Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TextView Text and Imageview images on the video during export. #354

Open
2 tasks
mobileexpert1 opened this issue Mar 2, 2023 · 7 comments
Open
2 tasks

Comments

@mobileexpert1
Copy link

Checklist

@mobileexpert1
Copy link
Author

mobileexpert1 commented Mar 2, 2023

Hello Team,
May you suggest me, how to add textview text and imageview images on the top of video while exporting the final video with composition.
Whenever i am exporting the video, it's blinking.
I am using this piece of code.

\\*********************** Export Method *********************************\\\\

func export(_ videoAsset:AVAsset?,_ videoComposition:MTIVideoComposition?,_ completion: @escaping (Result<URL, Error>) -> Void) {
guard let asset = videoAsset, let videoComposition = videoComposition else {
return
}
exportProgress = nil
exportSession?.cancel()
exportSession = nil
var configuration = AssetExportSession.Configuration(fileType: .mp4, videoSettings: .h264(videoSize: videoComposition.renderSize), audioSettings: .aac(channels: 2, sampleRate: 44100, bitRate: 128 * 1000))
configuration.videoComposition = videoComposition.makeAVVideoComposition()

    let fileManager = FileManager()
    let outputURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString).appendingPathExtension(".mp4")
    //        URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("temp.mp4")
    //        try? fileManager.removeItem(at: outputURL)
    //        let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString).appendingPathExtension("mp4")
    //        try? fileManager.removeItem(at: outputURL)
    
    do {
        let exportSession = try AssetExportSession(asset: asset, outputURL: outputURL, configuration: configuration)
        exportSession.export(progress: { [weak self] progress in
            self?.exportProgress = progress
            let value = self!.exportProgress!.fractionCompleted
            ProgressHUD.showProgress(value)
            print("progress value is ",value)
            print(progress)
        }, completion: { [weak self] error in
            self?.exportProgress = nil
            self?.exportSession = nil
            if let error = error {
                completion(.failure(error))
            } else {
                completion(.success(outputURL))
            }
        })
        self.exportSession = exportSession
    } catch {
        completion(.failure(error))
    }
}

@mobileexpert1 mobileexpert1 changed the title Hello Team, Add TextView Text and Imageview images on the video during export. Mar 2, 2023
@YuAo
Copy link
Member

YuAo commented Mar 4, 2023

How did you build the MTIVideoComposition? Did the preview blink?

@mobileexpert1
Copy link
Author

May be there a extra layer of images adding on video so that it is looking like it's blinking.

7A41B068-DA9F-41B6-A8F3-E3232C26313C.MP4

@mobileexpert1
Copy link
Author

//MARK: 🚀🚀Export Video

func exportVideo(){
    LocalStore.instance.export = true
    FilterImage.shared.export(self.videoAsset,VideoCompositon) { result  in
        switch result {
        case .success(let outputURL):
            self.tempOutputUrl = outputURL
            let url = outputURL as AnyObject

// self.exportFile(outputImg: url )
self.exportFile(outputImg: url) { present in
if present{ //-- while Present activityController
FilterImage.shared.multiLayerFilter.layers.removeAll()
let _: [()] = self.containerView.subviews.compactMap { $0.isHidden = false}
MyPlayer.share.player?.play()
MyPlayer.share.player?.currentItem?.videoComposition = VideoCompositon?.makeAVVideoComposition()
}
else{ //-- while Dismiss activityController
FilterImage.shared.multiLayerFilter.layers.removeAll()
let _: [()] = self.containerView.subviews.compactMap { $0.isHidden = false}
try? FileManager.default.removeItem(at: self.tempOutputUrl!)
// let fileManager = FileManager()
// try? fileManager.removeItem(at: self.tempOutputUrl!)
}
LocalStore.instance.export = false
}

        case .failure(let error):
            print(error)
            FilterImage.shared.multiLayerFilter.layers.removeAll()
            let _: [()] = self.containerView.subviews.compactMap { $0.isHidden = false}
            ProgressHUD.showFailed("\(error)")
            MyPlayer.share.player?.play()
        }
    }
}

@mobileexpert1
Copy link
Author

// MARK: --- MTIVideoComposition Method

static func DemoFilter(asset :AVAsset,render:MTIContext) -> MTIVideoComposition?{ //    --- MPSDefinitionFilter
    FilterImage.shared.isApplyFilter = true
    FilterImage.shared.filterdImage = nil
    let blendFilter = MTIBlendFilter(blendMode: overBlendMode)
    let lookup = MTIColorLookupFilter()
    let multilayerFilter = MTIMultilayerCompositingFilter()
    
    let composition = MTIVideoComposition(asset: asset, context: render, queue: DispatchQueue.main, filter: { request in
        guard let sourceImage = request.anySourceImage else {
            return MTIImage.transparent
        }
        FilterImage.shared.orignalImage = sourceImage
        if let uiImg = GlobalStruct.ColorLookUp {
            let MtImg = DemoImages.convertUiToMti(image: uiImg)
            lookup.inputColorLookupTable = MtImg
        }
        else{
            let uiImg = UIImage(named: "Trans")
            let MtImg = DemoImages.convertUiToMti(image: uiImg)
            lookup.inputColorLookupTable = MtImg
        }
        
        
        if let uiImg = GlobalStruct.overlayImage {
            let MtImg = DemoImages.convertUiToMti(image: uiImg)
            blendFilter.inputImage = MtImg
            blendFilter.intensity = blendIntensty
        }
        else{
            blendFilter.inputImage = MTIImage.transparent
            blendFilter.intensity = blendIntensty
        }
        
        
        if LocalStore.instance.export{
            imageLayerDataArr.forEach { object in
                let val = object.value
                guard let img = val.image else{return}
                let position = val.xy
                let size = val.size
                let opacity = val.opacity
                let rotate = val.rotation
                
                let clayer1 = MTILayer(content: img, layoutUnit: .pixel, position: position ?? .zero , size: size ?? CGSize(width: 1000, height: 1500) , rotation: Float(rotate ?? 0) , opacity: opacity ?? 1, blendMode: .normal)
                multilayerFilter.layers.append(clayer1)
                //            completion()
                print(imageLayerDataArr)
            }
        }
        else{
            if imageLayerDataArr.count == 0{
                
            }
            else{
                
            }
            multilayerFilter.layers.removeAll()
        }
        
        
        
        
        
        let newImg = FilterGraph.makeImage(builder: { output in
            sourceImage => lookup.inputPorts.inputImage
            //                        lookup => blendFilter.inputBackgroundImage//output
            if let img = lookup.outputImage{
                if LocalStore.instance.mirrorFilter == "Left"{
                    defaultMirrorEffectImage = DemoImages.splitImageVersionLeftRight(processingImage: sourceImage)
                }
                else if LocalStore.instance.mirrorFilter == "Up"{
                    defaultMirrorEffectImage = DemoImages.splitImageVersionUpDown(processingImage: sourceImage)
                }
                else{
                    defaultMirrorEffectImage = img
                }
            }
            else{
                if LocalStore.instance.mirrorFilter == "Left"{
                    defaultMirrorEffectImage = DemoImages.splitImageVersionLeftRight(processingImage: sourceImage)
                }
                else if LocalStore.instance.mirrorFilter == "Up"{
                    defaultMirrorEffectImage = DemoImages.splitImageVersionUpDown(processingImage: sourceImage)
                }
                else{
                    defaultMirrorEffectImage = sourceImage
                }
            }
            
            if LocalStore.instance.heatMap{
                defaultHeatMapEffectImage = DemoImages.makeHeatmapEffect(processingImage: defaultMirrorEffectImage!)
            }
            else{
                defaultHeatMapEffectImage = defaultMirrorEffectImage
            }
            
            
            if let img = defaultHeatMapEffectImage{
                img => blendFilter.inputPorts.inputBackgroundImage
            }else{
                sourceImage => blendFilter.inputPorts.inputBackgroundImage
            }
            
            if let img = blendFilter.outputImage{
                defaultFocusEffectImage = DemoImages.makeFocusEffect(processingImage: img)
            }else{
                defaultFocusEffectImage = defaultHeatMapEffectImage
            }
            
            if let img = defaultFocusEffectImage{
                if LocalStore.instance.canvas{
                    defaultCropEffectImage = DemoImages.makeCropFilter(processingImage: img)
                }
                else{
                    defaultCropEffectImage = defaultFocusEffectImage
                }
            }else{
                defaultCropEffectImage = defaultFocusEffectImage
            }
            
            
            if let img = defaultCropEffectImage{
                img => multilayerFilter.inputPorts.inputBackgroundImage
            }else{
                sourceImage => multilayerFilter.inputPorts.inputBackgroundImage
            }
            
            multilayerFilter => output
            //AnyIOPort(sequence: []) => output
        })!
        return newImg //sourceImage
    })
    
    return composition
}

@mobileexpert1
Copy link
Author

MTIVideoComposition is fine because Video is playing fine on the player view as i want but during export it blinks.

@YuAo
Copy link
Member

YuAo commented Mar 28, 2023

It looks like you are reusing your filters (blendFilter, lookup, multilayerFilter) for both preview and export. So you need to make sure you've stopped the preview before exporting.

Creating filters are cheap operation, you can also try moving the filter creation part to the filter block, so they are not shared by different AVVideoCompositions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants