2010-11-23 107 views
9

我會製作縮小尺寸的視頻,可能是50像素和75像素的長度。這些是物理層面。如何使用AVAssetWriter製作縮小尺寸的視頻?

你是如何設定的?在視頻設置?我認爲AVVideoWidthKey和AVVideoHeightKey更適合不需要物理尺寸的解決方案。

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
           AVVideoCodecH264, AVVideoCodecKey, 
           [NSNumber numberWithInt: 320], AVVideoWidthKey,  
           [NSNumber numberWithInt:480], AVVideoHeightKey, 
           nil]; 
AVAssetWriterInput* writerInput = [[AVAssetWriterInput 
            assetWriterInputWithMediaType:AVMediaTypeVideo 
            outputSettings:videoSettings] retain 

回答

19

您需要設置視頻編解碼器參數:

NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
              [NSNumber numberWithInt:320], AVVideoCleanApertureWidthKey, 
              [NSNumber numberWithInt:480], AVVideoCleanApertureHeightKey, 
              [NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey, 
              [NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey, 
              nil]; 


NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
              [NSNumber numberWithInt:3], AVVideoPixelAspectRatioHorizontalSpacingKey, 
              [NSNumber numberWithInt:3],AVVideoPixelAspectRatioVerticalSpacingKey, 
                nil]; 



NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithInt:960000], AVVideoAverageBitRateKey, 
           [NSNumber numberWithInt:1],AVVideoMaxKeyFrameIntervalKey, 
           videoCleanApertureSettings, AVVideoCleanApertureKey, 
           //videoAspectRatioSettings, AVVideoPixelAspectRatioKey, 
           //AVVideoProfileLevelH264Main30, AVVideoProfileLevelKey, 
           nil]; 





NSString *targetDevice = [[UIDevice currentDevice] model]; 

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
           AVVideoCodecH264, AVVideoCodecKey, 
           codecSettings,AVVideoCompressionPropertiesKey, 
           [NSNumber numberWithInt:320], AVVideoWidthKey, 
           [NSNumber numberWithInt:480], AVVideoHeightKey, 
           nil]; 
+0

爲什麼[NSNumber的numberWithInt:1],AVVideoMaxKeyFrameIntervalKey? – Meekohi 2012-06-26 21:15:22

+1

@Meekohi:[`AVVideoMaxKeyFrameIntervalKey`](https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVFoundation_Constants/Reference/reference.html#//apple_ref/doc/c_ref/AVVideoMaxKeyFrameIntervalKey)指定一個鍵訪問關鍵幀之間的最大間隔。相應的值是`NSNumber`的一個實例。 `1`只表示關鍵幀**。 – Regexident 2012-09-28 14:25:25

7

你需要一個博士與AVAssetWriter工作 - 這是不平凡的: https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/05_Export.html#//apple_ref/doc/uid/TP40010188-CH9-SW1

有一個驚人的庫做什麼你想要哪個只是一個AVAssetExportSession插入式替代更關鍵的功能,如更改比特率:https://github.com/rs/SDAVAssetExportSession

下面是如何使用它:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 

    SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:[AVAsset assetWithURL:[info objectForKey:UIImagePickerControllerMediaURL]]]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    self.myPathDocs = [documentsDirectory stringByAppendingPathComponent: 
         [NSString stringWithFormat:@"lowerBitRate-%d.mov",arc4random() % 1000]]; 
    NSURL *url = [NSURL fileURLWithPath:self.myPathDocs]; 
    encoder.outputURL=url; 
    encoder.outputFileType = AVFileTypeMPEG4; 
    encoder.shouldOptimizeForNetworkUse = YES; 

    encoder.videoSettings = @ 
    { 
    AVVideoCodecKey: AVVideoCodecH264, 
    AVVideoCompressionPropertiesKey: @ 
    { 
    AVVideoAverageBitRateKey: @2300000, 
    AVVideoProfileLevelKey: AVVideoProfileLevelH264High40, 
    }, 
    }; 
    encoder.audioSettings = @ 
    { 
    AVFormatIDKey: @(kAudioFormatMPEG4AAC), 
    AVNumberOfChannelsKey: @2, 
    AVSampleRateKey: @44100, 
    AVEncoderBitRateKey: @128000, 
    }; 

    [encoder exportAsynchronouslyWithCompletionHandler:^ 
    { 
    int status = encoder.status; 

    if (status == AVAssetExportSessionStatusCompleted) 
    { 
     AVAssetTrack *videoTrack = nil; 
     AVURLAsset *asset = [AVAsset assetWithURL:encoder.outputURL]; 
     NSArray *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo]; 
     videoTrack = [videoTracks objectAtIndex:0]; 
     float frameRate = [videoTrack nominalFrameRate]; 
     float bps = [videoTrack estimatedDataRate]; 
     NSLog(@"Frame rate == %f",frameRate); 
     NSLog(@"bps rate == %f",bps/(1024.0 * 1024.0)); 
     NSLog(@"Video export succeeded"); 
     // encoder.outputURL <- this is what you want!! 
    } 
    else if (status == AVAssetExportSessionStatusCancelled) 
    { 
     NSLog(@"Video export cancelled"); 
    } 
    else 
    { 
     NSLog(@"Video export failed with error: %@ (%d)", encoder.error.localizedDescription, encoder.error.code); 
    } 
    }]; 
}