AVComposition后将视频旋转为人像

时间:2018-06-27 22:12:28

标签: ios swift xcode avfoundation avcomposition

在我的应用程序中,用户可以记录多个纵向视频,这些视频存储在AVAsset数组中,然后在下面附加的功能中合并到一个视频文件中。在合并过程中,视频已旋转为横向,通过变换动作,我已经能够将其旋转为纵向。 导出的视频是水平翻转的-如何在不水平翻转的情况下将视频旋转为纵向?

func mergeVideoArray(){


        //This merges all video files of the array that we just recorded.
        var arrayVideos = self.videoArray //Videos Array
        var atTimeM: CMTime = CMTimeMake(0, 0)
        var lastAsset: AVAsset!
        var layerInstructionsArray = [AVVideoCompositionLayerInstruction]()
        var completeTrackDuration: CMTime = CMTimeMake(0, 1)
        var videoSize: CGSize = CGSize(width: 0.0, height: 0.0)
        var totalTime : CMTime = CMTimeMake(0, 0)

        let mixComposition = AVMutableComposition()
        let videoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
        let soundTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)

        for videoAsset in arrayVideos {

            do {
                try videoTrack!.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaType.video)[0], at: totalTime)
                try soundTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaType.audio)[0], at: totalTime)

                videoSize = (videoTrack?.naturalSize)!
            }

            catch let error as NSError { print("error: \(error.localizedDescription)") }

            totalTime = CMTimeAdd(atTimeM, videoAsset.duration) // <-- Update the total time for all videos.
            completeTrackDuration = CMTimeAdd(completeTrackDuration, videoAsset.duration)


            //Rotates the video to portrait
            let videoInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack!)
            var transform:CGAffineTransform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            transform = transform.translatedBy(x: -((videoTrack?.naturalSize.width)!), y: 0.0)
            transform = transform.rotated(by: CGFloat(Double.pi/2))
            transform = transform.translatedBy(x: 0.0, y: -((videoTrack?.naturalSize.width)!))


            videoInstruction.setTransform(transform, at: kCMTimeZero)

            if videoAsset != videoArray.last{
                videoInstruction.setOpacity(0.0, at: completeTrackDuration)
            }
            layerInstructionsArray.append(videoInstruction)
            lastAsset = videoAsset
        }

        let mainInstruction = AVMutableVideoCompositionInstruction()
        mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, completeTrackDuration)
        mainInstruction.layerInstructions = layerInstructionsArray

        let mainComposition = AVMutableVideoComposition()
        mainComposition.instructions = [mainInstruction]
        mainComposition.frameDuration = CMTimeMake(1, 30)
        mainComposition.renderSize = CGSize(width: videoSize.height, height: videoSize.width)

        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .short
        let date = dateFormatter.string(from: NSDate() as Date)
        let savePath = (documentDirectory as NSString).appendingPathComponent("mergeVideo-\(date).mov")
        let url = NSURL(fileURLWithPath: savePath)

        let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
        exporter!.outputURL = url as URL
        exporter!.outputFileType = AVFileType.mp4
        exporter!.shouldOptimizeForNetworkUse = true
        exporter!.videoComposition = mainComposition
        exporter!.exportAsynchronously {


            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL:  exporter!.outputURL!)
            }) { saved, error in
                if saved {
                    let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
                    let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alertController.addAction(defaultAction)
                    self.present(alertController, animated: true, completion: nil)
                } else{
                    print("video erro: \(error?.localizedDescription)")

                }

           }
        }
    }

0 个答案:

没有答案