11.9 C
New York
Thursday, December 12, 2024

ios – The identical video is displayed on each layers


I am creating two layers for a video and attempting to show my very own URL with a video on every separate layer. What am I doing improper? I’ve solely the primary video displayed within the remaining consequence on the video layer and on the overlay layer.
Challenge: Within the remaining output video, I solely see the video from the primary URL (videoURL) on each the video layer and the overlay layer. The overlay layer doesn’t show the video from overlayVideoURL as anticipated.
What I’ve Tried:
I checked the CALayer frames and confirmed that they’re set accurately.
Verified that AVVideoCompositionCoreAnimationTool is used accurately.
Confirmed that AVMutableComposition has each tracks inserted.
Questions:
Is there a mistake in how I’m organising the video layers?
How can I make sure that every layer shows its respective video accurately?
Extra Particulars:
The movies are accurately loaded and inserted into the AVMutableComposition.
The ultimate composition solely shows the video from videoURL on each layers.

 func makeVideo(videoURL: URL, overlayVideoURL: URL, forName identify: String, onComplete: @escaping (URL?) -> Void) {
            let asset = AVURLAsset(url: videoURL)
            let overlayAsset = AVURLAsset(url: overlayVideoURL)
            let composition = AVMutableComposition()
            guard
                let compositionTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid),
                let assetTrack = asset.tracks(withMediaType: .video).first,
                let overlayCompositionTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid),
                let overlayAssetTrack = overlayAsset.tracks(withMediaType: .video).first
            else {
                print("One thing is improper with the belongings.")
                onComplete(nil)
                return
            }
            do {
                let timeRange = CMTimeRange(begin: .zero, period: asset.period)
                attempt compositionTrack.insertTimeRange(timeRange, of: assetTrack, at: .zero)
                attempt overlayCompositionTrack.insertTimeRange(timeRange, of: overlayAssetTrack, at: .zero)
            } catch {
                print(error)
                onComplete(nil)
                return
            } 
            let videoInfo = orientation(from: assetTrack.preferredTransform)
            let videoSize = videoInfo.isPortrait ? CGSize(width: assetTrack.naturalSize.top, top: assetTrack.naturalSize.width) : assetTrack.naturalSize
            let videoComposition = AVMutableVideoComposition()
            videoComposition.renderSize = videoSize
            videoComposition.frameDuration = CMTime(worth: 1, timescale: 30) 
            let instruction = AVMutableVideoCompositionInstruction()
            instruction.timeRange = CMTimeRange(begin: .zero, period: composition.period)
            let layerInstruction = compositionLayerInstruction(for: compositionTrack, assetTrack: assetTrack)
            let overlayLayerInstruction = compositionLayerInstruction(for: overlayCompositionTrack, assetTrack: overlayAssetTrack)
            instruction.layerInstructions = [layerInstruction, overlayLayerInstruction]
            videoComposition.directions = [instruction]
            let videoLayer = CALayer()
            videoLayer.body = CGRect(origin: .zero, measurement: videoSize)
            let overlayVideoLayer = CALayer()
            overlayVideoLayer.body = CGRect(x: videoSize.width / 4, y: videoSize.top / 4, width: videoSize.width / 2, top: videoSize.top / 2)
            let outputLayer = CALayer()
            outputLayer.body = CGRect(origin: .zero, measurement: videoSize)
            outputLayer.addSublayer(videoLayer)
            outputLayer.addSublayer(overlayVideoLayer)
            videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayers: [videoLayer, overlayVideoLayer], in: outputLayer)
            guard let export = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else {
                print("Can't create export session.")
                onComplete(nil)
                return
            }
            let videoName = UUID().uuidString
            let exportURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(videoName).appendingPathExtension("mov")
            export.videoComposition = videoComposition
            export.outputFileType = .mov
            export.outputURL = exportURL
            export.exportAsynchronously {
                DispatchQueue.essential.async {
                    change export.standing {
                    case .accomplished:
                        onComplete(exportURL)
                    default:
                        print("One thing went improper throughout export.")
                        print(export.error ?? "unknown error")
                        onComplete(nil)
                    }
                }
            }
        }

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles