简体   繁体   English

AVAssetExportSession,AVMutableComposition w / AudioMix淡出不起作用

[英]AVAssetExportSession, AVMutableComposition w/ AudioMix fade out not working

I'm building a app that combines a couple of videos, merges them into one and puts a custom audiotrack in the video. 我正在构建一个结合了几个视频的应用程序,将它们合并为一个并在视频中放置一个自定义的录音带。 This all works flawlessly. 这一切都完美无瑕。 Now I want to fade out my audio. 现在我想淡出我的音频。 This on the other hand, does not work, and I have no idea why. 另一方面,这不起作用,我不知道为什么。 This is my code: 这是我的代码:

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

And after this block of code it continues to another method where the video itself is rendered. 在这段代码之后,它继续到另一种呈现视频本身的方法。 Could someone explain me why this does not work and how to fix this? 有人可以解释一下为什么这不起作用以及如何解决这个问题?

Thanks in advance! 提前致谢!

Here is a code for add Video and audio url and set volume of both. 这是一个用于添加视频和音频网址以及设置两者音量的代码。 Your result video will be fade in and fade out effect. 您的结果视频将淡入淡出效果。

 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")
        }            
    })
}

It's a bit unclear where your "audioTrack" comes from in the code snippet, but make sure you're getting the right composition track for the 你的“audioTrack”在代码片段中的来源有点不清楚,但请确保你获得正确的合成曲目

AVMutableAudioMixInputParameters

eg 例如

let compositionAudioTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
let params = AVMutableAudioMixInputParameters(track: compositionAudioTrack)

It may just be that 可能就是这样

composition.tracks.first!

is referencing one of your video tracks 正在引用您的一个视频曲目

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM