Преобразование аудио iOS из AVMutableComposition в AVAudioPlayer

Я искал решение для этого, но пока не нашел.

Прямо сейчас я создаю аудиофайл с помощью AVMutableComposition и записываю его на диск с помощью AVAssetExportSession, чтобы я мог загрузить его с помощью AVAudioPlayer и воспроизвести его в определенное время. Тот факт, что запись на диск занимает много времени, замедляет работу, а в некоторых случаях делает мое приложение очень медленным.

Создание части звука занимает очень мало времени, поэтому мне было интересно, если я могу экспортировать файл на диск, я могу просто экспортировать его как NSData или что-то в этом роде, чтобы я мог использовать его в AVAudioPlayer без записи / чтения с диска


код let soundPath = "temp" let 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)
}

person Francis Reynolds    schedule 16.11.2014    source источник


Ответы (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]];
person DimaC    schedule 17.11.2014
comment
Спасибо за ваш ответ, моя проблема заключается не в воспроизведении звука, а в том, что после этого я должен воспроизвести его в виде временного цикла (длина звука может отличаться от длины цикла) Вот почему я хотел использовать AVAudioPlayer - person Francis Reynolds; 17.11.2014
comment
Я добавил код, надеюсь, он не усложнит понимание. - person Francis Reynolds; 18.11.2014