10

AVPlayer を使用する単純なビデオ編集ビューがあります。1 つまたは複数の AVURLAsset を使用して AVMutableComposition を作成します。すべて正常に動作しますが、ビデオは常に 90 度回転します。つまり、ソース ビデオがポートレート モードで撮影された場合です。AVPlayer は横向きモードで表示し、その逆も同様です。私はドキュメントを調べて、それを「グーグル」で調べましたが、解決策が見つかりません。多分私は間違った場所を探しています。

誰でも助けることができますか?

前もって感謝します;

ジャンピエール

4

2 に答える 2

4

私の理解では、ポートレート ビデオがランドスケープ モードで、時々ビデオが逆さまになっているなどの向きの問題があります。これは、デフォルトの AVAsset の向きによるものです。デフォルトの iPhone カメラ アプリケーションを使用して記録されたすべての動画および画像ファイルは、ビデオ フレームが横向きに設定されているため、メディアは横向きモードで保存されます。AVAsset には、メディアの方向情報を含む preferredTransform プロパティがあり、これは、写真アプリまたは QuickTime を使用してメディア ファイルを表示するたびに、メディア ファイルに適用されます。これは、必要な変換を AVAsset オブジェクトに適用することで簡単に修正できます。ただし、2 つの動画ファイルの向きが異なる可能性があるため、最初に行ったように 1 つ (想定) ではなく、2 つの別個の AVMutableCompositionTrack インスタンスを使用する必要があります。2 つの AVMutableCompositionTrack ビデオ トラックを作成する 2 つの別個の AVMutableCompositionTrack インスタンスがあるため、方向を修正するために各トラックに AVMutableVideoCompositionLayerInstruction を適用する必要があります。したがって、次のコードを追加します

    //  Create AVMutableVideoCompositionInstruction
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(firstAsset.duration, secondAsset.duration));
// Create an AVMutableVideoCompositionLayerInstruction for the first track
AVMutableVideoCompositionLayerInstruction *firstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:firstTrack];
AVAssetTrack *firstAssetTrack = [[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation firstAssetOrientation_  = UIImageOrientationUp;
BOOL isFirstAssetPortrait_  = NO;
CGAffineTransform firstTransform = firstAssetTrack.preferredTransform;
if (firstTransform.a == 0 && firstTransform.b == 1.0 && firstTransform.c == -1.0 && firstTransform.d == 0) {
    firstAssetOrientation_ = UIImageOrientationRight; 
    isFirstAssetPortrait_ = YES;
}
if (firstTransform.a == 0 && firstTransform.b == -1.0 && firstTransform.c == 1.0 && firstTransform.d == 0) {
    firstAssetOrientation_ =  UIImageOrientationLeft; 
    isFirstAssetPortrait_ = YES;
}
if (firstTransform.a == 1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == 1.0) {
    firstAssetOrientation_ =  UIImageOrientationUp;
}
if (firstTransform.a == -1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == -1.0) {
    firstAssetOrientation_ = UIImageOrientationDown;
}
[firstlayerInstruction setTransform:firstAsset.preferredTransform atTime:kCMTimeZero];
[firstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration];
//  Create an AVMutableVideoCompositionLayerInstruction for the second track
AVMutableVideoCompositionLayerInstruction *secondlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:secondTrack];
AVAssetTrack *secondAssetTrack = [[secondAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation secondAssetOrientation_  = UIImageOrientationUp;
BOOL isSecondAssetPortrait_  = NO;
CGAffineTransform secondTransform = secondAssetTrack.preferredTransform;
if (secondTransform.a == 0 && secondTransform.b == 1.0 && secondTransform.c == -1.0 && secondTransform.d == 0) {
    secondAssetOrientation_= UIImageOrientationRight; 
    isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 0 && secondTransform.b == -1.0 && secondTransform.c == 1.0 && secondTransform.d == 0) {
    secondAssetOrientation_ =  UIImageOrientationLeft; 
    isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == 1.0) {
    secondAssetOrientation_ =  UIImageOrientationUp;
}
if (secondTransform.a == -1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == -1.0) {
    secondAssetOrientation_ = UIImageOrientationDown;
}
[secondlayerInstruction setTransform:secondAsset.preferredTransform atTime:firstAsset.duration];
}

最後に指示を追加します。これは、2 番目のトラックに適用された向きの修正です。

    mainInstruction.layerInstructions = [NSArray arrayWithObjects:firstlayerInstruction, secondlayerInstruction,nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);

CGSize naturalSizeFirst, naturalSizeSecond;
if(isFirstAssetPortrait_){
    naturalSizeFirst = CGSizeMake(FirstAssetTrack.naturalSize.height, FirstAssetTrack.naturalSize.width);
} else {
    naturalSizeFirst = FirstAssetTrack.naturalSize;
}
if(isSecondAssetPortrait_){
    naturalSizeSecond = CGSizeMake(SecondAssetTrack.naturalSize.height, SecondAssetTrack.naturalSize.width);
} else {
    naturalSizeSecond = SecondAssetTrack.naturalSize;
}

float renderWidth, renderHeight;
if(naturalSizeFirst.width > naturalSizeSecond.width) {
    renderWidth = naturalSizeFirst.width;
} else {
    renderWidth = naturalSizeSecond.width;
}
if(naturalSizeFirst.height > naturalSizeSecond.height) {
    renderHeight = naturalSizeFirst.height;
} else {
    renderHeight = naturalSizeSecond.height;
}
MainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight);

お役に立てれば

于 2013-05-15T06:23:33.313 に答える
1

調べるコードがなければ、何が起こっているのかを知ることは困難です...しかし、ほとんどの場合、preferredTransformプロパティの価値を失っているために問題が発生しています。

すべてのAVAssetTrackオブジェクトには、preferredTransformビデオを回転するかどうかを指定するために使用されるプロパティがあります。新しいAVMutableAssetTrackオブジェクトを作成している場合は、ビデオが意図した方向にとどまるように、そのプロパティの値を設定する必要がある場合があります。

于 2012-10-08T10:19:55.123 に答える