AVMutableVideoComposition does not works

MyCode:



class VideoComposeHelper {

    

    static func create(assets: [AVAsset], textSections: [TextSectionView], duration: Double, onDone: @escaping (AVMutableComposition,AVMutableVideoComposition) -> Void) {

        

        let composition = AVMutableComposition()

        let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID:Int32(kCMPersistentTrackID_Invalid))!

        let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID:Int32(kCMPersistentTrackID_Invalid))!

        

        var duration = 0.0

        

        do {

            for videoAsset in assets {

                print("videoAsset",duration)

                let cmTime = CMTimeMakeWithSeconds(duration, preferredTimescale: 1000)

                // video

                try videoTrack.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration),

                                                of: videoAsset.tracks(withMediaType:.video)[0] as AVAssetTrack, at: cmTime)

                // audio

                try audioTrack.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration),

                                                of: videoAsset.tracks(withMediaType:.audio)[0] as AVAssetTrack, at: cmTime)

                duration += videoAsset.duraSec()

            }

            

        } catch {

            print("darn")

        }

        

        let size = videoTrack.naturalSize

        let fillRect = CGRect(x: 0, y: 0, width: size.height, height: size.width)

        print("naturalSize",size)



        let parentlayer = CALayer()

        parentlayer.frame = fillRect

        parentlayer.zPosition = 100

        let videolayer = CALayer()

        videolayer.frame = fillRect

        parentlayer.addSublayer(videolayer)

        videolayer.isHidden = false

        parentlayer.isHidden = false

        

        for textSection in textSections {

            let imglayer = CALayer()

            imglayer.contents = textSection.getImage().cgImage

            imglayer.frame = fillRect

            imglayer.opacity = 1

            parentlayer.addSublayer(imglayer)

        }





        let layercomposition = AVMutableVideoComposition()

        layercomposition.frameDuration = CMTimeMake(value: 4, timescale: 30)

        layercomposition.renderSize = size

        layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videolayer, in: parentlayer)



        // instruction for watermark

        let instruction = AVMutableVideoCompositionInstruction()

        instruction.timeRange = CMTimeRangeMake(start: .zero, duration: composition.duration)



        let videotrack = composition.tracks(withMediaType: .video)[0] as AVAssetTrack

        let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)



        instruction.layerInstructions = [layerinstruction]

        layercomposition.instructions = [instruction]



        let FirstAssetScaleFactor = CGAffineTransform(scaleX: 1, y: 1)

        layerinstruction.setTransform(videoTrack.preferredTransform.concatenating(FirstAssetScaleFactor), at: .zero)

        

        onDone(composition,layercomposition)

    }



    func exportVideo(duration: Double, composition: AVMutableComposition, videoComposition: AVMutableVideoComposition) {

        

        let outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

            .appendingPathComponent("result.mp4")

        if FileManager.default.fileExists(atPath: outputURL.path) {

            do {

                try FileManager.default.removeItem(at: outputURL)

            } catch {

                print(error)

            }

        }

        print("outputURL",outputURL)

        let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)!

        exporter.videoComposition = videoComposition

        exporter.outputURL = outputURL

        exporter.outputFileType = .mp4

        exporter.shouldOptimizeForNetworkUse = true

        let start = CMTimeMakeWithSeconds(0, preferredTimescale: 1000)

        let range = CMTimeRangeMake(start: start, duration: CMTimeMakeWithSeconds(duration, preferredTimescale: 1000))

        exporter.timeRange = range

        exporter.exportAsynchronously {

            switch exporter.status {

            case .completed:

                //self.checkDuration(for: fileName, at: outputURL)

                PHPhotoLibrary.shared().performChanges({

                    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputURL)

                }) { completed, error in

                    if let error = error {

                        print("Failed to save video in photos", error)

                        return

                    }

                    DispatchQueue.main.async {

                        //self.view.isUserInteractionEnabled = true

                        if completed {

                            print("Video has been saved to your photos.")

                        } else {

                            print("Video saving has NOT been completed")

                        }

                    }

                }

            case .failed:

                print("failed with:", exporter.error ?? "no error")

            case .cancelled: break

            default: break

            }

        }

    }

}

When I run the code, it saves plain video with no texts which supposed to be handled by parentlayer.

AVMutableVideoComposition does not works
 
 
Q