使用 AVMutableVideoComposition 导出后呈现为横向的纵向视频
Portrait video rendered as landscape after exporting with AVMutableVideoComposition
你好,我将两个视频与 AVMutableVideoComposition() 组合在一起,它适用于从 youtube 下载的横向视频和纵向视频,但是当尝试在 iPhone 或 android 中录制的纵向视频时,导出的视频出现 landscape/horizontal 而不是原始纵向/垂直。
如果对堆栈溢出和 google 进行了大量研究,但找不到任何可行的解决方案。
这篇 raywenderlich 的文章很好地解释了为什么视频处于横向模式,并在文章的 Orienting Video 部分提供了解决方法,首先检查视频是否为纵向,然后设置它的高度宽度和首选方向。但它不再起作用了。
我尝试手动将 AVAssetTrack 的 .preferredTransform 设置为 CGAffineTransform(a: 0.0, b: 1.0, c: -1.0, d: 0.0, tx: 0.0, ty: 0.0) 但不起作用。
许多旧答案建议将 AVAssetTrack 的 .preferredTransform 设置为 AvAsset 的 preferredTransform 但它不起作用。
从 AVAssetTrack 的 .preferredTransform 我可以知道视频是否为纵向但无法更改它,非常感谢任何帮助,谢谢。
在搜索并尝试了很多事情之后,我这样做来解决问题,首先我使用 raywenderlich 文章中的这个功能检查方向。
func orientationFromTransform(
_ transform: CGAffineTransform
) -> (orientation: UIImage.Orientation, isPortrait: Bool) {
var assetOrientation = UIImage.Orientation.up
var isPortrait = false
let tfA = transform.a
let tfB = transform.b
let tfC = transform.c
let tfD = transform.d
if tfA == 0 && tfB == 1.0 && tfC == -1.0 && tfD == 0 {
assetOrientation = .right
isPortrait = true
} else if tfA == 0 && tfB == -1.0 && tfC == 1.0 && tfD == 0 {
assetOrientation = .left
isPortrait = true
} else if tfA == 1.0 && tfB == 0 && tfC == 0 && tfD == 1.0 {
assetOrientation = .up
} else if tfA == -1.0 && tfB == 0 && tfC == 0 && tfD == -1.0 {
assetOrientation = .down
}
return (assetOrientation, isPortrait)
}
并存储它
let firstAssetInfo = orientationFromTransform(firstVideoTrack!.preferredTransform)
然后在添加转换指令之前,我检查它是否为纵向,然后手动将其转换为纵向并根据其设置缩放比例,并将其宽度用作高度,将高度用作宽度,如果它不是纵向,则执行我正在做的事情之前。
let firstLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
if firstAssetInfo.isPortrait {
let rotate = __CGAffineTransformMake(0.0, 1.0, -1.0, 0.0, 0.0, 0.0)
let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = rotate.concatenating(scale).concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)
} else {
let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = scale.concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)
}
07:16:45.410 I/TrackGather updateClient client=TrackClient@51a7a21a{tag=5c2da814}
07:16:45.411 I/TrackUpload updateClient client=TrackClient@51a7a21a{tag=5c2da814}
07:16:45.414 I/TrackController onAppStateChanged state=FOREGROUND page=SplashActivity
07:16:45.484 I/TrackUploadCacheTask 上传任务因客户端存在而被忽略
07:16:45.872 I/TrackController onAppStateChanged state=FOREGROUND page=HomePageActivity
07:16:46.199 I/TrackController onAppStateChanged state=FOREGROUND page=HomePageActivity
07:16:46.628 I/TrackLoc onDirectLocError
你好,我将两个视频与 AVMutableVideoComposition() 组合在一起,它适用于从 youtube 下载的横向视频和纵向视频,但是当尝试在 iPhone 或 android 中录制的纵向视频时,导出的视频出现 landscape/horizontal 而不是原始纵向/垂直。
如果对堆栈溢出和 google 进行了大量研究,但找不到任何可行的解决方案。
这篇 raywenderlich 的文章很好地解释了为什么视频处于横向模式,并在文章的 Orienting Video 部分提供了解决方法,首先检查视频是否为纵向,然后设置它的高度宽度和首选方向。但它不再起作用了。
我尝试手动将 AVAssetTrack 的 .preferredTransform 设置为 CGAffineTransform(a: 0.0, b: 1.0, c: -1.0, d: 0.0, tx: 0.0, ty: 0.0) 但不起作用。
许多旧答案建议将 AVAssetTrack 的 .preferredTransform 设置为 AvAsset 的 preferredTransform 但它不起作用。
从 AVAssetTrack 的 .preferredTransform 我可以知道视频是否为纵向但无法更改它,非常感谢任何帮助,谢谢。
在搜索并尝试了很多事情之后,我这样做来解决问题,首先我使用 raywenderlich 文章中的这个功能检查方向。
func orientationFromTransform(
_ transform: CGAffineTransform
) -> (orientation: UIImage.Orientation, isPortrait: Bool) {
var assetOrientation = UIImage.Orientation.up
var isPortrait = false
let tfA = transform.a
let tfB = transform.b
let tfC = transform.c
let tfD = transform.d
if tfA == 0 && tfB == 1.0 && tfC == -1.0 && tfD == 0 {
assetOrientation = .right
isPortrait = true
} else if tfA == 0 && tfB == -1.0 && tfC == 1.0 && tfD == 0 {
assetOrientation = .left
isPortrait = true
} else if tfA == 1.0 && tfB == 0 && tfC == 0 && tfD == 1.0 {
assetOrientation = .up
} else if tfA == -1.0 && tfB == 0 && tfC == 0 && tfD == -1.0 {
assetOrientation = .down
}
return (assetOrientation, isPortrait)
}
并存储它
let firstAssetInfo = orientationFromTransform(firstVideoTrack!.preferredTransform)
然后在添加转换指令之前,我检查它是否为纵向,然后手动将其转换为纵向并根据其设置缩放比例,并将其宽度用作高度,将高度用作宽度,如果它不是纵向,则执行我正在做的事情之前。
let firstLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
if firstAssetInfo.isPortrait {
let rotate = __CGAffineTransformMake(0.0, 1.0, -1.0, 0.0, 0.0, 0.0)
let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = rotate.concatenating(scale).concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)
} else {
let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = scale.concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)
}
07:16:45.410 I/TrackGather updateClient client=TrackClient@51a7a21a{tag=5c2da814} 07:16:45.411 I/TrackUpload updateClient client=TrackClient@51a7a21a{tag=5c2da814} 07:16:45.414 I/TrackController onAppStateChanged state=FOREGROUND page=SplashActivity 07:16:45.484 I/TrackUploadCacheTask 上传任务因客户端存在而被忽略 07:16:45.872 I/TrackController onAppStateChanged state=FOREGROUND page=HomePageActivity 07:16:46.199 I/TrackController onAppStateChanged state=FOREGROUND page=HomePageActivity 07:16:46.628 I/TrackLoc onDirectLocError