从 .mov 文件创建 CMSampleBufferRef
Creating `CMSampleBufferRef` from a .mov file
我的应用程序捕获了一个 3 秒的视频剪辑,我想以编程方式通过循环 5 次从录制的 3 秒剪辑创建一个 15 秒的剪辑。最后必须在 CameraRoll 中保存 15 秒的剪辑。
我通过 AVCaptureMovieFileOutput
获得了我的 3 秒视频剪辑,并且我从代表处获得了它的 NSURL
,目前在 NSTemporaryDirectory()
。
我正在使用 AVAssetWriterInput
循环播放。但它要求 CMSampleBufferRef
像 :
[writerInput appendSampleBuffer:sampleBuffer];
我如何从 NSTemporaryDirectory() 中的视频中获取这个 CMSampleBufferRef
?
我看过将 UIImage
转换为 CMSampleBufferRef
的代码,但我可以找到任何视频文件。
任何建议都会有所帮助。 :)
看看 AVAssetReader,它可以 return 一个 CMSampleBufferRef。请记住,您需要为您的工作方法操纵时间戳。
最后,我使用 AVMutableComposition
解决了我的问题。这是我的代码:
AVMutableComposition *mixComposition = [AVMutableComposition new];
AVMutableCompositionTrack *mutableCompVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:3SecFileURL options:nil];
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(M_PI_2);
[mutableCompVideoTrack setPreferredTransform:rotationTransform];
CMTime currentCMTime = kCMTimeZero;
for (NSInteger count = 0 ; count < 5 ; count++)
{
[mutableCompVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:currentCMTime error:nil];
currentCMTime = CMTimeAdd(currentCMTime, [videoAsset duration]);
}
NSString *fullMoviePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"moviefull" stringByAppendingPathExtension:@"mov"]];
NSURL *finalVideoFileURL = [NSURL fileURLWithPath:fullMoviePath];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough];
[exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
[exportSession setOutputURL:finalVideoFileURL];
CMTimeValue val = [mixComposition duration].value;
CMTime start = CMTimeMake(0, 1);
CMTime duration = CMTimeMake(val, 1);
CMTimeRange range = CMTimeRangeMake(start, duration);
[exportSession setTimeRange:range];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status])
{
case AVAssetExportSessionStatusFailed:
{
NSLog(@"Export failed: %@ %@", [[exportSession error] localizedDescription], [[exportSession error]debugDescription]);
}
case AVAssetExportSessionStatusCancelled:
{
NSLog(@"Export canceled");
break;
}
case AVAssetExportSessionStatusCompleted:
{
NSLog(@"Export complete!");
}
default: NSLog(@"default");
}
}];
我的应用程序捕获了一个 3 秒的视频剪辑,我想以编程方式通过循环 5 次从录制的 3 秒剪辑创建一个 15 秒的剪辑。最后必须在 CameraRoll 中保存 15 秒的剪辑。
我通过 AVCaptureMovieFileOutput
获得了我的 3 秒视频剪辑,并且我从代表处获得了它的 NSURL
,目前在 NSTemporaryDirectory()
。
我正在使用 AVAssetWriterInput
循环播放。但它要求 CMSampleBufferRef
像 :
[writerInput appendSampleBuffer:sampleBuffer];
我如何从 NSTemporaryDirectory() 中的视频中获取这个 CMSampleBufferRef
?
我看过将 UIImage
转换为 CMSampleBufferRef
的代码,但我可以找到任何视频文件。
任何建议都会有所帮助。 :)
看看 AVAssetReader,它可以 return 一个 CMSampleBufferRef。请记住,您需要为您的工作方法操纵时间戳。
最后,我使用 AVMutableComposition
解决了我的问题。这是我的代码:
AVMutableComposition *mixComposition = [AVMutableComposition new];
AVMutableCompositionTrack *mutableCompVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:3SecFileURL options:nil];
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(M_PI_2);
[mutableCompVideoTrack setPreferredTransform:rotationTransform];
CMTime currentCMTime = kCMTimeZero;
for (NSInteger count = 0 ; count < 5 ; count++)
{
[mutableCompVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:currentCMTime error:nil];
currentCMTime = CMTimeAdd(currentCMTime, [videoAsset duration]);
}
NSString *fullMoviePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"moviefull" stringByAppendingPathExtension:@"mov"]];
NSURL *finalVideoFileURL = [NSURL fileURLWithPath:fullMoviePath];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough];
[exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
[exportSession setOutputURL:finalVideoFileURL];
CMTimeValue val = [mixComposition duration].value;
CMTime start = CMTimeMake(0, 1);
CMTime duration = CMTimeMake(val, 1);
CMTimeRange range = CMTimeRangeMake(start, duration);
[exportSession setTimeRange:range];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status])
{
case AVAssetExportSessionStatusFailed:
{
NSLog(@"Export failed: %@ %@", [[exportSession error] localizedDescription], [[exportSession error]debugDescription]);
}
case AVAssetExportSessionStatusCancelled:
{
NSLog(@"Export canceled");
break;
}
case AVAssetExportSessionStatusCompleted:
{
NSLog(@"Export complete!");
}
default: NSLog(@"default");
}
}];