3

我正在使用AVCaptureMovieFileOutput. 但是,我不想在整个录制时间内保留捕获的视频,而只想保留最后 2 分钟的视频。本质上,我想创建一个视频的尾随缓冲区。

我试图通过设置movieFragmentInterval等于 15 秒来实现这一点。由于这 15 秒的缓冲,MOV 文件的前 15 秒将使用以下代码修剪掉:

//This would be called 7 seconds after the video stream started buffering.
-(void)startTrimTimer
{
    trimTimer = [NSTimer scheduledTimerWithTimeInterval:15 target:self selector:@selector(trimFlashbackBuffer) userInfo:nil repeats:YES];
}

    -(void)trimFlashbackBuffer
    {
        //make sure that there is enough video before trimming off 15 seconds
        if(trimReadyCount<3){
            trimReadyCount++;
            return;
        }

        AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/flashbackBuffer.MOV",tripDirectory]] options:nil]; 

        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:videoAsset presetName:AVAssetExportPresetHighestQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/flashbackBuffer.MOV",tripDirectory]];
        exportSession.outputFileType = AVFileTypeQuickTimeMovie;
        CMTimeRange timeRange = CMTimeRangeMake(CMTimeMake(15000, 1000), CMTimeMake(120000, 1000));
        exportSession.timeRange = timeRange;

        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            switch (exportSession.status) {
                case AVAssetExportSessionStatusCompleted:
                    // Custom method to import the Exported Video
                    [self loadAssetFromFile:exportSession.outputURL];
                    break;
                case AVAssetExportSessionStatusFailed:
                    //
                    NSLog(@"Failed:%@",exportSession.error);
                    break;
                case AVAssetExportSessionStatusCancelled:
                    //
                    NSLog(@"Canceled:%@",exportSession.error);
                    break;
                default:
                    break;
            }
        }];

    }

但是,每次trimFlashbackBuffer调用我都会收到以下错误:

Failed:Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo=0x12e710 {NSLocalizedRecoverySuggestion=Try saving again., NSLocalizedDescription=Cannot Save}

这是因为该文件已被写入AVCaptureMovieFileOutput吗?

如果这种方法不起作用,如何实现无缝尾随视频缓冲区的效果?

谢谢!

4

2 回答 2

3

不确定您在这里尝试实现的目标是否可行,这是因为就像您说的那样,您在尝试修剪文件时正在写入文件,为什么不能录制视频并稍后修剪?如果您真的想随时保留两分钟的视频,您可能想尝试使用 AVCaptureVideoDataOutput,使用它您将获得视频帧,您可以使用 AVAssetWriter 将其写入以压缩并将帧写入文件,请查看此 SO关于如何做到这一点的问题此代码通过 AVAssetWriter 和 AVAssetWriterInputs 编写视频+音频不起作用。为什么?

于 2011-08-23T19:07:59.047 回答
2

我怀疑您遇到的错误是因为您试图覆盖与导出 URL 中相同的文件。文档说“如果您尝试覆盖现有文件或在应用程序的沙箱之外写入文件,则导出将失败。如果您需要覆盖现有文件,则必须先将其删除。”

要获取视频的最后两分钟,您可能希望首先使用 loadValuesAsynchronouslyForKeys 获取它的持续时间,这是另一个异步调用。使用此持续时间,您可以创建时间范围并通过将视频导出到不同的 URL 来修剪视频。

CMTime start = CMTimeMakeWithSeconds(durationObtained - 120, 600); 
CMTime duration = CMTimeMakeWithSeconds(120, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);  
exportSession.timeRange = range;
于 2011-09-27T07:22:15.713 回答