使用AVCaptureSession创建的.mov视频文件大小如何减小?

3

我能使用AVCaptureSession录制视频。但是我想要减小它的大小。我该如何做呢?我在代理“captureOutput”方法中获取最终URL

    VideoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    VideoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:VideoDevice error:&error]; 
    if (!error) 
    { 
        if ([CaptureSession canAddInput:VideoInputDevice]) 
        {
            [CaptureSession addInput:VideoInputDevice]; 
        }
        else 
        {
            NSLog(@"Couldn't add video input"); 
        } 
    else 
    { 
        NSLog(@"Couldn't create video input"); 
    } 
} 
else 
{ 
    NSLog(@"Couldn't create video capture device"); 
} 

AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 

你能展示一下如何记录和保存吗? - Unheilig
VideoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; VideoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:VideoDevice error:&error]; 如果(!error) { 如果([CaptureSession canAddInput:VideoInputDevice]) [CaptureSession addInput:VideoInputDevice]; else NSLog(@"无法添加视频输入"); } else { NSLog(@"无法创建视频输入"); } } else { NSLog(@"无法创建视频捕获设备"); } AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - sai
我会为您编辑那个。 - Unheilig
2个回答

2

I hope this method will be helpful for u

- (void)compressingVideoWithSoundWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL andResolution:(CGSize)resolution
{
    self.myVideoWriter = nil;

    [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];

    //setup video writer
    AVAsset *videoAsset = [[AVURLAsset alloc] initWithURL:inputURL options:nil];

    AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    NSDictionary *videoWriterCompressionSettings =  [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1250000], AVVideoAverageBitRateKey, nil];

    NSDictionary *videoWriterSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey, videoWriterCompressionSettings, AVVideoCompressionPropertiesKey, [NSNumber numberWithFloat:resolution.width], AVVideoWidthKey, [NSNumber numberWithFloat:resolution.height], AVVideoHeightKey, nil];

    AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput
                                            assetWriterInputWithMediaType:AVMediaTypeVideo
                                            outputSettings:videoWriterSettings];

    videoWriterInput.expectsMediaDataInRealTime = YES;

    videoWriterInput.transform = videoTrack.preferredTransform;


    NSError* writerError = nil;

    self.myVideoWriter = [[AVAssetWriter alloc] initWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:&writerError];

    if (writerError) {
        NSLog(@"Writer error: %@", writerError);
        NSString *message = [NSString stringWithFormat:@"VideoEditor. compressingVideoWithInputURL: outputURL: andResolution:. Writer error: %@", writerError];
        FLog(message);
        return;
    }



    [self.myVideoWriter addInput:videoWriterInput];

    //setup video reader
    NSDictionary *videoReaderSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

    AVAssetReaderTrackOutput *videoReaderOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:videoReaderSettings];

    AVAssetReader *videoReader = [[AVAssetReader alloc] initWithAsset:videoAsset error:nil];

    [videoReader addOutput:videoReaderOutput];

    //setup audio writer
    AVAssetWriterInput* audioWriterInput = [AVAssetWriterInput
                                            assetWriterInputWithMediaType:AVMediaTypeAudio
                                            outputSettings:nil];

    audioWriterInput.expectsMediaDataInRealTime = NO;

    [self.myVideoWriter addInput:audioWriterInput];

    //setup audio reader
    AVAssetTrack* audioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

    AVAssetReaderOutput *audioReaderOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil];

    AVAssetReader *audioReader = [AVAssetReader assetReaderWithAsset:videoAsset error:nil];

    [audioReader addOutput:audioReaderOutput];

    [self.myVideoWriter startWriting];

    //start writing from video reader
    [videoReader startReading];

    [self.myVideoWriter startSessionAtSourceTime:kCMTimeZero];

    dispatch_queue_t processingQueue = dispatch_queue_create("processingQueue1", DISPATCH_QUEUE_SERIAL);

    [videoWriterInput requestMediaDataWhenReadyOnQueue:processingQueue usingBlock:
     ^{

         while ([videoWriterInput isReadyForMoreMediaData]) {

             CMSampleBufferRef sampleBuffer;

             if ([videoReader status] == AVAssetReaderStatusReading &&
                 (sampleBuffer = [videoReaderOutput copyNextSampleBuffer])) {

                 [videoWriterInput appendSampleBuffer:sampleBuffer];
                 CFRelease(sampleBuffer);
             }

             else {

                 [videoWriterInput markAsFinished];

                 if ([videoReader status] == AVAssetReaderStatusCompleted) {
                     if ([audioReader status] == AVAssetReaderStatusReading || [audioReader status] == AVAssetReaderStatusCompleted) {

                     }
                     else{
                         //start writing from audio reader
                         [audioReader startReading];

                         [self.myVideoWriter startSessionAtSourceTime:kCMTimeZero];

                         dispatch_queue_t processingQueue = dispatch_queue_create("processingQueue2", NULL);

                         [audioWriterInput requestMediaDataWhenReadyOnQueue:processingQueue usingBlock:^{

                             while (audioWriterInput.readyForMoreMediaData) {

                                 CMSampleBufferRef sampleBuffer;

                                 if ([audioReader status] == AVAssetReaderStatusReading &&
                                     (sampleBuffer = [audioReaderOutput copyNextSampleBuffer])) {

                                     [audioWriterInput appendSampleBuffer:sampleBuffer];
                                     CFRelease(sampleBuffer);
                                 }
                                 else {

                                     [audioWriterInput markAsFinished];

                                     if ([audioReader status] == AVAssetReaderStatusCompleted)
                                     {
                                         [self finishWritingAction];
                                         break;
                                     }

                                 }
                             }

                         }
                          ];
                     }
                 }

             }
         }
     }
     ];
}

0

你想要使用AVAssetExportSession。你的代码应该长这样:

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:myAsset presetName:exportPreset];

exporter.videoComposition = _videoComposition;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = NO;
url = [url URLByAppendingPathExtension:CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)(exporter.outputFileType), kUTTagClassFilenameExtension))];
exporter.outputURL = url;

[exporter exportAsynchronouslyWithCompletionHandler:^{
    // handle the completion in a way meaningful to your app
}];

你的导出预设应该是以下之一:

AVF_EXPORT NSString *const AVAssetExportPreset640x480           NS_AVAILABLE(10_7, 4_0);
AVF_EXPORT NSString *const AVAssetExportPreset960x540           NS_AVAILABLE(10_7, 4_0);
AVF_EXPORT NSString *const AVAssetExportPreset1280x720          NS_AVAILABLE(10_7, 4_0);
AVF_EXPORT NSString *const AVAssetExportPreset1920x1080         NS_AVAILABLE(10_7, 5_0);
AVF_EXPORT NSString *const AVAssetExportPreset3840x2160         NS_AVAILABLE(10_10, NA);

是的,我尝试过这个...压缩后视频大小太小了。 - sai
肯定有一个预设可以给你想要的大小。你的视频有多大(宽度/高度和长度以及MB),你想让它变成多大?为什么你需要它更小?你想用它做什么? - Paul Cezanne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接