我們在處理音檔時常常會使用到 [soundfile](https://pypi.org/project/soundfile/) 這套工具, 當我們試圖讀取檔案時卻發生了這樣的錯誤訊息…
TypeError: Not allowed for existing files (except 'RAW'): samplerate, channels, format, subtype, endian
用於讀取和寫入音頻文件。它提供了一種簡單而靈活的方式來處理各種音頻格式的數據,例如 WAV、FLAC、AIFF、OGG 等等。
使用 soundfile 可以讓使用者輕鬆地處理音頻文件,從而進行聲音處理、信號處理、音樂分析等各種應用。
簡單的讀取音檔我們可以這樣做。
data, samplerate = sf.read('existing_file.wav')
這樣的讀取方式沒問題, soundfile 會根據我們的副檔名進行相關的格式轉換, 但凡事總有一些例外狀況。
處理音訊時, 通常我們不會一次的連接就傳送所有的資料, 這樣對於效率來說太沒效率了, 尤其是大檔案, 我們通常會搭配websocket + asyncio來接收傳送的檔案並處理, 因此假設我們的伺服端皆收到檔案資料並試圖解碼時…
message = await socket.recv()
if message == 'Done':
return None, None
with io.BytesIO(message) as file:
message, _ = sf.read(
file=file,
dtype='float32',
format='WAV',
)
這時候就發生了以下狀況:
TypeError: Not allowed for existing files (except 'RAW'): samplerate, channels, format, subtype, endian
首先我們根據線索查到原始碼區段, 🔍 請參考這裡
原來是當我們的來源不是RAW時, 不允許隨意去更改 samplerate, channels, format, subtype, endian 這些屬性。
那麼如此一來事情就簡單了。
message, _ = sf.read(
file=file,
dtype='float32',
format='RAW',
subtype='PCM_16',
samplerate='16000',
channels=1,
endian='FILE',
)
message, _ = sf.read(
file=file,
dtype='float32'
)
音訊處理果然又是一個坑,相較於單純的文字處理, 需要具備更多底層的知識, 雖然困難, 但掌握起來後成就感會非常的大, 因此我們應該勇於學習, 讓自己的實力更加深厚, 共勉之。