iPhone SDK. 是否可以使用 AVURLAsset / AVMutableComposition 在 AVPlayer 中旋转视频?

10
我有一个简单的视频编辑视图,使用AVPlayer。我使用一个或多个AVURLAsset创建AVMutableComposition。一切正常,但是视频总是旋转90度。例如,如果源视频是竖屏拍摄,则AVPlayer以横屏模式显示,反之亦然。我已经查阅了文档并进行了搜索,但无法找到解决方法。也许我在错误的地方寻找。

有人可以帮忙吗?

提前感谢;

Jean-Pierre


在观看了关于AVFoundation的WWDC10会议后,我相信有一个设置选项,但我需要再次观看。我确定后会发布答案。 - Jean-Pierre Semery
1
你解决过这个问题吗?我也遇到了同样的问题。 - Jeremie Weldin
你解决了这个问题吗?我也遇到了同样的问题,不知道该怎么办。 - Gaby Fitcal
2个回答

4
据我了解,您遇到了一些方向问题,例如纵向视频处于横向模式,有时视频会倒置。这是由于默认的AVAsset方向引起的。所有使用默认iPhone相机应用程序记录的电影和图像文件都将视频帧设置为横向,因此媒体以横向模式保存。 AVAsset具有一个preferredTransform属性,其中包含媒体方向信息,每当您使用Photos应用程序或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);

希望这能帮到你。

1

没有代码进行检查,很难知道发生了什么......但最有可能的是,您的问题是由于丢失了preferredTransform属性的值而引起的。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接