我正在使用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
已经写入了文件吗?
如果此方法不起作用,我怎样才能实现无缝尾随视频缓冲的效果?
谢谢!
答案 0 :(得分:3)
不确定你想要在这里实现的目标是否有效,这是因为就像你说的那样,你在试图修剪它时正在编写文件,为什么你不能录制视频并在以后修剪它?如果你真的想在任何时候保留两分钟的视频,你可能想尝试使用AVCaptureVideoDataOutput,使用它你将获得视频帧,你可以使用AVAssetWriter来编写它来压缩和写入一个文件的帧,看看这个SO关于如何做到这一点的问题This code to write video+audio through AVAssetWriter and AVAssetWriterInputs is not working. Why?
答案 1 :(得分:2)
我怀疑您收到的错误是因为您尝试覆盖与导出URL中相同的文件。 文档说“如果您尝试覆盖现有文件,或者在应用程序的沙箱之外写入文件,则导出将失败。如果您需要覆盖现有文件,则必须先将其删除。”
要获取视频的最后两分钟,您可能希望首先使用loadValuesAsynchronouslyForKeys获取它的持续时间,这是另一个异步调用。使用此持续时间,您可以创建时间范围并通过将视频导出到其他URL来修剪视频。
CMTime start = CMTimeMakeWithSeconds(durationObtained - 120, 600);
CMTime duration = CMTimeMakeWithSeconds(120, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);
exportSession.timeRange = range;