【Python 軍火庫🧨 - websockets】傳送/接收音檔並轉換成numpy(基礎篇)

更新於 發佈於 閱讀時間約 6 分鐘
raw-image



關於Websockets的篇章, 有興趣的朋友歡迎參考:

而這一篇章的主題主要是來分享如何透過websockets傳遞音檔並進行解碼, 我們都知道聲音的運算在Python的世界裡通常會轉成numpy或者是torch.Tensor這樣的資料結構來進行語音辨識、VAD、人聲分離…相關的語音計算, 但這會牽涉到音訊的編碼與解碼, 對於一般工程背景的開發者來說會相對較為複雜一些, 我們會嘗試著以較為基本知識的角度來進行傳輸層的說明與分析作法。

那麼首先在進入主題之前, 我們非常推薦您閱讀「【Python 軍火庫 - websockets】雙向溝通的渠道」, 因為當我們掌握了基本的傳輸方式之後, 之後的難題僅是編碼與解碼的過程, 所以請嘗試著根據說明搭建起websockets的傳輸與接收框架吧!

那麼關於編碼與解碼就會面臨到兩個問題了, 究竟是要Client端解碼後送到後端,還是後端再進行解碼呢?

那麼我們今天的主題就先來談談第一種,從Client端對音檔解碼之後傳送到後端的過程吧!

Client端

對於Client端來說,要進行音訊的讀取勢必會需要一些好用的套件,包括soundfile、pydub、…等,那我們就先用soundfile這個套件來進行示範吧!

關於soundfile我們先來簡單的說明一下, 它提供了對各種音頻文件格式的支持,這個模組的主要目的是簡化在 Python 中處理音頻文件的任務,使用戶能夠輕鬆地讀取和編寫不同格式的音頻數據。

安裝的部分:

# 記得安裝一下ffmpeg,我們的底層端會透過ffmpeg進行音訊處理
apt install ffmpeg

# 透過pip安裝soundfile套件
pip install soundfile

正式進入音訊解碼片段,以下是片段示範,透過soundfile音訊解碼後成numpy資料再轉成bytes進行傳送:

import asyncio
import websockets
import soundfile as sf

async def client():
async with websockets.connect(
'ws://0.0.0.0:8766',
ping_interval=None,
) as websocket: # noqa
sound_file = 'test.wav'
print(f'Sending {sound_file}')

chunk_size = 4096

# 讀取音檔並解碼成numpy再轉成bytes送websockets
with sf.SoundFile(sound_file, 'r') as file:
while True:
data = file.read(chunk_size, dtype='float32')
if data.size == 0:
break
chunk = data.tobytes()
await websocket.send(chunk)

await websocket.send('Done')

asyncio.run(client())

Server端

Server端的部分則是將接收到的bytes資料透過numpy的轉換轉成陣列結構, 後續我們可以進行語音辨識、VAD、去背景噪音…等音訊處理的作業。

import asyncio
import websockets
import numpy as np

async def server(websocket, path):
while True:
try:
message = await websocket.recv()
if message == 'Done':
return None

# 轉換成numpy資料型態準備進行後續運算
array = np.frombuffer(message, dtype=np.float32)

print(len(array))
except websockets.exceptions.ConnectionClosedOK:
print("Client disconnected")
break

async def main():
async with websockets.serve(server, "0.0.0.0", 8766):
print('start server: 0.0.0.0:8766')
await asyncio.Future() # run forever

asyncio.run(main())

我們可以接收到的資料長度如下:

raw-image


結語

音訊又是一門不同境界的學問, 不過我們也不要氣餒,所有跟程式有關的運作都離不開一些共同的核心邏輯,只要我們按部就班,打好基礎耐心學習,相信總有一天會將所有知識點融會貫通,也希望這個篇章能夠讓您學習到如何透過websockets來傳遞音訊並進行運算處理。

對了,今天的方式主要是透過Client端進行音訊解碼的動作,這樣的方式雖然簡單,但額外的傳輸成本較大,因此我們會在「【💎Python 軍火庫 - websockets】傳送/接收音檔並轉換成numpy(進階篇)」教您如何在Server端進行解碼,而Client端只要將檔案原封不動的傳送即可。

avatar-img
121會員
270內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
阿Han的沙龍 的其他內容
本文介紹了Python如何使用websockets進行雙向溝通,包括文字、json、xml和音訊的傳遞。特別著重於json資料交換格式,以及websockets通道的基本流程和關鍵的編碼與解碼。最終談到WebSocket對於傳統同步程式的轉變及對asyncio等套件的重要性。
我們常常在看開源專案時, 會在函式中看到「*args」與「**kwargs」這兩個參數, 一直以來都很好奇也尚未使用, 趁著好奇心強烈的時期趕緊來了解一番, 並且將學習過程轉化為易懂的概念提供給有需要的朋友參考, 也期望我們能夠共同學習程式語言, 讓科技引領世界進步。 首先是 *args 會
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
為什麼需要非同步? 我們在「【Web微知識系列】 Web Workers」有介紹到在瀏覽器可執行腳本Javascript環境底下如何完成非同步的操作, 主要是為了讓任務更有效率的進行, 不會因為一個非常耗時的工作堵塞住整個服務, 導致無法服務他人的窘境。 大家應該經常在餐廳裡會看到服務員協
我們在處理音檔時常常會使用到 [soundfile](https://pypi.org/project/soundfile/) 這套工具, 當我們試圖讀取檔案時卻發生了這樣的錯誤訊息… TypeError: Not allowed for existing files (except 'RAW')
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp
本文介紹了Python如何使用websockets進行雙向溝通,包括文字、json、xml和音訊的傳遞。特別著重於json資料交換格式,以及websockets通道的基本流程和關鍵的編碼與解碼。最終談到WebSocket對於傳統同步程式的轉變及對asyncio等套件的重要性。
我們常常在看開源專案時, 會在函式中看到「*args」與「**kwargs」這兩個參數, 一直以來都很好奇也尚未使用, 趁著好奇心強烈的時期趕緊來了解一番, 並且將學習過程轉化為易懂的概念提供給有需要的朋友參考, 也期望我們能夠共同學習程式語言, 讓科技引領世界進步。 首先是 *args 會
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
為什麼需要非同步? 我們在「【Web微知識系列】 Web Workers」有介紹到在瀏覽器可執行腳本Javascript環境底下如何完成非同步的操作, 主要是為了讓任務更有效率的進行, 不會因為一個非常耗時的工作堵塞住整個服務, 導致無法服務他人的窘境。 大家應該經常在餐廳裡會看到服務員協
我們在處理音檔時常常會使用到 [soundfile](https://pypi.org/project/soundfile/) 這套工具, 當我們試圖讀取檔案時卻發生了這樣的錯誤訊息… TypeError: Not allowed for existing files (except 'RAW')
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp
你可能也想看
Google News 追蹤
提問的內容越是清晰,強者、聰明人越能在短時間內做判斷、給出精準的建議,他們會對你產生「好印象」,認定你是「積極」的人,有機會、好人脈會不自覺地想引薦給你
Thumbnail
模塊、包 導入模塊: import module_name 導入模塊重新命名 import module_name asmn 檢查模塊屬性: dir(module_name) 文件操作 打開文件 open('filena
Thumbnail
基礎語法: 1、注釋: 例如:#單行注釋 ““多行注釋”” 2、變量:直接賦值, 例如:x=5 3、數據類型: 例如:int, float, str, bool 4、類型轉換: 例如:int( ), float( ), str( ), bool( )
Thumbnail
當我們在進行「語音辨識」的應用開發時, 首先會面臨一個問題, 那就是究竟要怎麼知道哪些段落是「人在說話的區段」, 精確的標示出這些區段之後, 我們除了可以儲存成純對話的段落, 還可以做出時間軸的字幕檔, 應用非常廣泛, 因此學會怎麼用VAD是進入語音領域非常重要的其中一個環節。 VAD代表
Thumbnail
EasyOCR是一個能夠幫助你對圖片中的文字進行辨識的工具,透過進階分析,可以應用在文件掃描、自動化數據輸入、發票掃描等領域。本章節將介紹如何安裝、引用模型、進行文字辨識、以及辨識結果的分析。透過學習,你可以建立屬於自己的文字辨識系統。
提問的內容越是清晰,強者、聰明人越能在短時間內做判斷、給出精準的建議,他們會對你產生「好印象」,認定你是「積極」的人,有機會、好人脈會不自覺地想引薦給你
Thumbnail
模塊、包 導入模塊: import module_name 導入模塊重新命名 import module_name asmn 檢查模塊屬性: dir(module_name) 文件操作 打開文件 open('filena
Thumbnail
基礎語法: 1、注釋: 例如:#單行注釋 ““多行注釋”” 2、變量:直接賦值, 例如:x=5 3、數據類型: 例如:int, float, str, bool 4、類型轉換: 例如:int( ), float( ), str( ), bool( )
Thumbnail
當我們在進行「語音辨識」的應用開發時, 首先會面臨一個問題, 那就是究竟要怎麼知道哪些段落是「人在說話的區段」, 精確的標示出這些區段之後, 我們除了可以儲存成純對話的段落, 還可以做出時間軸的字幕檔, 應用非常廣泛, 因此學會怎麼用VAD是進入語音領域非常重要的其中一個環節。 VAD代表
Thumbnail
EasyOCR是一個能夠幫助你對圖片中的文字進行辨識的工具,透過進階分析,可以應用在文件掃描、自動化數據輸入、發票掃描等領域。本章節將介紹如何安裝、引用模型、進行文字辨識、以及辨識結果的分析。透過學習,你可以建立屬於自己的文字辨識系統。