Last active
December 13, 2016 11:30
-
-
Save duzvik/853c0564dde684c1263d0f2a78dfde7e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if let asset = firstAsset { | |
| // 2 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances. | |
| let cmp = AVMutableComposition() | |
| // 3 - Video track | |
| let track = cmp.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) | |
| guard let sourceVideoTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first else {return} | |
| try! track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, asset.duration), of: sourceVideoTrack, at: kCMTimeZero) | |
| // 3.1 - Create AVMutableVideoCompositionInstruction | |
| let instruction = AVMutableVideoCompositionInstruction() | |
| instruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration) | |
| // 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation. | |
| let videolayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track) | |
| let videoAssetTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first | |
| var videoAssetOrientation: UIImageOrientation | |
| var isVideoAssetPortrait = false | |
| let videoTransform = videoAssetTrack!.preferredTransform | |
| if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) { | |
| videoAssetOrientation = .right | |
| isVideoAssetPortrait = true | |
| } | |
| if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) { | |
| videoAssetOrientation = .left | |
| isVideoAssetPortrait = true | |
| } | |
| if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) { | |
| videoAssetOrientation = .up | |
| } | |
| if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) { | |
| videoAssetOrientation = .down | |
| } | |
| videolayerInstruction.setTransform((videoAssetTrack!.preferredTransform), at: kCMTimeZero) | |
| videolayerInstruction.setOpacity(0.0, at: asset.duration) | |
| // 3.3 - Add instructions | |
| instruction.layerInstructions = [videolayerInstruction] | |
| let animComp = AVMutableVideoComposition() | |
| var naturalSize: CGSize | |
| if isVideoAssetPortrait { | |
| naturalSize = CGSize(width: track.naturalSize.height, height: track.naturalSize.width) | |
| } else { | |
| naturalSize = track.naturalSize | |
| } | |
| animComp.renderSize = naturalSize | |
| animComp.instructions = [instruction] | |
| animComp.frameDuration = CMTimeMake(1, 30); | |
| let parentLayer = CALayer() | |
| let videoLayer = CALayer() | |
| let aLayer = CALayer() | |
| aLayer.frame = CGRect(x: 100, y: 100, width: 100, height: 100) | |
| aLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) | |
| aLayer.contents = UIImage(named: "mask.png")?.cgImage | |
| aLayer.opacity = 0.5 | |
| aLayer.backgroundColor = UIColor.red.cgColor | |
| parentLayer.frame = CGRect(x: 0, y: 0, width: naturalSize.width, height: naturalSize.height) | |
| videoLayer.frame = CGRect(x: 0, y: 0, width: naturalSize.width, height: naturalSize.height) | |
| parentLayer.backgroundColor = UIColor.blue.cgColor | |
| videoLayer.backgroundColor = UIColor.green.cgColor | |
| parentLayer.addSublayer(videoLayer) | |
| parentLayer.addSublayer(aLayer) | |
| animComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) | |
| // 4 - Get path | |
| let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] | |
| let dateFormatter = DateFormatter() | |
| dateFormatter.dateStyle = .long | |
| dateFormatter.timeStyle = .short | |
| let date = dateFormatter.string(from: Date()) | |
| let savePath = (documentDirectory as NSString).appendingPathComponent("mergeVideo-\(date).mov") | |
| let url = URL(fileURLWithPath: savePath) | |
| // 5 - Create Exporter | |
| guard let exporter = AVAssetExportSession(asset: cmp, presetName: AVAssetExportPresetHighestQuality) else { return } | |
| exporter.outputURL = url | |
| exporter.outputFileType = AVFileTypeQuickTimeMovie | |
| exporter.shouldOptimizeForNetworkUse = true | |
| exporter.videoComposition = animComp | |
| // 6 - Perform the Export | |
| exporter.exportAsynchronously() { | |
| DispatchQueue.main.async { _ in | |
| self.exportDidFinish(exporter) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment