2016-03-02 381 views
0

有沒有人有任何代碼片段顯示如何將M4a文件轉換爲WAV?我知道有些庫可以用其他方式進行轉換。iOS代碼將m4a轉換爲WAV

謝謝。

+0

看到這一次可能是它可以幫助你http://stackoverflow.com/questions/31452202/ios-swift-merge-and-convert-wav-files-to-mp3 –

回答

3

如果別人需要一些代碼來做到這一點這是斯威夫特

func convertAudioFile(sourceURL: CFURLRef, destinationURL: 
CFURLRef, outputFormat: OSType , 
outputSampleRate: Float64) -> OSStatus 
{ 
var error : OSStatus = noErr 
var destinationFile : ExtAudioFileRef = nil 
var sourceFile : ExtAudioFileRef = nil 

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

var audioConverter : AudioConverterRef = nil 

audioConverter = AudioConverterRef.init() 

ExtAudioFileOpenURL(sourceURL, &sourceFile) 

var thePropertySize: UInt32 = UInt32(strideofValue(srcFormat)) 

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

dstFormat.mSampleRate = (outputSampleRate == 0 ? srcFormat.mSampleRate : outputSampleRate) //Set sample rate 

dstFormat.mFormatID = outputFormat 
dstFormat.mChannelsPerFrame = 1 
dstFormat.mBitsPerChannel = 16 
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame 
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame 
dstFormat.mFramesPerPacket = 1 
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger // little-endian 

//Create destination file 
ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil, 
    AudioFileFlags.EraseFile.rawValue, &destinationFile) 

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

var size : UInt32 = UInt32(strideofValue(audioConverter)) 

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

var canResume : UInt32 = 0 

size = UInt32(strideofValue(canResume)) 

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

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

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) 

let audioAsset = AVURLAsset.init(URL: destinationURL, options: nil) 
if(audioAsset.duration.seconds < 5.0){ 
    error = -2500 
} 

return error; 
+1

如果我想將m4a文件轉換爲wav文件,應該傳遞哪個'OSType'和'outputSampleRate'? – Cesare

+0

是的。你想使用OSType的kAudioFormatLinearPCM和outputSampleRate 16000 – O2U

+0

非常舊的代碼,Swift 3有很多變化。 –

0

在AVFoundation框架中的AVAssetReader和AVAssetWriter可以用於讀取AAC文件並將該數據寫入iOS設備上的WAV/RIFF文件。 Apple開發人員網站上有示例代碼。這不僅僅是一小段片段。

+0

謝謝使用,這就是我現在正在處理的內容。我將代碼轉換爲Swift,因爲示例代碼使用的是C++。 – O2U

0

下面是編輯爲@ O2U的answere。由於上述代碼實際上並未將其轉換爲波形文件。請在上面的代碼中使用「kAudioFileWAVEType」而不是「kAudioFileCAFType」在行//Create destination file ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil, AudioFileFlags.EraseFile.rawValue, &destinationFile)

+0

你改變了別的嗎?當我使用'kAudioFileWAVEType'時,沒有設置destinationFile' –

+0

不,沒有改變這個。請檢查您的目標網址是否正確,這可能是目標文件未設置時的問題。 –

6

只是爲了更新斯威夫特3:

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() 

    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 = kLinearPCMFormatFlagIsPacked | 
    kAudioFormatFlagIsSignedInteger 

    // Create destination file 
    error = ExtAudioFileCreateWithURL(
     outputURL as CFURL, 
     kAudioFileWAVEType, 
     &dstFormat, 
     nil, 
     AudioFileFlags.eraseFile.rawValue, 
     &destinationFile) 
    print("Error 1 in convertAudio: \(error.description)") 

    error = ExtAudioFileSetProperty(sourceFile!, 
            kExtAudioFileProperty_ClientDataFormat, 
            thePropertySize, 
            &dstFormat) 
    print("Error 2 in convertAudio: \(error.description)") 

    error = ExtAudioFileSetProperty(destinationFile!, 
            kExtAudioFileProperty_ClientDataFormat, 
            thePropertySize, 
            &dstFormat) 
    print("Error 3 in convertAudio: \(error.description)") 

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

    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 
     } 

     error = ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList) 
     print("Error 4 in convertAudio: \(error.description)") 

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

     sourceFrameOffset += numFrames 
     error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList) 
     print("Error 5 in convertAudio: \(error.description)") 
    } 

    error = ExtAudioFileDispose(destinationFile!) 
    print("Error 6 in convertAudio: \(error.description)") 
    error = ExtAudioFileDispose(sourceFile!) 
    print("Error 7 in convertAudio: \(error.description)") 
} 
+0

太棒了!謝謝!希望我可以投票10次。 –

+0

除了使用kAudioFileMP3Type以外,還有其他更改導出到MP3嗎?我在錯誤= ExtAudioFileSetProperty(destinationFile!)時遇到了錯誤=使用MP3類型 – miOS

+0

您可能需要嘗試不同的mFormatFlags。您會注意到,除了kAudioFileMP3Type之外,這是一個與已接受的答案之間的區別。 – MScottWaller