2012-05-29 10 views
11

私は最近、AVMutableCompositionを使用している問題を発見しました。私はこれについていくつかの洞察を求めています。AVMutableCompositionビデオを回転する

私は、左右の風景の2つの向きでビデオを録画できます。風景の右側にビデオを録画すると(ホームボタンが右側にあります)、それらはコンポジションに追加され、正しい向きで再生されます。ただし、左向きに録音すると(左のホームボタン)、これらのクリップは上下逆さまに再生されます。

ただし、コンポジションに挿入すると上下が逆転します。さもなければ、彼らは正しい向きで遊ぶ。ランドスケープで撮影したクリップの回転を逆にするのはなぜですか?これをどうすれば解決できますか?どんな助けもありがとう!

+0

私も、そのかかわらず、私はこれが起こっている何をするかのようにも気づきました。手作業での録音の向きの設定、回転の試行など。最初のクリップを単独で再生すると、トラックは右上に再生されますが、コンポジションに結合されると同時に逆さまになります。 – bgoers

答えて

27

ここでは、元の回転を維持したい場合は、やや簡単です。

// Grab the source track from AVURLAsset for example. 
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].lastObject; 

// Grab the composition video track from AVMutableComposition you already made. 
AVMutableCompositionTrack *compositionVideoTrack = [composition tracksWithMediaType:AVMediaTypeVideo].lastObject; 

// Apply the original transform.  
if (assetVideoTrack && compositionVideoTrack) { 
    [compositionVideoTrack setPreferredTransform:assetVideoTrack.preferredTransform]; 
} 

// Export... 
+0

このソリューションは、元のローテーションを維持するために私にとって完璧に機能しました。 – Brad

+0

は迅速に変換中に機能しませんか? –

+1

異なるトランスフォームを持つコンポジション内に複数のトラックがある場合、それぞれのトランスフォームに簡単に設定することはできません。別々に補正する必要があります。 –

8

解決しました。最終的にトラックを回転させてフレームに変換することができました。魅力のように動作します。

//setting up the first video based on previous recording 
    CMTimeRange videoDuration = CMTimeRangeMake(kCMTimeZero, [self.previousRecording duration]); 
    AVAssetTrack *clipVideoTrack = [[self.previousRecording tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVAssetTrack *clipAudioTrack = [[self.previousRecording tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    [compositionVideoTrack insertTimeRange:videoDuration ofTrack:clipVideoTrack atTime:nextClipStartTime error:nil]; 
    [compositionAudioTrack insertTimeRange:videoDuration ofTrack:clipAudioTrack atTime:nextClipStartTime error:nil]; 

    //our first track instruction - set up the instruction layer, then check the orientation of the track 
    //if the track is in landscape-left mode, it needs to be rotated 180 degrees (PI) 
    AVMutableVideoCompositionLayerInstruction *firstTrackInstruction = 
     [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; 

    if([self orientationForTrack:clipVideoTrack] == UIDeviceOrientationLandscapeLeft) { 
     CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI); 
     CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation(640, 480); 
     CGAffineTransform mixedTransform = CGAffineTransformConcat(rotation, translateToCenter); 
     [firstTrackInstruction setTransform:mixedTransform atTime:kCMTimeZero]; 
    } 
+0

こんにちはbogers ....私も同じ問題を抱えています...私はあなたのコードを使用していますが、[self orientationForTrack:clipVideoTrack](メソッドが見つかりません)の近くでエラーが発生しています...これで私を助けてください... – ask123

+0

トラックの向きを決定する方法を自分で定義しました。パラメータとしてAVAssetTrackが使用され、優先方向が使用されました。私は少し私を変更しましたが、これは助けてくださいhttp://stackoverflow.com/a/6046421/1415949 – bgoers

+0

'[self orientationForTrack:]'とは何ですか?実装は何ですか? –

0

答えは確かに最良の選択ですが、部分的にしか正しくないと思います。実際には、それを機能させるために、ポートレートトラックの自然なサイズの高さと幅を反転させて、エクスポートのレンダーサイズを調整する必要があります。

私はちょうどそれをテストし、私はまた、AVFoundationプログラミングガイドを引用 - 実際に@dizyの答えではなく、言及加えて提案されたものを実装することを示唆している編集部:

すべてAVAssetTrackオブジェクトはpreferredTransformを持っていますそのアセットトラックの方向情報を含むプロパティ。この変換は、アセットトラックが画面上に表示されるたびに適用されます。前のコードでは、レンダリングサイズを調整すると、レイヤーの命令のトランスフォームがアセットトラックのトランスフォームに設定され、新しいコンポジションのビデオが正しくに表示されます。

コードは(わずか2行が追加する)この1のようにする必要があります:

// Grab the source track from AVURLAsset for example. 
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].lastObject; 

// Grab the composition video track from AVMutableComposition you already made. 
AVMutableCompositionTrack *compositionVideoTrack = [composition tracksWithMediaType:AVMediaTypeVideo].lastObject; 

// Apply the original transform.  
if (assetVideoTrack && compositionVideoTrack) { 
    [compositionVideoTrack setPreferredTransform:assetVideoTrack.preferredTransform]; 
} 

flippedSize = CGSize(compositionVideoTrack.naturalSize.height, compositionVideoTrack.naturalSize.width); 
composition.renderSize = flippedSize; 

// Export.. 
関連する問題