Могу ли я получить AudioKit appendAsynchronously для создания файла с именем, отличным от ‘.caf’, и для вывода в формате .mp4?

#audiokit

#audiokit

Вопрос:

У меня есть следующий сценарий использования AudioKit под iOS:

  1. Я записываю звук с микрофона.
  2. Я сохраняю звук асинхронно в каталог tmp в виде файла .mp4.
  3. Я записываю второй звук с микрофона.
  4. Я пытаюсь (а) извлечь ранее сохраненный файл .mp4 и (б) асинхронно добавить к нему звук второго микрофона.

Моя проблема в том, что, хотя этот процесс выполняется успешно, добавленный файл сохраняется с именем файла ‘.caf’ (буквально только так, без указания расширения).

В идеале, я хотел бы каким-то образом придать добавляемому файлу более управляемое имя. Также было бы неплохо, если бы добавляемый файл мог быть в формате .mp4.

Для воспроизведения проблемы достаточно следующего кода:

импорт SwiftUI импорт AudioKit

struct contentView: Просмотр {

 @State private var mic: AKMicrophone!
@State private var micBooster: AKBooster!
@State private var micRecorder: AKNodeRecorder! 

var body: some View {
    Button(action: {
        self.recordFirstSound()
    }) {
        Text("Start")
    }
}


func recordFirstSound() {
    
    AKAudioFile.cleanTempDirectory()
    AKSettings.audioInputEnabled = true
    AKSettings.defaultToSpeaker = true
    do {
        try AKSettings.setSession(category: .multiRoute)
    } catch {
        print("Failed to set session category to .playAndRecord");
    }
    AKSettings.bufferLength = .medium
    mic = AKMicrophone()
    micBooster = AKBooster()
    mic >>> micBooster
    micBooster.gain = 0.0
    
    do {
        micRecorder = try AKNodeRecorder(node: mic)
    } catch {
        print("Failed to initialise micRecorder")
    }
    
    AudioKit.output = micBooster
    do {
        try AudioKit.start()
    } catch {
        print("Failed to start AudioKit")
    }
    
    do {
        try micRecorder.record()
    } catch {
        print("Failed to start micRecorder")
    }
    
    DispatchQueue.main.asyncAfter(deadline: .now()   5 , execute: {
        self.writeRecordingToTmpDir()
    })
}

func writeRecordingToTmpDir() {
    
    micRecorder.stop()
    if let recorderAudioFile = micRecorder.audioFile {
        recorderAudioFile.exportAsynchronously(name: "recording",
                                               baseDir: .temp,
                                               exportFormat: .mp4, callback: callbackAfterInitialExport)
    } else {
        print("Problem accessing micRecorder audioFile")
    }
    
    DispatchQueue.main.asyncAfter(deadline: .now()   5 , execute: {
        self.recordSecondSound()
    })
}

func recordSecondSound() {
    do {
        try micRecorder.reset()
    } catch {
        print("Failed to reset micRecorder")
    }

    do {
        try micRecorder.record()
    } catch {
        print("Failed to re-start micRecorder")
    }
    
    DispatchQueue.main.asyncAfter(deadline: .now()   5 , execute: {
        self.appendSecondSoundFileToFirstAsynchronously()
    })
}


func appendSecondSoundFileToFirstAsynchronously() {
    micRecorder.stop()
    do {
        let existingMp4File = try AKAudioFile(readFileName: "recording.mp4", baseDir: .temp)
        if let micRecorderAudioFile = micRecorder.audioFile {
            existingMp4File.appendAsynchronously(file: micRecorderAudioFile, completionHandler: callbackAfterAsynchronousAppend)
        }
    } catch {
        print("Failed to read or append recording.mp4")
    }
}


func callbackAfterInitialExport(processedFile: AKAudioFile?, error: NSError?) {
    if let file = processedFile {
        print("Asynchronous export of (file.fileNamePlusExtension) succeeded")
        print("Exported file duration: (file.duration) seconds")
    } else {
        print("Asynchronous export failed")
    }
}

func callbackAfterAsynchronousAppend(processedFile: AKAudioFile?, error: NSError?) {
    
    if let file = processedFile {
        print("Asynchronous append succeeded. New file is (file.fileNamePlusExtension)")
        print("Duration of new file: (file.duration) seconds")
    } else {
        print("Asynchronous append failed")
    }
}
  

}

Ответ №1:

Не заполнял соответствующие параметры для appendAsynchronously вызова. Вызов должен быть:

если разрешить micRecorderAudioFile = micRecorder.AudioFile { Существующий файл MP4FILE.appendAsynchronously (файл: micRecorderAudioFile, baseDir: .temp, имя: «запись», обработчик завершения: обратный вызов после синхронного добавления) }