快速叠加多个视频

时间:2018-06-27 15:04:31

标签: iphone avfoundation swift4 ios11

我试图将目标C代码转换为Swift 4,该代码是在另一个视频http://www.theappguruz.com/blog/ios-overlap-multiple-videos上添加视频,这是Objective-C代码  我收到此错误: “(错误域= AVFoundationErrorDomain代码= -11841“操作已停止” UserInfo = {NSLocalizedFailureReason =无法合成视频。,NSLocalizedDescription =操作已停止,NSUnderlyingError = 0x604000646cf0 {错误域= NSOSStatusErrorDomain代码= -17390”(空)“}} }) “

class func mergeVideos(firestUrl : URL , SecondUrl : URL ){

    let firstAssets = AVAsset(url: firestUrl)
    let secondAssets = AVAsset(url: SecondUrl)

    let mixComposition = AVMutableComposition()

    let firstTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
    let seconTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)

    do{
  try   firstTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, firstAssets.duration), of: firstAssets.tracks(withMediaType: .video)[0], at: kCMTimeZero)
    try seconTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, secondAssets.duration), of: secondAssets.tracks(withMediaType: .video)[0], at: kCMTimeZero)


    }catch{


    }

    let mainInstraction = AVMutableVideoCompositionInstruction()

    mainInstraction.timeRange  = CMTimeRangeMake(kCMTimeZero, firstAssets.duration)

    let firstLayerInstraction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)
    let scale = CGAffineTransform(scaleX: 0.6, y: 0.6)
    let move = CGAffineTransform(translationX: 0, y: 0)
    let transform = scale.concatenating(move)
    firstLayerInstraction.setTransform(transform, at: kCMTimeZero)


    let secondLayerInstraction = AVMutableVideoCompositionLayerInstruction(assetTrack: seconTrack!)
    let secondScale = CGAffineTransform(scaleX: 0.9, y: 0.9)
    let secondMove = CGAffineTransform(translationX: 0, y: 0)
    let secondTransform = secondScale.concatenating(secondMove)
    secondLayerInstraction.setTransform(secondTransform, at: kCMTimeZero)

 let  mainCompositonInst = AVMutableVideoComposition()
    mainCompositonInst.instructions = [mainInstraction]
    mainCompositonInst.frameDuration = CMTimeMake(1, 30)
    mainCompositonInst.renderSize = CGSize(width:(firstTrack?.naturalSize.width)!, height:(firstTrack?.naturalSize.height)! )


  let saveUrl = URL(fileURLWithPath: NSHomeDirectory() + "/Documents/1.mp4")






   guard let assetExport = AVAssetExportSession(asset: mixComposition, presetName:AVAssetExportPresetHighestQuality) else {return}
    assetExport.videoComposition = mainCompositonInst
    assetExport.outputFileType = .mp4
    assetExport.outputURL = saveUrl
    assetExport.exportAsynchronously(completionHandler: {
        switch assetExport.status{
        case  AVAssetExportSessionStatus.failed:
            print("failed \(assetExport.error)")
        case AVAssetExportSessionStatus.cancelled:
            print("cancelled \(assetExport.error)")
        case AVAssetExportSessionStatus.completed:
            print("Completed")
        default:
            print("unknown")
        }
    })

}

1 个答案:

答案 0 :(得分:0)

我有解决问题的办法。 我只需要在AVMutableVideoCompositionInstruction属性中添加layerInstractions,代码就可以正常工作。 这行代码将解决问题:

    mainInstraction.layerInstructions = [firstLayerInstraction , secondLayerInstraction]