123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- //
- // VideoComposer.swift
- // dubbing_lib
- //
- // Created by weihong huang on 2020/9/18.
- //
- import Foundation
- import AVFoundation
- class VideoComposer {
- var videoUrl: URL
- var musicUrl: URL
-
- init(videoUrl: URL, musicUrl: URL){
- self.videoUrl = videoUrl
- self.musicUrl = musicUrl
- }
-
- func compose(_ output: URL, onSuccess successBlock: (()->())?, onFail failBlock:((_ message: String)->())? ) {
-
- //初始化合成器
- let composition = AVMutableComposition()
-
- var videoTimeRange:CMTimeRange?
-
- //为合成器添加视频轨道
- let videoTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
- let videoAsset = AVURLAsset(url: videoUrl, options: nil)
- videoTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration)
- do {
- try videoTrack?.insertTimeRange(videoTimeRange!, of: videoAsset.tracks(withMediaType: AVMediaType.video).first!, at: CMTime.zero)
- }
- catch {
- DispatchQueue.main.async(execute: {
- failBlock?("Fail on load video")
- })
- return
- }
-
-
- //添加音乐轨道
- let musicTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
- let musicAsset = AVURLAsset(url: musicUrl, options: nil)
- let musicTimeRange = videoTimeRange ?? CMTimeRangeMake(start: CMTime.zero, duration: musicAsset.duration)
- do {
- try musicTrack?.insertTimeRange(musicTimeRange, of: musicAsset.tracks(withMediaType: AVMediaType.audio).first!, at: CMTime.zero)
- print("创建音乐音轨成功")
- }
- catch {
- print("创建音乐音轨失败")
- }
-
- let manager = FileManager.default
- do {
- try manager.removeItem(at: output)
- print("删除旧输出成功")
- }
- catch {
- print("删除旧输出失败")
- }
-
- //输出到文件
- if let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) {
- assetExport.outputFileType = AVFileType.mp4
- assetExport.outputURL = output
- assetExport.shouldOptimizeForNetworkUse = true
- assetExport.exportAsynchronously(completionHandler: {
- if((assetExport.error) != nil){
- print(assetExport.error!)
- DispatchQueue.main.async(execute: {
- failBlock?("Something wrong on composition")
- })
- }else{
- successBlock?()
- }
- return
- })
- }
- else {
- DispatchQueue.main.async(execute: {
- failBlock?("Something wrong on composition")
- })
- }
- }
- }
|