视频无法使用AVMutableVideoCompositionLayerInstruction旋转 [英] Video not rotating using AVMutableVideoCompositionLayerInstruction
问题描述
我正在尝试将使用相机作为UIImagePickerController录制后录制的两个视频合并。我已成功将视频合并为一个,但我对视频的方向有一些问题。
I'm trying to merge two videos I get after recording using the camera as a UIImagePickerController. I've succeeded with combining the videos into one but I have some problems with the orientation of the videos.
正如我所知,UIImagePickerController是所有视频在横向捕捉,这意味着以纵向录制的视频旋转90°。
As I've understood it with the UIImagePickerController is that all videos are captured in landscape, this means that the videos recorded in portrait are rotated 90°.
每次录制后我将新视频添加到阵列
After each recording I add the new video to an array
func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info:NSDictionary) {
let tempImage = info[UIImagePickerControllerMediaURL] as NSURL
videos.append(tempImage)
let pathString = tempImage.relativePath
self.dismissViewControllerAnimated(true, completion: {})
}
然后当我想要合并时,我会浏览每个视频并创建一条指令并将指令添加到另一个数组
Then when I want to merge I go through each video and create an instruction and adds the instruction to another array
var composition = AVMutableComposition()
let trackVideo:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let trackAudio:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
var insertTime = kCMTimeZero
for i in 0...(videos.count-1){
let moviePathUrl = videos[i]
let sourceAsset = AVURLAsset(URL: moviePathUrl, options: nil)
let tracks = sourceAsset.tracksWithMediaType(AVMediaTypeVideo)
let audios = sourceAsset.tracksWithMediaType(AVMediaTypeAudio)
if tracks.count > 0{
var videoDuration = CMTimeRangeMake(kCMTimeZero, sourceAsset.duration);
let assetTrack:AVAssetTrack = tracks[0] as AVAssetTrack
let assetTrackAudio:AVAssetTrack = audios[0] as AVAssetTrack
trackVideo.insertTimeRange(videoDuration, ofTrack: assetTrack, atTime: insertTime, error: nil)
trackAudio.insertTimeRange(videoDuration, ofTrack: assetTrackAudio, atTime: insertTime, error: nil)
//Rotate
var rotater = AVMutableVideoCompositionLayerInstruction(assetTrack: assetTrack)
rotater.setTransform(assetTrack.preferredTransform, atTime: insertTime)
rotater.setOpacity(0.0, atTime: CMTimeAdd(insertTime, sourceAsset.duration))
instructions.append(rotater)
//Resize
var resizer = AVMutableVideoCompositionLayerInstruction(assetTrack: assetTrack)
resizer.setCropRectangle(CGRectMake(0, 0, 300, 300), atTime: insertTime)
instructions.append(resizer)
insertTime = CMTimeAdd(insertTime, sourceAsset.duration)
}
}
当我创建了所有指令后,我将它们添加到主指令并创建导出会话。
When I've created all the instructions I add them to the main instruction and create the export session.
var instruction = AVMutableVideoCompositionInstruction();
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, insertTime);
instruction.layerInstructions = instructions;
var mainCompositionInst = AVMutableVideoComposition()
mainCompositionInst.instructions = NSArray(object: instruction)
mainCompositionInst.frameDuration = CMTimeMake(1, 60);
mainCompositionInst.renderSize = CGSizeMake(300, 300);
var exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
exporter.videoComposition = mainCompositionInst;
我缺少什么?
推荐答案
尝试在图层指令的初始化程序中使用 trackVideo
,这样它将使用 AVMutableCompositionTrack
的 trackID
而不是源资产的 trackID
Try using trackVideo
in the initializer for your layer Instruction so it will use the AVMutableCompositionTrack
's trackID
rather than the source asset's trackID
更新:
你只需要一个 AVMutableVideoCompositionLayerInstruction
,所以在循环前用 AVMutableCompositionTrack
作为参数。然后在循环的每次迭代中,为您正在使用的当前视频资产设置图层指令(transform,crop rect)的必要属性。您正在控制合成轨道中视频内容在每次插入时的显示方式。
You only need one AVMutableVideoCompositionLayerInstruction
, so declare it before the loop with the AVMutableCompositionTrack
as the parameter. Then on each iteration of the loop, set the necessary properties of the layer instruction (transform, crop rect) for the current video asset you're working with. You're controlling how the video content in the composition track should be displayed at each insert time.
最后,将单个layerInstruction放在指令数组中,然后使用在视频合成中。
At the end, place the single layerInstruction in the instructions array, and use that in the video composition.
var layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: trackVideo)
for i in 0...(videos.count-1){
//...your other code here
layerInstruction.setTransform(assetTrack.preferredTransform, atTime: insertTime)
layerInstruction.setCropRectangle(CGRectMake(0, 0, 300, 300), atTime: insertTime)
}
var instruction = AVMutableVideoCompositionInstruction();
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, insertTime);
instruction.layerInstructions = NSArray(object: layerInstruction);
var mainCompositionInst = AVMutableVideoComposition()
mainCompositionInst.instructions = NSArray(object: instruction)
这篇关于视频无法使用AVMutableVideoCompositionLayerInstruction旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!