WEBRTC+FFMPEG+RNN 服務端實現通話背景噪聲消除
created by snowlyg
開源的 webrtc 項目本身內置了對音頻信號的3A算法,包括回聲消除(AEC)、噪聲抑制(ANS)、自動增益控制(AGC), 這個三個算法配合在發聲端對音頻數據進程處理,可以提高音頻質量和通話效果。
但是 webrtc 畢竟是國外的開源項目,國內的小廠商的硬件大部分都無法很好適配,而且一些低端產品的麥克風和揚聲器質量不太行,導致實際的通話效果並不理想。
小廠商的產品線又不穩定。可能過幾個月,之前的產品就淘汰了。所以修改 webrtc 項目去做適配不僅費時費力,而且很可能最終成為無用功。
在服務端中間層對音頻處理之後再發送到遠端設備,是另一種可行的解決方案。
需求依賴
- ffmpeg
- opus
- webrtc
- models
項目樣例採用開源項目 https://github.com/pion/webrtc/tree/master/examples/save-to-disk 。
- 編譯 save-to-disk 樣例,生成 save-to-disk 執行文件
git clone https://github.com/pion/webrtc --depth=1
cd webrtc/[examples/save-to-disk](https://github.com/pion/webrtc/tree/master/examples/save-to-disk)
go build
- 在瀏覽器打開 https://jsfiddle.net/2nwt1vjq/ 地址,點擊
Copy browser SDP to clipboard按鈕,複製瀏覽器 SDP 信息。
- 執行 save-to-disk 執行文件並帶上 複製的瀏覽器SDP 信息,將控制枱輸出的 sdp 信息複製到瀏覽器的第二個輸入框,並點擊
Start Session按鈕。
- 瀏覽器能看到 connected 輸出,説明 webrtc 建立完成。
同時控制枱看到正在保持 .opus 和 .ivf 文件,通過 Audacity 軟件查看可以發現有明顯的背景噪聲。
接下來需要花費幾分鐘時間,增加相關邏輯來消除相關噪聲
步驟分別為:
- 在
OnTrack回調方法中解碼webrtc音頻數據為PCM數據流 - 將
PCM通過FFMPEG過濾器將數據降噪,再重新將處理好的數據發回webrtc
Webrtc 默認採用 opus 音頻格式,採用 https://github.com/hraban/opus/tree/v2 項目來解碼音頻數據會比較合適。
如果沒有 opus 編碼庫依賴,可以使用 https://github.com/xiph/opus 項目編譯。
var sampleRate = 48000
var channels = 2
var frameSizeMs int = 20 // if you don't know, go with 60 ms.
frameSize := channels * frameSizeMs * sampleRate / 1000
pcm := make([]int16, int(frameSize))
dec, err := opus.NewDecoder(sampleRate, channels)
if err != nil {
return
}
for {
packet, _, err := track.ReadRTP()
if err != nil {
return
}
n, err := dec.Decode(packet.Payload, pcm)
if err != nil {
return
}
pcm = pcm[:n*channels]
buf := new(bytes.Buffer)
// Write the int16 to the buffer, specifying the byte order (e.g., LittleEndian)
if err := binary.Write(buf, binary.LittleEndian, pcm); err != nil {
return
}
}
把解碼後的數據發送到 ffmpeg 可以通過 pipe:0 通道傳輸
cmd := exec.Command("ffmpeg", "-v", "verbose", "-f", "s32le", "-i", "pipe:0", "-ac", "2", "-ar", "48000", "-af", "arnndn=m=models/cb.rnnn", "-vn", "-b:a", "64k", "-c:a", "libopus", "output_rnn.opus")
重複之前的信令複製過程,控制枱會顯示 ffmpeg 命令的輸出內容如下:
輸出文件為 output_rnn.opus 通過 Audacity 軟件查看可以發現之前明顯的背景噪聲,現在幾乎全部消失了。
FFMPEG 音頻過濾器還支持很多其它的效果,比如 動態均衡、混音、濾波 等等。
具體介紹可以查看 官方文檔。
完整代碼地址 https://github.com/snowlyg/webrtc_denoise_use_ffmpge
參考
- https://github.com/pion/webrtc
- https://ffmpeg.org/ffmpeg-filters.html
- https://github.com/richardpl/arnndn-models