Визуализация аудио файла в автономном режиме с помощью AVAudioEngine - PullRequest
0 голосов
/ 05 сентября 2018

Я хочу записать аудио файл и сохранить его, применив некоторые эффекты. Запись в порядке, а также воспроизведение этого аудио с эффектом тоже хорошо. Проблема в том, что когда я пытаюсь сохранить такой звук в автономном режиме, он создает пустой аудиофайл. Вот мой код:

let effect = AVAudioUnitTimePitch()
effect.pitch = -300
self.addSomeEffect(effect)

func addSomeEffect(_ effect: AVAudioUnit) {
    try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)

    let format = self.audioFile.processingFormat
    self.audioEngine.stop()
    self.audioEngine.reset()

    self.audioEngine = AVAudioEngine()
    let audioPlayerNode = AVAudioPlayerNode()


    self.audioEngine.attach(audioPlayerNode)
    self.audioEngine.attach(effect)

    self.audioEngine.connect(audioPlayerNode, to: self.audioEngine.mainMixerNode, format: format)
    self.audioEngine.connect(effect, to: self.audioEngine.mainMixerNode, format: format)

    audioPlayerNode.scheduleFile(self.audioFile, at: nil)
    do {
        let maxNumberOfFrames: AVAudioFrameCount = 8096
        try self.audioEngine.enableManualRenderingMode(.offline,
                                                       format: format,
                                                       maximumFrameCount: maxNumberOfFrames)
    } catch {
        fatalError()
    }


    do {
        try audioEngine.start()
        audioPlayerNode.play()
    } catch {

    }

    let outputFile: AVAudioFile
    do {
        let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("temp.m4a")
        if FileManager.default.fileExists(atPath: url.path) {
            try? FileManager.default.removeItem(at: url)
        }

        let recordSettings = self.audioFile.fileFormat.settings

        outputFile = try AVAudioFile(forWriting: url, settings: recordSettings)
    } catch {
        fatalError()
    }

    let buffer = AVAudioPCMBuffer(pcmFormat: self.audioEngine.manualRenderingFormat,
                                  frameCapacity: self.audioEngine.manualRenderingMaximumFrameCount)!

    while self.audioEngine.manualRenderingSampleTime < self.audioFile.length {
        do {
            let framesToRender = min(buffer.frameCapacity,
                                     AVAudioFrameCount(self.audioFile.length - self.audioEngine.manualRenderingSampleTime))
            let status = try self.audioEngine.renderOffline(framesToRender, to: buffer)
            switch status {
            case .success:
                print("Write to file")
                try outputFile.write(from: buffer)
            case .error:
                fatalError()
            default:
                break
            }
        } catch {
            fatalError()
        }
    }
    print("Finish write")


    audioPlayerNode.stop()
    audioEngine.stop()


    self.outputFile = outputFile
    self.audioPlayer = try? AVAudioPlayer(contentsOf: outputFile.url)

}

AVAudioPlayer не удается открыть файл с выходным URL. Я посмотрел на файл через файловую систему, и он пуст и не может быть воспроизведен.

Выбор разных категорий для AVAudioSession тоже не работает.

Спасибо за помощь!

UPDATE

Я перешел на использование расширения файла .caf в своей записи в выходном файле, и это сработало. Есть идеи, почему .m4a не работает?

1 Ответ

0 голосов
/ 19 сентября 2018

Вам нужно nil outputFile, чтобы очистить заголовок и закрыть файл m4a.

...