美文网首页
ios AVFoundation框架给视频添加背景音乐的方法

ios AVFoundation框架给视频添加背景音乐的方法

作者: 刘乔泓 | 来源:发表于2021-01-03 10:50 被阅读0次
    /// 视频添加背景音乐
        /// - Parameters:
        ///   - videoURL: 视频文件URL
        ///   - audioURL: 音频文件URL
        ///   - startTime: 音频开始时间
        ///   - endTime: 音频结束时间
        ///   - isOriginal: 是否保留视频原音
        ///   - oriVolume: 视频原音音量
        ///   - newVolume: 新增背景音乐音量
        ///   - outputURL: 视频输出文件地址
        ///   - completion: 完成回掉
        static func addBackgroundMusic(videoURL : URL, audioURL : URL, startTime : Double, endTime : Double, isOriginal : Bool = true, oriVolume : Float, newVolume : Float, outputURL : String, completion : @escaping (_ success : Bool) -> Void) {
            
            if FileManager.default.fileExists(atPath: outputURL) {
                do {
                    try FileManager.default.removeItem(atPath: outputURL)
                } catch {
                    logger(item: "addBackgroundMusic remove exit file error")
                }
            }
            
            do {
                //导出路径
                let outputFileURL = URL.init(fileURLWithPath: outputURL)
                
                let nextClipStartTime = CMTime.zero
                
                //创建可变的音频视频组合
                let mixComposition = AVMutableComposition()
                
                //视频采集
                let videoAsset = AVURLAsset.init(url: videoURL)
                let videoTimeRange = CMTimeRange.init(start: .zero, duration: videoAsset.duration)
                let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
                if compositionVideoTrack == nil {
                    completion(false)
                    return
                }
                try compositionVideoTrack!.insertTimeRange(videoTimeRange, of: videoAsset.tracks(withMediaType: .video).first!, at: nextClipStartTime)
                
                let start = CMTime.init(seconds: startTime, preferredTimescale: videoAsset.duration.timescale)
                let duration = CMTime.init(seconds: endTime - startTime, preferredTimescale: videoAsset.duration.timescale)
                let audioTimeRange = CMTimeRange.init(start: start, duration: duration)
                
                //创建最终混合的音频实例
                let audioMix = AVMutableAudioMix()
                
                //添加新的音频
                let audioAsset = AVURLAsset.init(url: audioURL)
                let newAudioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
                if compositionVideoTrack == nil {
                    completion(false)
                    return
                }
                try newAudioTrack!.insertTimeRange(audioTimeRange, of: audioAsset.tracks(withMediaType: .audio).first!, at: start)
                let newAudioInputParams = AVMutableAudioMixInputParameters.init(track: newAudioTrack!)
                newAudioInputParams.setVolumeRamp(fromStartVolume: newVolume, toEndVolume: 0.0, timeRange: CMTimeRange.init(start: .zero, duration: videoAsset.duration))
                newAudioInputParams.trackID = newAudioTrack!.trackID
                
                //视频文件原始音频通道
                if isOriginal {
                    //视频声音采集(也可不执行这段代码不采集视频音轨,合并后的视频文件将没有视频)
                    if videoAsset.tracks(withMediaType: .audio).first != nil {
                        if let originVoiceTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
                            try originVoiceTrack.insertTimeRange(videoTimeRange, of:videoAsset.tracks(withMediaType: .audio).first!, at: .zero)
                            let originAudioInputParams = AVMutableAudioMixInputParameters.init(track: originVoiceTrack)
                            originAudioInputParams.setVolumeRamp(fromStartVolume: newVolume, toEndVolume: 0.0, timeRange: CMTimeRange.init(start: .zero, duration: videoAsset.duration))
                            originAudioInputParams.trackID = originVoiceTrack.trackID
                            audioMix.inputParameters = [newAudioInputParams,originAudioInputParams]
                        } else {
                            audioMix.inputParameters = [newAudioInputParams]
                        }
                    } else {
                        audioMix.inputParameters = [newAudioInputParams]
                    }
                } else {
                    audioMix.inputParameters = [newAudioInputParams]
                }
                
                //创建一个输出
                let assetExport = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
                if assetExport == nil {
                    completion(false)
                    return
                }
                assetExport!.outputFileType = .mp4
                assetExport!.outputURL = outputFileURL
                assetExport!.shouldOptimizeForNetworkUse = true
                assetExport!.audioMix = audioMix
                
                assetExport!.exportAsynchronously {
                    switch assetExport!.status {
                    case .unknown:
                        break
                    case .waiting:
                        break
                    case .exporting:
                        break
                    case .completed:
                        completion(true)
                        break
                    case .failed:
                        //合成失败
                        completion(false)
                        break
                    case .cancelled:
                        completion(false)
                        break
                    @unknown default:
                        break
                    }
                }
            } catch {
                completion(false)
            }
        }
        
    

    相关文章

      网友评论

          本文标题:ios AVFoundation框架给视频添加背景音乐的方法

          本文链接:https://www.haomeiwen.com/subject/blgqgktx.html