2017-10-10 57 views
0

我正在构建一个应用程序,它结合了几个视频,将它们合并为一个视频并将自定义音频记录放入视频中。这一切都完美无瑕。现在我想淡出我的音频。另一方面,这不起作用,我不知道为什么。 这是我的代码: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 

而且这个代码块后,继续至视频本身呈现的另一种方法。 有人可以解释为什么这不起作用,以及如何解决这个问题?

在此先感谢!

回答

0

以下是添加视频和音频网址并设置音量的代码。您的结果视频将淡入淡出效果。

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