Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用AudioConverter Swift将.m4a文件转换为.aiff_Swift_Audio_Avfoundation - Fatal编程技术网

使用AudioConverter Swift将.m4a文件转换为.aiff

使用AudioConverter Swift将.m4a文件转换为.aiff,swift,audio,avfoundation,Swift,Audio,Avfoundation,我正在尝试使用中的答案将.m4a格式的给定音频文件转换为.aiff格式。我已将代码转换为Swift 3.0 func convertAudio(_ url: URL, outputURL: URL) { var error : OSStatus = noErr var destinationFile : ExtAudioFileRef? = nil var sourceFile : ExtAudioFileRef? = nil var srcFormat : A

我正在尝试使用中的答案将.m4a格式的给定音频文件转换为.aiff格式。我已将代码转换为Swift 3.0

func convertAudio(_ url: URL, outputURL: URL) {
    var error : OSStatus = noErr
    var destinationFile : ExtAudioFileRef? = nil
    var sourceFile : ExtAudioFileRef? = nil

    var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
    var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()

    var audioConverter : AudioConverterRef? = nil

    ExtAudioFileOpenURL(url as CFURL, &sourceFile)

    var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))

    ExtAudioFileGetProperty(sourceFile!, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)

    dstFormat.mSampleRate = 44100  //Set sample rate
    dstFormat.mFormatID = kAudioFormatLinearPCM
    dstFormat.mChannelsPerFrame = 1
    dstFormat.mBitsPerChannel = 16
    dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
    dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
    dstFormat.mFramesPerPacket = 1
    dstFormat.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger

    //Create destination file
    ExtAudioFileCreateWithURL(outputURL as CFURL, kAudioFileAIFFType, &dstFormat, nil,
                              AudioFileFlags.eraseFile.rawValue, &destinationFile)

    ExtAudioFileSetProperty(sourceFile!, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)
    ExtAudioFileSetProperty(destinationFile!, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)

    var size : UInt32 = UInt32(MemoryLayout.stride(ofValue: audioConverter))

    ExtAudioFileGetProperty(destinationFile!, kExtAudioFileProperty_AudioConverter, &size, &audioConverter)

    var canResume : UInt32 = 0

    size = UInt32(MemoryLayout.stride(ofValue: canResume))

    error = AudioConverterGetProperty(audioConverter!, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume)

    let bufferByteSize : UInt32 = 32768
    var srcBuffer = [UInt8](repeating: 0, count: 32768)
    var sourceFrameOffset : ULONG = 0

    print("Converting audio file")

    while(true){

        var fillBufList = AudioBufferList(
            mNumberBuffers: 1,
            mBuffers: AudioBuffer(
                mNumberChannels: 2,
                mDataByteSize: UInt32(srcBuffer.count),
                mData: &srcBuffer
            )
        )
        var numFrames : UInt32 = 0

        if(dstFormat.mBytesPerFrame > 0){
            numFrames = bufferByteSize / dstFormat.mBytesPerFrame
        }

        ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList)

        if(numFrames == 0){
            error = noErr;
            break;
        }

        sourceFrameOffset += numFrames
        error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList)
    }

    ExtAudioFileDispose(destinationFile!)
    ExtAudioFileDispose(sourceFile!)
}
问题是音频转换器在这条线上似乎为零

error = AudioConverterGetProperty(audioConverter!, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume)
我似乎不明白为什么。我遗漏了什么?

跳过AudioConverterGetProperty 你实际上没有使用它。 以下代码段将音频文件转换为AIFF:它以支持的格式之一读取源文件,创建AIFF编码器,并使用bufferByteSize缓冲区在其中循环。错误处理得很温和

完整代码,swift 3:

支撑方法:

func reportError(error: OSStatus) {
    // Handle error
}
调用:

let sourceUrl = URL(string: Bundle.main.path(forResource: "sample", ofType: "mp3")!)
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                                .userDomainMask,
                                                true)
let documentsDirectory = URL(string: paths.first!)
let destUrl = documentsDirectory?.appendingPathComponent("converted.aiff")
if let sourceUrl = sourceUrl, let destUrl = destUrl {
    print("from \(sourceUrl.absoluteString) to \(destUrl.absoluteString)")
    convertAudio(sourceUrl, outputURL: destUrl)
}

您似乎没有初始化audioConverter,因此它有它的默认值-nil@Cristik它不是在ExtAudioFileGetPropertydestinationFile中设置的吗!,kExtAudioFileProperty_音频转换器、大小和音频转换器?如果没有,那么初始化它的正确方法是什么?除了使用kAudioFileWAVEType外,是否还有其他更改要导出到wav?我在错误=ExtAudioFileSetPropertydestinationFile!时遇到零崩溃!,当使用波形时。我需要将m4a导出到wav或flac。@MarcosGriselli在MP3转换时遇到同样的错误。你找到解决办法了吗?@MarcosGriselli我也遇到了CAF格式的类似问题。到目前为止有什么解决办法吗?
let sourceUrl = URL(string: Bundle.main.path(forResource: "sample", ofType: "mp3")!)
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                                .userDomainMask,
                                                true)
let documentsDirectory = URL(string: paths.first!)
let destUrl = documentsDirectory?.appendingPathComponent("converted.aiff")
if let sourceUrl = sourceUrl, let destUrl = destUrl {
    print("from \(sourceUrl.absoluteString) to \(destUrl.absoluteString)")
    convertAudio(sourceUrl, outputURL: destUrl)
}