如何通过合并来自前后摄像头的视频来解决我的方向问题
How to fix my orientation issue with merging videos from front and back camera
我正在合并多个视频(暂停按钮的植入)并且一切正常,除了将来自后置摄像头的视频与来自前置摄像头的视频合并时,其中一个视频在新视频(合并视频)中颠倒了.我的代码:
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
您需要小心 AVMutableVideoComposition
的 renderSize
和 AVMutableVideoCompositionLayerInstruction
的转换。
要正确对齐它们,您需要 翻译 和 旋转 视频以正确的度数。要翻转它,您需要将它旋转 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
以使转换生效。
我正在合并多个视频(暂停按钮的植入)并且一切正常,除了将来自后置摄像头的视频与来自前置摄像头的视频合并时,其中一个视频在新视频(合并视频)中颠倒了.我的代码:
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
您需要小心 AVMutableVideoComposition
的 renderSize
和 AVMutableVideoCompositionLayerInstruction
的转换。
要正确对齐它们,您需要 翻译 和 旋转 视频以正确的度数。要翻转它,您需要将它旋转 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
以使转换生效。