Неверный тип выходного файла - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь вывести wav-файл из приведенной ниже функции, однако во время выполнения я получаю сообщение об ошибке «Неверный тип выходного файла». Я не понимаю, почему AVFileType.wav не работает, я протестировал AVFileType.m4a, и он почему-то работает. Ура!

func createSound(soundFiles: [String], outputFile: String) {
    var startTime: CMTime = kCMTimeZero
    let composition: AVMutableComposition = AVMutableComposition()
    let compositionAudioTrack: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)!

    for fileName in soundFiles {

        let sound: String = fileName
        let url: URL = URL(fileURLWithPath: sound)
        let avAsset: AVURLAsset = AVURLAsset(url: url)
        let timeRange: CMTimeRange = CMTimeRangeMake(kCMTimeZero, avAsset.duration)
        let audioTrack: AVAssetTrack = avAsset.tracks(withMediaType: AVMediaType.audio)[0]

        try! compositionAudioTrack.insertTimeRange(timeRange, of: audioTrack, at: startTime)
        startTime = CMTimeAdd(startTime, timeRange.duration)
    }

    let exportPath: String = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].path+"/"+outputFile+".wav"

    let export: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)!

    export.outputURL = URL(fileURLWithPath: exportPath)
    export.outputFileType = AVFileType.wav

    export.exportAsynchronously {
        if export.status == AVAssetExportSessionStatus.completed {
            NSLog("All done");
            print(export.outputURL)
        }
    }

}

1 Ответ

0 голосов
/ 11 мая 2018

По умолчанию AVAssetExportPresetAppleM4A предназначен для создания файлов m4a, а не файлов wav. Для wav, попробуйте предустановку passthrough: AVAssetExportPresetPassthrough и удалите файлы, оставшиеся от предыдущих запусков:

let export: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)!

export.outputURL = URL(fileURLWithPath: exportPath)
export.outputFileType = .wav

try? FileManager.default.removeItem(at: export.outputURL!)    // otherwise export can fail :(

export.exportAsynchronously {
    // etc
}

Примечание: при AVAssetExportPresetPassthrough ваши входные аудиофайлы, вероятно, тоже должны быть в формате wav, и, возможно, даже иметь тот же формат. Если это не подходит для вас, попробуйте один из AVAssetWriter, AVAudioFile или ExtAudioFile API.

p.s. если вам интересно, какие комбинации AVAssetExportSession preset, AVAsset/AVAssetComposition и AVFileType поддерживаются, вы можете использовать функцию determineCompatibility:

AVAssetExportSession.determineCompatibility(ofExportPreset: AVAssetExportPresetPassthrough, with: composition, outputFileType: .wav) { ok in
    print("COMPUTER SAYS \(ok)")
}

хотя это, в основном, пробный экспорт, за исключением проверки file-url-Уже существует и иногда полезной Error превратилась в бесполезную логическую переменную, так что я думаю, что это вообще ничего не добавляет.

...