2013-04-08 44 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