【发布时间】:2019-03-02 00:48:15
【问题描述】:
我正在尝试从视频中裁剪一个方形框架。以下是流程
- 获取视频资产
- 从该资产中获取视频轨道
- 创建具有帧持续时间 (30fps) 和 renderSize(必需矩形)的 AVMutableComposition 实例
- 使用 timeRange (0-asset.duration) 创建 AVMutableVideoCompositionInstruction 实例
- 创建 LayerInstruction 实例
- 设置它的变换来给帧偏移
- 在指令中设置 LayerInstruction
- 在 mutableComposition 实例中设置指令
- 使用上述资产和 HighestQuality 预设创建 AVAssetExportSession 实例
- 设置它的输出地址、时间范围和输出文件类型
- 异步导出
现在发生的情况是,视频显示正确,但在某些情况下持续时间会有所不同
- 如果视频最后有运动,则不进行剪切,输出视频与原始视频时间一致
- 如果视频是静态的,例如视频中没有移动,或者视频的最后,一些静态帧会被移除,视频长度会变小
- 在某些情况下,如果视频中有大量移动,则持续时间会增加。
持续时间的变化是从 0.1 秒到 1 秒。这可能是一个非常小的变化,但我需要这个过程,视频时长必须是精确的。
如果您想深入了解,我将添加代码。
AVAsset *asset ;
asset = [AVAsset assetWithURL:customURL];
//create an avassetrack with our asset
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CMTime originalVideoDur = asset.duration;
float orgDurFloat = (float)originalVideoDur.value / (float)originalVideoDur.timescale;
//create a video composition and preset some settings
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);
//here we are setting its render size to its height x height (Square)
CGFloat outputWidth = UIScreen.mainScreen.bounds.size.width * UIScreen.mainScreen.scale;
videoComposition.renderSize = CGSizeMake(outputWidth, outputWidth);
//create a video instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
CGAffineTransform finalTransform = [self getOutputTransformOfAsset:asset track:clipVideoTrack];
[transformer setTransform:finalTransform atTime:kCMTimeZero];
//add the transformer layer instructions, then add to video composition
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
//Create an Export Path to store the cropped video
NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *exportPath = [documentsPath stringByAppendingFormat:@"/CroppedVideo2.mp4"];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
//Remove any prevouis videos at that path
[[NSFileManager defaultManager] removeItemAtURL:exportUrl error:nil];
//Export
exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComposition;
exporter.outputURL = exportUrl;
exporter.outputFileType = AVFileTypeMPEG4;
exporter.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
[exporter exportAsynchronouslyWithCompletionHandler:^
{
dispatch_async(dispatch_get_main_queue(), ^{
//Call when finished
});
}];
我测试但不起作用的东西是:
- 更改 AVAssetExportSession 预设。 (没有效果,除了低质量产生的持续时间差异较小但仍然有很大差异)
- 帧持续时间(较短的帧持续时间较小的持续时间差异,1 帧持续时间可提供最佳持续时间结果,但输出视频不可用)
【问题讨论】:
标签: ios video avasset avassetexportsession avmutablecomposition