AVAssetExportSession,AVMutableComposition w/AudioMix淡出不起作用
问题描述:
我正在构建一个应用程序,它结合了几个视频,将它们合并为一个视频并将自定义音频记录放入视频中。这一切都完美无瑕。现在我想淡出我的音频。另一方面,这不起作用,我不知道为什么。 这是我的代码:AVAssetExportSession,AVMutableComposition w/AudioMix淡出不起作用
let duration = composition.duration
let durationInSeconds = CMTimeGetSeconds(duration) * 10
let composition = AVMutableComposition()
let item = AVPlayerItem(asset: composition)
let params = AVMutableAudioMixInputParameters(track: composition.tracks.first! as AVAssetTrack)
let lastSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(durationInSeconds-10, 10), CMTimeMakeWithSeconds(1, 1))
params.setVolumeRamp(fromStartVolume: 1, toEndVolume: 0, timeRange: lastSecond)
let mix = AVMutableAudioMix()
mix.inputParameters = [params]
item.audioMix = mix
// Put the track under the video
do {
try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, current), of: backgroundAudio.tracks(withMediaType: AVMediaTypeAudio)[0], at: kCMTimeZero)
} catch _ {
print("Failed to load Audio track")
}
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else { return }
exporter.audioMix = mix
exporter.outputURL = URL(fileURLWithPath: finalVideoPath)
exporter.outputFileType = AVFileTypeMPEG4
exporter.shouldOptimizeForNetworkUse = true
而且这个代码块后,继续至视频本身呈现的另一种方法。 有人可以解释为什么这不起作用,以及如何解决这个问题?
在此先感谢!
答
以下是添加视频和音频网址并设置音量的代码。您的结果视频将淡入淡出效果。
func mergeVideoAndMusicWithVolume(videoURL: NSURL, audioURL: NSURL, startAudioTime: Float64, volumeVideo: Float, volumeAudio: Float, complete: ((NSURL?)) -> Void) -> Void {
//The goal is merging a video and a music from iPod library, and set it a volume
//Get the path of App Document Directory
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir = dirPaths[0] as String
//Create Asset from record and music
let assetVideo: AVURLAsset = AVURLAsset(URL: videoURL)
let assetMusic: AVURLAsset = AVURLAsset(URL: audioURL)
let composition: AVMutableComposition = AVMutableComposition()
let compositionVideo : AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let compositionAudioVideo: AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
let compositionAudioMusic: AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
//Add video to the final record
do {
try compositionVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, assetVideo.duration), ofTrack:assetVideo.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: kCMTimeZero)
} catch _ {
}
//Extract audio from the video and the music
let audioMix: AVMutableAudioMix = AVMutableAudioMix()
var audioMixParam: [AVMutableAudioMixInputParameters] = []
let assetVideoTrack: AVAssetTrack = assetVideo.tracksWithMediaType(AVMediaTypeAudio)[0]
let assetMusicTrack: AVAssetTrack = assetMusic.tracksWithMediaType(AVMediaTypeAudio)[0]
let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack)
videoParam.trackID = compositionAudioVideo.trackID
let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack)
musicParam.trackID = compositionAudioMusic.trackID
//Set final volume of the audio record and the music
videoParam.setVolume(volumeVideo, atTime: kCMTimeZero)
musicParam.setVolume(volumeAudio, atTime: kCMTimeZero)
//Add setting
audioMixParam.append(musicParam)
audioMixParam.append(videoParam)
//Add audio on final record
//First: the audio of the record and Second: the music
do {
try compositionAudioVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, assetVideo.duration), ofTrack: assetVideoTrack, atTime: kCMTimeZero)
} catch _ {
assertionFailure()
}
do {
try compositionAudioMusic.insertTimeRange(CMTimeRangeMake(CMTimeMake(Int64(startAudioTime * 10000), 10000), assetVideo.duration), ofTrack: assetMusicTrack, atTime: kCMTimeZero)
} catch _ {
assertionFailure()
}
//Add parameter
audioMix.inputParameters = audioMixParam
//Remove the previous temp video if exist
let filemgr = NSFileManager.defaultManager()
do {
if filemgr.fileExistsAtPath("\(docsDir)"){
try filemgr.removeItemAtPath("\(docsDir)/movie-merge-music.mp4")
} else {
}
} catch _ {
}
//Exporte the final record’
let completeMovie = "\(docsDir)/\(randomString(5)).mp4"
let completeMovieUrl = NSURL(fileURLWithPath: completeMovie)
let exporter: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)!
exporter.outputURL = completeMovieUrl
exporter.outputFileType = AVFileTypeMPEG4
exporter.audioMix = audioMix
exporter.exportAsynchronouslyWithCompletionHandler({
switch exporter.status {
case AVAssetExportSessionStatus.Completed:
print("success with output url \(completeMovieUrl)")
case AVAssetExportSessionStatus.Failed:
print("failed \(String(exporter.error))")
case AVAssetExportSessionStatus.Cancelled:
print("cancelled \(String(exporter.error))")
default:
print("complete")
}
})
}