【问题标题】:Video not rotating using AVMutableVideoCompositionLayerInstruction视频不使用 AVMutableVideoCompositionLayerInstruction 旋转
【发布时间】:2014-12-23 20:33:31
【问题描述】:

我正在尝试合并使用相机作为 UIImagePickerController 录制后获得的两个视频。我已成功将视频合二为一,但视频的方向有些问题。

根据我对 UIImagePickerController 的理解,所有视频都是横向拍摄的,这意味着纵向录制的视频会旋转 90°。

每次录制后,我都会将新视频添加到数组中

func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info:NSDictionary) {
    let tempImage = info[UIImagePickerControllerMediaURL] as NSURL
    videos.append(tempImage)
    let pathString = tempImage.relativePath
    self.dismissViewControllerAnimated(true, completion: {})
}

然后,当我想合并时,我会浏览每个视频并创建一条指令并将该指令添加到另一个数组中

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)

    }
}

创建完所有指令后,我将它们添加到主指令并创建导出会话。

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;

我错过了什么?

【问题讨论】:

    标签: ios swift avfoundation


    【解决方案1】:

    尝试在层指令的初始化程序中使用trackVideo,这样它将使用AVMutableCompositionTracktrackID而不是源资产的trackID

    更新:

    你只需要一个AVMutableVideoCompositionLayerInstruction,所以在循环之前以AVMutableCompositionTrack为参数声明它。然后在循环的每次迭代中,为您正在使用的当前视频资产设置图层指令的必要属性(变换、裁剪矩形)。您正在控制每次插入时应如何显示合成轨道中的视频内容。

    最后,将单层指令放入指令数组中,并在视频合成中使用。

    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)
    

    【讨论】:

    • 还是同样的问题,没有区别
    • 实际上,我认为您只需要一个rotater 的实例。只有一个视频合成轨道,因此您需要在循环外声明rotater,并将转换设置为在每个新视频的开始时间应用。如果您要连接视频,则也无需将不透明度设置为 0。下一个只会出现。
    • 如果我理解正确,我会在循环之前使用 trackVideo 创建旋转。然后在循环中我像以前一样设置转换。这也不起作用。 ://
    • 我在 Swift 4 中找不到 AVMutableVideoComposition 的任何成员“说明”。
    【解决方案2】:

    你有两层。您需要将旋转指令应用于合成中的两个图层。您在这里所做的是将旋转指令仅应用于其中一个。获取对视频合成中两个元素的引用,并对两个图层应用单独的说明。

    【讨论】:

    • 这不是我已经在做的吗?我在我的问题中添加了更多代码
    【解决方案3】:

    你可以使用这个简单的代码,它对我有用:

      var assetVideoTrack = (sourceAsset.tracksWithMediaType(AVMediaTypeVideo)).last as! AVAssetTrack
    
      var compositionVideoTrack = (composition.tracksWithMediaType(AVMediaTypeVideo)).last as! AVMutableCompositionTrack
    
      if (assetVideoTrack.playable && compositionVideoTrack.playable) {
    
           compositionVideoTrack.preferredTransform = assetVideoTrack.preferredTransform
       }
    

    【讨论】:

      猜你喜欢
      • 2011-07-08
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2023-02-15
      • 2015-01-15
      • 2014-05-20
      • 2019-03-10
      相关资源
      最近更新 更多