14

最近、AVMutableCompositionを使用して問題を発見しました。これについて、いくつかの洞察を探しています。

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

ただし、コンポジションに挿入されている場合にのみ、上下逆に再生されます。それ以外の場合は、正しい方向で再生されます。横向きで撮影したクリップの回転を反転させた構図が残っているのはなぜですか?どうすればこれを修正できますか?どんな助けでも大歓迎です!

4

3 に答える 3

34

元の回転を維持したいだけの場合は、これが少し簡単な方法です。

// 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...
于 2014-02-24T05:59:47.897 に答える
9

私の問題を解決しました。ついにトラックを回転させてフレームに変換することができました。チャームのように機能します。

    //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];
    }
于 2012-05-30T17:37:23.197 に答える
0

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

私はそれをテストしたばかりで、AVFoundationプログラミングガイド-編集セクションも引用しています。これは、@ dizyの回答で実際に提案されているものを実装することを提案していますが、上記の追加があります。

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

その場合、コードは次のようになります(追加するのは2行だけです)。

// 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..
于 2017-10-01T10:46:59.317 に答える