iPhone SDK。是否有可能使用AVURLlAsset/AVMutableComposition在AVplayer中旋转视频?

问题描述:

我有一个简单的使用AVPlayer的视频编辑视图。我使用一个或多个AVURLAsset创建一个AVMutableComposition。所有工作正常,但视频始终旋转90度。即如果源视频是以纵向模式拍摄的。 AVPlayer以横向模式显示,反之亦然。我已经阅读了文档,并“死死”地找到了解决办法。可能我正在寻找错误的地方。iPhone SDK。是否有可能使用AVURLlAsset/AVMutableComposition在AVplayer中旋转视频?

任何人都可以帮忙吗?

在此先感谢;

让 - 皮埃尔·

+0

观看AVFoundation一个WWDC10会议上,我相信这是什么地方的设置,但我需要再看一遍之后。我肯定会发布答案 – 2011-03-06 17:54:12

+1

你有没有解决过这个问题?我有同样的问题。 – 2012-02-02 06:49:06

+0

你解决了这个问题?我有同样的问题,我不知道我必须做什么 – 2015-08-18 08:16:13

而无需代码检查,也很难知道是怎么回事......但最有可能的,因为你正在失去你的preferredTransform属性的值,您的问题引起的。

全部AVAssetTrack对象具有preferredTransform属性,用于指定是否应旋转视频。如果您正在创建新的AVMutableAssetTrack对象,则可能需要设置该属性的值,以便视频保持预期方向。

根据我的理解,您有一些方向问题,例如纵向视频处于横向模式,有时视频会颠倒。这是由于默认的AVAsset方向。使用默认iPhone摄像头应用程序录制的所有影片和图像文件都将视频帧设置为横向,因此媒体将以横向模式保存。 AVAsset具有preferredTransform属性,其中包含媒体方向信息,并且只要您使用照片应用程序或QuickTime查看媒体文件,就会将其应用于媒体文件。 您可以通过将必要的变换应用于AVAsset对象,轻松地进行纠正。但是,由于您的两个视频文件可能有不同的方向,因此您需要使用两个独立的AVMutableCompositionTrack实例,而不是原来的一个(假设)。 创建两个AVMutableCompositionTrack视频轨迹 由于您现在有两个单独的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]; 
} 

最后添加说明,它只是应用于第二个轨道的方向修正。

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); 

希望这有助于