Търсих решение за това, но досега не можах да го намеря.
В момента създавам аудио файл с 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)
}