首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVMutableAudioMixInputParameters: setVolume()不能处理音频文件iOS 9

AVMutableAudioMixInputParameters: setVolume()不能处理音频文件iOS 9
EN

Stack Overflow用户
提问于 2015-10-26 13:41:27
回答 1查看 1.8K关注 0票数 2

我尝试将视频记录与设备的iPod库中的音频文件混在一起。

我想设置每个音频的音量(视频和音频文件的音频)。

我尝试将AVMutableAudioMixInputParameters对象与setVolume()方法结合使用。

我对视频的音量没有任何问题,但是最终记录上的音频文件的音量总是设置为最大值。我试图更改音频文件,以便使用视频进行测试,并且只使用此视频的音频轨道,这很好。

代码语言:javascript
复制
import UIKit
import AVFoundation

class AVTools: NSObject {

    /**
    volume: between 1.0 and 0.0
    */
    class 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 = assetVideoTrack.trackID

        let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack)
        musicParam.trackID = assetMusicTrack.trackID

        //Set final volume of the audio record and the music
        videoParam.setVolume(volumeVideo, atTime: kCMTimeZero)
        musicParam.setVolume(volumeAudio, atTime: kCMTimeZero) // <----- This doesn't work on audio file

        //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)/movie-merge-music.mov") {
                try filemgr.removeItemAtPath("\(docsDir)/movie-merge-music.mov")
            } else {
            }
        } catch _ {
        }

        //Exporte the final record’
        let completeMovie = "\(docsDir)/movie-merge-music.mov"
        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.Failed:
                print("failed \(exporter.error)")
                complete(nil)
            case AVAssetExportSessionStatus.Cancelled:
                print("cancelled \(exporter.error)")
                complete(nil)
            default:
                print("complete")
                complete(completeMovieUrl)
            }
        })
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-18 12:07:12

好的,我已经找到问题了。问题是,我分配的是资产的trackID,而不是组合的trackID。要修复它,只需替换:

代码语言:javascript
复制
       let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack)
    videoParam.trackID = assetVideoTrack.trackID

    let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack)
    musicParam.trackID = assetMusicTrack.trackID

至:

代码语言:javascript
复制
        let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack)
    videoParam.trackID = compositionAudioVideo.trackID

    let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack)
    musicParam.trackID = compositionAudioMusic.trackID

最终结果:

代码语言:javascript
复制
    /**
 volume: between 1.0 and 0.0
 */
class 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)/movie-merge-music.mov") {
            try filemgr.removeItemAtPath("\(docsDir)/movie-merge-music.mov")
        } else {
        }
    } catch _ {
    }

    //Exporte the final record’
    let completeMovie = "\(docsDir)/movie-merge-music.mov"
    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.Failed:
            print("failed \(exporter.error)")
            complete(nil)
        case AVAssetExportSessionStatus.Cancelled:
            print("cancelled \(exporter.error)")
            complete(nil)
        default:
            print("complete")
            complete(completeMovieUrl)
        }
    })
}
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33347256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档