Я искал решение для этого, но пока не нашел.
Прямо сейчас я создаю аудиофайл с помощью 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)
}