首页 文章

从AVMutableComposition到AVAudioPlayer的iOS音频转换

提问于
浏览
0

我一直在寻找解决方案,但到目前为止我找不到它 .

现在我正在使用AVMutableComposition创建一个音频文件并使用AVAssetExportSession将其写入磁盘,这样我就可以使用AVAudioPlayer加载它并在特定时间播放它 . 将它写入磁盘需要花费很多时间的事实会减慢速度,在某些情况下会使我的应用程序变得非常慢 .

音频的创建部分花费很少的时间,所以我想知道是否将文件导出到磁盘我可以像NSData一样导出它,所以我可以在AVAudioPlayer中使用它而无需从磁盘写入/读取


代码让soundPath =“temp”让filepath = NSURL(fileURLWithPath:NSBundle.mainBundle() . pathForResource(soundPath,ofType:“wav”)!)

var songAsset = AVURLAsset(URL: filepath, options: nil)

    var track = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
    var source: AnyObject = songAsset.tracksWithMediaType(AVMediaTypeAudio)[0]

    var startTime = CMTimeMakeWithSeconds(0, 44100)
    var time_insert = CMTimeMakeWithSeconds(atTime, 44100)
    var trackDuration = songAsset.duration
    var longestTime = CMTimeMake(882000, 44100)
    var timeRange = CMTimeRangeMake(startTime, longestTime)

    var trackMix = AVMutableAudioMixInputParameters(track: track)
    trackMix.setVolume(volume, atTime: startTime)
    audioMixParams.insert(trackMix, atIndex: audioMixParams.count)

    track.insertTimeRange(timeRange, ofTrack: source as AVAssetTrack, atTime: time_insert, error: nil)

这在发生整个轨道的循环中发生了几次

最后我用

var exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
    exporter.audioMix = audioMix
    exporter.outputFileType = "com.apple.m4a-audio"
    exporter.outputURL = NSURL(fileURLWithPath: fileName)

    exporter.exportAsynchronouslyWithCompletionHandler({
        switch exporter.status{
        case  AVAssetExportSessionStatus.Failed:
            println("failed \(exporter.error)")
        case AVAssetExportSessionStatus.Cancelled:
            println("cancelled \(exporter.error)")
        default:
            println("complete")
            callback()
        }
    })

导出文件 .

然后它调用一个回调加载声音并在一段时间内循环它 .

我没有使用普通循环属性循环的事实是每个文件可能与loopDuration的长度不同

callback: {

        self.fillSoundArray()
        self.fillSoundArray()
        self.fillSoundArray()
    }


private func fillSoundArray() {
    var currentloop = self.current_loop++

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    var fileName = documentsPath + "/temp.mp4"

    var tempAudio = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: fileName), error: nil)
    if (self.start_time == 0) {
        self.start_time = tempAudio.deviceCurrentTime
    }

    queue.insert(tempAudio, atIndex: queue.count)
    tempAudio.prepareToPlay()
    tempAudio.delegate = self
    tempAudio.playAtTime(start_time + currentloop*self.loopDuration)
}

1 回答

  • 1

    使用AVPlayerItem和AVPlayer快速预览您的音频构成

    AVPlayerItem*  previewPlayerItem = [[AVPlayerItem alloc] initWithAsset:mutableCompositionMain 
                                              automaticallyLoadedAssetKeys:@[@"tracks",@"duration"]];
    previewPlayerItem.videoComposition = mutableVideoComposition;
    AVPlayer* previewPlayer = [[AVPlayer alloc] initWithPlayerItem:previewPlayerItem ];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(dismisPreviewPlayer:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[previewPlayer currentItem]];
    

相关问题