【问题标题】:AVAssetExportSession ignoring videoComposition rotation & stripping metadataAVAssetExportSession 忽略 videoComposition 旋转和剥离元数据
【发布时间】:2013-04-08 21:28:34
【问题描述】:

我正在尝试在上传到我的 iOS 设备之前旋转视频,因为其他平台(例如 android)无法正确解释 iOS 录制视频中的旋转信息,因此播放它们时旋转不正确。

我查看了以下堆栈帖子,但没有成功将其中任何一个应用于我的案例:


我处理了Apple AVSimpleEditor 项目示例,但不幸的是,在创建 AVAssetExportSession 并调用 exportAsynchronouslyWithCompletionHandler 时,没有执行任何旋转,更糟糕的是,旋转元数据被从结果文件中剥离。

这是运行导出的代码:

AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[_mutableComposition copy] presetName:AVAssetExportPresetPassthrough];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileType3GPP;
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.videoComposition = _mutableVideoComposition;

[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
 {
     NSLog(@"Status is %d %@", exportSession.status, exportSession.error);

     handler(exportSession);
     [exportSession release];
 }];

_mutableComposition 和 _mutableVideoComposition 的值在这里通过这个方法初始化:

- (void) getVideoComposition:(AVAsset*)asset
{

    AVMutableComposition *mutableComposition = nil;
    AVMutableVideoComposition *mutableVideoComposition = nil;

    AVMutableVideoCompositionInstruction *instruction = nil;
    AVMutableVideoCompositionLayerInstruction *layerInstruction = nil;
    CGAffineTransform t1;
    CGAffineTransform t2;

    AVAssetTrack *assetVideoTrack = nil;
    AVAssetTrack *assetAudioTrack = nil;
    // Check if the asset contains video and audio tracks
    if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
        assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
    }
    if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
        assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
    }

    CMTime insertionPoint = kCMTimeZero;
    NSError *error = nil;


    // Step 1
    // Create a composition with the given asset and insert audio and video tracks into it from the asset
    // Check whether a composition has already been created, i.e, some other tool has already been applied
    // Create a new composition
    mutableComposition = [AVMutableComposition composition];

    // Insert the video and audio tracks from AVAsset
    if (assetVideoTrack != nil) {
        AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];
    }
    if (assetAudioTrack != nil) {
        AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];
    }


    // Step 2
    // Translate the composition to compensate the movement caused by rotation (since rotation would cause it to move out of frame)
    t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0);
    // Rotate transformation
    t2 = CGAffineTransformRotate(t1, degreesToRadians(90.0));


    // Step 3
    // Set the appropriate render sizes and rotational transforms
    // Create a new video composition
    mutableVideoComposition = [AVMutableVideoComposition videoComposition];
    mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width);
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30);

    // The rotate transform is set on a layer instruction
    instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mutableComposition duration]);
    layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:(mutableComposition.tracks)[0]];
    [layerInstruction setTransform:t2 atTime:kCMTimeZero];


    // Step 4
    // Add the transform instructions to the video composition
    instruction.layerInstructions = @[layerInstruction];
    mutableVideoComposition.instructions = @[instruction];

    TT_RELEASE_SAFELY(_mutableComposition);
    _mutableComposition = [mutableComposition retain];
    TT_RELEASE_SAFELY(_mutableVideoComposition);
    _mutableVideoComposition = [mutableVideoComposition retain];
}

我从 AVSERotateCommand from here 中提取了这个方法。谁能建议为什么这种方法不能成功地将我的视频旋转必要的 90 度?

【问题讨论】:

  • 我遇到了和你一样的问题,下面建议的答案(例如更改为 AVAssetExportPresetMediumQuality)并不能解决问题。我也尝试在 layerInstruction 上添加 setOpacity:0,但导出电影时似乎忽略了说明。
  • 我也有同样的问题,请问您有解决办法吗?

标签: ios video orientation avassetwriter avassetexportsession


【解决方案1】:

因为您使用的是AVAssetExportPresetPassthrough,所以AVAssetExportSession 将忽略videoComposition,请使用任何其他预设。

【讨论】:

  • 这似乎没有任何区别了。
  • 您在模拟器中尝试吗?在设备中尝试
猜你喜欢
  • 1970-01-01
  • 2014-11-04
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
相关资源
最近更新 更多