AudioKit renderToFile не работает

Я пытаюсь загрузить песню, смешать ее с фильтрами и сохранить в файл. Однако мне не удается заставить его работать с AudioKit.renderToFile. Я всегда получаю сообщение «нет такого файла» после рендеринга.

Мой код очень похож на этот.

if let fileUrl = Bundle.main.path(forResource: "song", ofType: "wav") {
    export()
}

Рендеринг:

func export(songUrl: String) {
    do {
        if let url = URL(string: songUrl) {
            if let file = try? AKAudioFile(forReading: url) {
                player = try AKAudioPlayer(file: file)
            }
        }
    } catch {
        fatalError("PLAYER URL ERROR")
    }

    mainMixer = AKMixer(player)
    AudioKit.output = mainMixer

    do {
        try AudioKit.start()
        self.outputFile = try AVAudioFile(forWriting: exportURL, settings: player.audioFile.fileFormat.settings)
        try AudioKit.renderToFile(self.outputFile, duration: self.player.duration, prerender: {
            self.player.play()
        })
    } catch {
        fatalError("Unexpected error: \(error).")
    }

    self.showFileSize()
}

URL-адрес экспорта:

let exportURL: URL = {
    let documentsURL = FileManager.default.temporaryDirectory
    return documentsURL.appendingPathComponent("exported_song.wav")
}()

showFileSize использует FileManager.default.attributesOfItem (atPath: filePath), но здесь выдает исключение:

The file “exported_song.wav” couldn’t be opened because there is no such file.

Что я здесь делаю не так? Заранее спасибо!


person Dev_IL    schedule 04.07.2018    source источник
comment
Я запустил образец проекта, который этот программист так любезно создал для меня для тестирования, и могу сказать, что файл определенно создается. Почему iOS не видит, что это может быть связано с песочницей?   -  person Aurelius Prochazka    schedule 06.08.2018
comment
@AureliusProchazka Вы правы - проблема в чтении. Я внес 2 изменения в тестовый проект: 1) Я проверяю файл с помощью FileManager.default.fileExists(atPath: url) 2) Я загружаю данные let data = try Data(contentsOf: URL(fileURLWithPath: url)) 3) Я пытаюсь воспроизвести audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: url)). 1) и 2) работает нормально, поэтому файл создается, но AVAudio не может его загрузить. Я также пробовал init с AVAudio (данные), но он также выдает ошибку. Я даже добавил возможность поделиться файлом данных - и когда я открыл его и перезапустил на Mac - звук хороший (со всеми эффектами).   -  person Dev_IL    schedule 06.08.2018
comment
@AureliusProchazka Я думаю, что с renderToFile тоже может что-то не так. Я напечатал AudioFile.fileFormat из ресурсов: <AVAudioFormat 0x6000000991e0: 2 ch, 44100 Hz, 'alac' (0x00000003) from 24-bit source, 4096 frames/packet> Но из документов после рендеринга это выглядит так: <AVAudioFormat 0x604000097890: 2 ch, 44100 Hz, 'alac' (0x00000000) from UNKNOWN source bit depth, 0 frames/packet> исходный бит НЕИЗВЕСТНО, а количество кадров в пакете 0. Вы знаете, в чем может быть проблема?   -  person Dev_IL    schedule 07.08.2018
comment
@AureliusProchazka Мне наконец удалось заставить его работать, но это не очень тривиально. Что я сделал (случайно), так это дважды создал выходной файл и renderToFile. Я обновил тестовый проект, так что вы можете его протестировать. В SongPlayer - ›метод экспорта. Обычно создание AVAudioPlayer или любой другой подход к созданию аудиофайла / ресурса не удался. Теперь, после второго рендеринга, он работает ... Что может быть интересно - я печатаю размер файла и вижу, что после первого рендеринга он (в байтах): 13857770, но после второго: 13857778. Таким образом, эти дополнительные 8 байтов должны выполнять свою работу. .   -  person Dev_IL    schedule 19.08.2018
comment
@AureliusProchazka Если бы вы могли проанализировать его и высказать свои мысли, мы сможем создать образец проекта и, возможно, добавить его в свои документы, поскольку он отсутствует.   -  person Dev_IL    schedule 19.08.2018
comment
@AureliusProchazka Ты хоть представляешь, почему это нужно делать дважды? gist.github.com/Ufosek/0631189e41663cf11585fb732353cc53   -  person Dev_IL    schedule 19.11.2018
comment
Нет, я не знаю, почему это работает во второй раз, возможно, есть состояние гонки, когда первый процесс задерживает успешный второй процесс.   -  person Aurelius Prochazka    schedule 23.11.2018


Ответы (1)


Вот что помогло мне написать выходной файл * .wav (заканчивается в Documents / out.wav):

private func testRecord() {
    let testOscillator = AKOscillator()
    AudioKit.output = testOscillator

    // write to file
    do {
        try AudioKit.start()

        print("home: \(NSHomeDirectory())")

        guard let outURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("out.wav") else {
            fatalError("Failed URL create")
        }

        guard let format = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 44100, channels: 2, interleaved: true) else {
            fatalError("Failed to create format")
        }

        let file = try AKAudioFile(forWriting: outURL, settings: format.settings)

        try AudioKit.renderToFile(file, duration: 10.0, prerender: {
            testOscillator.start()
        })
    } catch {
        print("renderToFile error: \(error)")
    }
    print("didn't crash")
}
person Doug Voss    schedule 26.08.2019