解決使用 AVAudioRecorder 錄音儲存 .WAV 檔案遇到的問題

語言: CN / TW / HK

問題背景

伺服器接收到檔案並進行語音識別,使用的是微軟語音,只支援 PCM 資料來源的 WAV 格式。

問題程式碼

- (NSDictionary *)getAudioSetting {
    NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
    //設定錄音格式
    [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
    //設定錄音取樣率,8000是電話取樣率,對於一般錄音已經夠了
    [dicM setObject:@(16000) forKey:AVSampleRateKey];
    //設定通道,這裡採用單聲道 1 2
    [dicM setObject:@(2) forKey:AVNumberOfChannelsKey];
    //每個取樣點位數,分為8、16、24、32
    [dicM setObject:@(16) forKey:AVLinearPCMBitDepthKey];
    //是否使用浮點數取樣
    [dicM setObject:@(NO) forKey:AVLinearPCMIsFloatKey];
    //....其他設定等
    return dicM;
}

在沒有使用微軟語音識別庫之前,使用上面的程式碼沒有任何問題。識別庫更新之後,不識別上傳的的音訊檔案。

一開始以為是因為沒有使用浮點數取樣導致音訊檔案被壓縮。修改後依然沒有解決問題。

經過和伺服器的聯調,發現 .wav 音訊檔案的頭不資訊服務區無法識別。

解決方案

當音訊檔案儲存為 .wav 格式的時候,iOS11 以下的系統,.wav 檔案的頭部資訊是沒問題,但是在 iOS11+ .wav 檔案的頭部資訊服務區識別不了。

需要設定 AVAudioFileTypeKey 來解決這個問題。程式碼如下:

- (NSDictionary *)getAudioSetting {
    NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
    //設定錄音格式
    [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
    if (@available(iOS 11.0, *)) {
        [dicM setObject:@(kAudioFileWAVEType) forKey:AVAudioFileTypeKey];
    } else {
        // Fallback on earlier versions
    }
    //設定錄音取樣率,8000是電話取樣率,對於一般錄音已經夠了
    [dicM setObject:@(16000) forKey:AVSampleRateKey];
    //設定通道,這裡採用單聲道 1 2
    [dicM setObject:@(2) forKey:AVNumberOfChannelsKey];
    //每個取樣點位數,分為8、16、24、32
    [dicM setObject:@(16) forKey:AVLinearPCMBitDepthKey];
    //是否使用浮點數取樣
    [dicM setObject:@(NO) forKey:AVLinearPCMIsFloatKey];
    //....其他設定等
    return dicM;
}