Как добавить эффект Fade In и Fade Out для Video AVAsset в Swift3 iOS

Я разрабатываю приложение Video в Swift3. Где я должен преобразовать любой текст в Video, а затем добавить эффект Fade In and Fade Out и отправить Fade effect Video на сервер. Мне не нужно использовать Third Party Library для Fade effect.

Я могу преобразовать свой Text в Video. Моя проблема в том, как добавить Fade In and Fade Out к Video AVAsset.

Может ли кто-нибудь предложить мне достичь этого. Я не могу найти какие-либо недавние ответы на эту проблему. Спасибо за любую помощь!


person user2786    schedule 03.07.2018    source источник


Ответы (2)


Эффект исчезновения

let parentLayer = CALayer()
let fadeOut = CABasicAnimation(keyPath: "opacity")
fadeOut.fromValue = 1.0
fadeOut.toValue = 0.0
fadeOut.duration = 5.0//This will video duration
fadeOut.setValue("video", forKey:"fadeOut")
fadeOut.isRemovedOnCompletion = false
fadeOut.fillMode = CAMediaTimingFillMode.forwards
parentLayer.add(fadeOut, forKey: "opacity")

Эффект затухания

fadeIn.fromValue = 0.0
fadeIn.toValue = 1.0

Добавить в свой проигрыватель

self.playerView?.playerLayer?.add(fadeOut, forKey: nil)

Добавить в свои активы

var startTime = CMTime.zero
var timeDuration = CMTimeMake(value: 3, timescale: 1)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

//MARK: Fade in effect
layerInstruction.setOpacityRamp(fromStartOpacity: 0.0, toEndOpacity: 1.0, timeRange: CMTimeRange(start: startTime, duration: timeDuration))

//MARK: Fade out effect
        startTime = CMTimeSubtract(mutableComposition.duration, CMTimeMake(value: 3, timescale: 1))
        timeDuration = CMTimeMake(value: 3, timescale: 1)
        layerInstruction.setOpacityRamp(
            fromStartOpacity: 1.0,
            toEndOpacity: 0.0,
            timeRange: CMTimeRangeMake(start: startTime, duration: timeDuration)
        )
person kalpesh    schedule 28.11.2018

Инструкция AVVideoCompositionLayerInstruction

Массив экземпляров AVVideoCompositionLayerInstruction, указывающих, как видеокадры из исходных дорожек должны располагаться слоями и компоноваться.

Инструкция AVMutableVideoCompositionInstruction

Объект AVVideoComposition поддерживает массив instructions для выполнения своей композиции.

Пример Swift4: я объединил видео с эффектами fade-in и fade-out и изменил последовательность аудио

func doMerge(arrayVideos:[AVAsset], arrayAudios:[AVAsset], animation:Bool, completion:@escaping Completion) -> Void {

    var insertTime = kCMTimeZero
    var audioInsertTime = kCMTimeZero
    var arrayLayerInstructions:[AVMutableVideoCompositionLayerInstruction] = []
    var outputSize = CGSize.init(width: 0, height: 0)

    // Determine video output size
    for videoAsset in arrayVideos {
        let videoTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]
        let assetInfo = orientationFromTransform(transform: videoTrack.preferredTransform)
        var videoSize = videoTrack.naturalSize
        if assetInfo.isPortrait == true {
            videoSize.width = videoTrack.naturalSize.height
            videoSize.height = videoTrack.naturalSize.width
        }
        outputSize = videoSize
    }

    // Init composition
    let mixComposition = AVMutableComposition.init()

    for index in 0..<arrayVideos.count {
        // Get video track
        guard let videoTrack = arrayVideos[index].tracks(withMediaType: AVMediaType.video).first else { continue }

        // Get audio track
        var audioTrack:AVAssetTrack?
        if index < arrayAudios.count {
            if arrayAudios[index].tracks(withMediaType: AVMediaType.audio).count > 0 {
                audioTrack = arrayAudios[index].tracks(withMediaType: AVMediaType.audio).first
            }
        }
        // Init video & audio composition track
        let videoCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

        let audioCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

        do {
            let startTime = kCMTimeZero
            let duration = arrayVideos[index].duration

            // Add video track to video composition at specific time
            try videoCompositionTrack?.insertTimeRange(CMTimeRangeMake(startTime, duration), of: videoTrack, at: insertTime)

            // Add audio track to audio composition at specific time
            var audioDuration = kCMTimeZero
            if index < arrayAudios.count   {
                 audioDuration = arrayAudios[index].duration
            }

            if let audioTrack = audioTrack {
                do {
                    try audioCompositionTrack?.insertTimeRange(CMTimeRangeMake(startTime, audioDuration), of: audioTrack, at: audioInsertTime)
                }
                catch {
                    print(error.localizedDescription)
                }
            }

            // Add instruction for video track
            let layerInstruction = videoCompositionInstructionForTrack(track: videoCompositionTrack!, asset: arrayVideos[index], standardSize: outputSize, atTime: insertTime)

            // Hide video track before changing to new track
            let endTime = CMTimeAdd(insertTime, duration)

            if animation {
                let timeScale = arrayVideos[index].duration.timescale
                let durationAnimation = CMTime.init(seconds: 1, preferredTimescale: timeScale)

                layerInstruction.setOpacityRamp (fromStartOpacity: 1.0, toEndOpacity: 0.0, timeRange: CMTimeRange.init(start: endTime, duration: durationAnimation))
            }
            else {
                layerInstruction.setOpacity(0, at: endTime)
            }

            arrayLayerInstructions.append(layerInstruction)

            // Increase the insert time
            audioInsertTime = CMTimeAdd(audioInsertTime, audioDuration)
            insertTime = CMTimeAdd(insertTime, duration)
        }
        catch {
            print("Load track error")
        }
    }

    // Main video composition instruction
    let mainInstruction = AVMutableVideoCompositionInstruction()
    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, insertTime)
    mainInstruction.layerInstructions = arrayLayerInstructions

    // Main video composition
    let mainComposition = AVMutableVideoComposition()
    mainComposition.instructions = [mainInstruction]
    mainComposition.frameDuration = CMTimeMake(1, 30)
    mainComposition.renderSize = outputSize

    // Export to file
    let path = NSTemporaryDirectory().appending("mergedVideo.mp4")
    let exportURL = URL.init(fileURLWithPath: path)

    // Remove file if existed
    FileManager.default.removeItemIfExisted(exportURL)

    // Init exporter
    let exporter = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
    exporter?.outputURL = exportURL
    exporter?.outputFileType = AVFileType.mp4
    exporter?.shouldOptimizeForNetworkUse = true
    exporter?.videoComposition = mainComposition

    // Do export
    exporter?.exportAsynchronously(completionHandler: {
        DispatchQueue.main.async {
            self.exportDidFinish(exporter: exporter, videoURL: exportURL, completion: completion)
        }
    })

}
person Harshal Valanda    schedule 03.07.2018
comment
Спасибо за ваш добрый ответ. Как я вижу в вашем коде, вы добавляете эффект Fade для каждого видео. правильный? Также мне нужно уточнить у вас, например, вы также получаете аудио звук видео отдельно в Final Video? - person user2786; 03.07.2018
comment
Да, я объединил более 5 видео с приведенным выше кодом с анимацией постепенного исчезновения. - person Harshal Valanda; 03.07.2018
comment
Я получаю сообщение об ошибке при использовании вышеуказанного метода. У вас есть пример приложения, использующего вышеуказанный метод? - person user2786; 03.07.2018
comment
Какую быструю версию вы используете? - person Harshal Valanda; 03.07.2018
comment
Быстрая версия: 3.0 - person user2786; 03.07.2018
comment
Если возможно, пришлите мне образец, чтобы я мог просмотреть окончательный предварительный просмотр видео и сравнить его с моим требованием. - person user2786; 03.07.2018
comment
Давайте продолжим обсуждение в чате. - person Harshal Valanda; 03.07.2018
comment
Можете ли вы изучить этот заголовок @Harshal: stackoverflow.com/questions/51419495/ Спасибо. - person Anand Gautam; 19.07.2018