如何解决前后摄像头合并视频时的方向问题

5

我正在合并多个视频(实现暂停按钮),除了从后置摄像头和前置摄像头合并视频时,其中一个视频在新视频(合并后的视频)中倒置之外,一切正常。以下是我的代码:

let mixComposition = AVMutableComposition() 

let videoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let trackAudio = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())

var insertTime = kCMTimeZero
for var i = 0; i < currentAssets.count; i++ {
    let tracks = currentAssets[i].tracksWithMediaType(AVMediaTypeVideo)
    let audios = currentAssets[i].tracksWithMediaType(AVMediaTypeAudio)
                    
    let assetTrack:AVAssetTrack = tracks[0] as AVAssetTrack
    try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, currentAssets[i].duration), ofTrack: assetTrack, atTime: insertTime)
    let assetTrackAudio:AVAssetTrack = audios[0] as AVAssetTrack
    try trackAudio.insertTimeRange(CMTimeRangeMake(kCMTimeZero, currentAssets[i].duration), ofTrack: assetTrackAudio, atTime: insertTime)
    insertTime = CMTimeAdd(insertTime, currentAssets[i].duration)
}
videoTrack.preferredTransform = assetTrack.preferredTransform

let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains: .UserDomainMask).last!
let mediaURL = documentsURL.URLByAppendingPathComponent(AppMediaFolder)
let savePath = mediaURL.URLByAppendingPathComponent("\(NSUUID().UUIDString).mp4").path!
        
self.createDirectoryIfExists(mediaURL)
let url = NSURL(fileURLWithPath: savePath)
        
currentAssets.removeAll()
currentAssets.append(AVAsset(URL: url))
        
//Create Exporter
let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
exporter.outputURL = url
exporter.outputFileType = AVFileTypeMPEG4
exporter.shouldOptimizeForNetworkUse = true
                

你解决了吗?我也遇到了同样的问题 @Ivan Slavov - pigeon_39
1个回答

5
你需要注意 AVMutableVideoCompositionrenderSizeAVMutableVideoCompositionLayerInstruction 的变换。为了正确对齐它们,你需要旋转和平移视频,并使用正确的角度。如果要将其翻转,你需要将其旋转180度并将其平移到正确的坐标位置:
...
videoComposition.renderSize = CGSizeMake(X, Y)
...
let translate = CGAffineTransformMakeTranslation(X, Y);
let rotate = CGAffineTransformRotate(translate, CGFloat(ANGLE_IN_RADIANS))
...    

在我的情况下,renderSize和翻译设置为1280和720,180度旋转基本上是以弧度表示的M_PI:

let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = CGSizeMake(1280, 720)
videoComposition.frameDuration = CMTimeMake(1, 30)

let videoInstruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(180, 30))

let transformInstruction:AVMutableVideoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
let translate = CGAffineTransformMakeTranslation(1280, 720);
let rotate = CGAffineTransformRotate(translate, CGFloat(M_PI))

transformInstruction.setTransform(rotate, atTime: kCMTimeZero)
videoInstruction.layerInstructions = [transformInstruction]
videoComposition.instructions = [videoInstruction]

最后,您仍需要将此videoComposition添加到您的AVAssetExportSession中,以使转换生效。

1
你能否详细说明一下你的答案?我也遇到了同样的问题 @gigo - pigeon_39
2
在你指定timeRange的地方,那不应该写成“instruction”,而是“videoInstruction”对吗?“clipVideoTrack”是什么? - Chewie The Chorkie
我需要720x1280,以下是解决旋转问题的代码:let translate = CGAffineTransformMakeTranslation(720, 1280); let rotate = CGAffineTransformRotate(translate, CGFloat(M_PI) 但在 Swift 中应该这样写:let translate = CGAffineTransform(translationX: 720, y: 1280); let rotate = translate.rotated(by: CGFloat(Double.pi)) - Lance Samaria

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