【问题标题】:Video duration changes after composing and export using AVAssetExportSession使用 AVAssetExportSession 合成和导出后视频时长发生变化
【发布时间】:2019-03-02 00:48:15
【问题描述】:

我正在尝试从视频中裁剪一个方形框架。以下是流程

  1. 获取视频资产
  2. 从该资产中获取视频轨道
  3. 创建具有帧持续时间 (30fps) 和 renderSize(必需矩形)的 AVMutableComposition 实例
  4. 使用 timeRange (0-asset.duration) 创建 AVMutableVideoCompositionInstruction 实例
  5. 创建 LayerInstruction 实例
  6. 设置它的变换来给帧偏移
  7. 在指令中设置 LayerInstruction
  8. 在 mutableComposition 实例中设置指令
  9. 使用上述资产和 HighestQuality 预设创建 AVAssetExportSession 实例
  10. 设置它的输出地址、时间范围和输出文件类型
  11. 异步导出

现在发生的情况是,视频显示正确,但在某些情况下持续时间会有所不同

  1. 如果视频最后有运动,则不进行剪切,输出视频与原始视频时间一致
  2. 如果视频是静态的,例如视频中没有移动,或者视频的最后,一些静态帧会被移除,视频长度会变小
  3. 在某些情况下,如果视频中有大量移动,则持续时间会增加。

持续时间的变化是从 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


    【解决方案1】:

    发现问题: 老实说,这不是问题,这是一种系统错误。导出器无缘无故地忽略了最后的静态帧。 在我将变换设置为 kCMTimeZero 时,我添加了新行,在视频末尾设置了相同的变换。

    [transformer setTransform:finalTransform atTime:asset.duration];
    

    现在导出器不会忽略最后几帧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 2018-04-11
      相关资源
      最近更新 更多