2013-04-08 45 views
11

我试图在我的iOS设备上传视频之前旋转视频,因为其他平台(如android)没有正确解释iOS录制的视频中的旋转信息,并因此播放他们不正确地旋转。AVAssetExportSession忽略视频组合旋转和剥离元数据

我已经看过下面的堆栈职位,但还没有成功申请其中任何我的情况:


我应付了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度?

+0

我遇到了同样的问题,下面的建议答案(例如更改为AVAssetExportPresetMediumQuality)不能解决问题。 我也尝试在layerInstruction上添加setOpacity:0,但似乎导出电影时忽略指令。 – 2015-01-19 12:46:39

+0

我也有同样的问题,你有任何解决方案? – user3306145 2016-09-30 12:23:31

回答

6

因为您正在使用AVAssetExportPresetPassthroughAVAssetExportSession将忽略videoComposition,请使用任何其他预设。

+0

这似乎没有任何区别了。 – 2015-01-19 13:34:42