LoginSignup
14
15

More than 5 years have passed since last update.

Websocketで簡単に音声のストリーミングをしてみる

Last updated at Posted at 2018-10-10

前回Rustで作ったpipeをwebsocketにつなぐコマンドを使って、音声のストリーミングをしてみます。

準備

前回作ったものはgithubにソースを置いてあります。
Rustはデバッグビルドとリリースビルドでは実行速度にかなり差があるということなので、必ずリリースビルドしたものを使用してください。

cargo build --release

それ以外のコマンドはUbuntu 18.04 では以下で揃います。

sudo apt install alsa-utils opus-tools

事前の確認

以下のようにすると私の環境ではUSBのWebcamの内蔵マイクの音声をイヤホンから出すことができます。(量子化16bit、サンプリングレート 48kHz, モノラル)

arecord -D plughw:2 -f S16_LE -r 48000 -c 1 -t raw \
| aplay -f S16_LE -r 48000 -c 1 

aplay, arecordの引数は環境によって調整してください。

遅延を減らすために-B オプションでバッファリングする時間指定します。マイクロ秒単位です。あまり減らしすぎるとbuffer underrun のエラーが発生しやすくなるので、いい感じに調整します。

arecord -D plughw:2 -f S16_LE -r 48000 -c 1 -B 10000 -t raw \
| aplay -f S16_LE -r 48000 -c 1 -B 20000

これでほぼリアルタイムになりました。
これをネットワークにまたがって行えばストリーミングになります。

非圧縮の音声データのストリーミング

受信側

こちらのマシンのIPアドレスは192.168.10.210です。ポートは8001を使用します。

./ws2stdout 0.0.0.0:8001 \
| aplay -f S16_LE -r 48000 -c 1 -B 20000

送信側

arecord -D plughw:2 -f S16_LE -r 48000 -c 1 -B 10000 -t raw \
| ./stdin2ws ws://192.168.10.210:8001

この方法だとわりと遅延が少ない状態でストリーミングすることができます。しかし非圧縮の音声データなので、100kB/s くらいネットワークの帯域を食います。

opusで圧縮した音声データのストリーミング

opusでのエンコード、デコードをはさんでみます。

受信側

./ws2stdout 0.0.0.0:8001 \
| opusdec - - \
| aplay -f S16_LE -r 48000 -c 1 -B 20000

送信側

arecord -D plughw:2 -f S16_LE -r 48000 -c 1 -B 10000 -t wav \
| opusenc --max-delay 10 --bitrate 32 - - \
| ./stdin2ws ws://192.168.10.210:8001

この方法だとネットワークの帯域はぐっと下がって4KB/s くらいです。
しかし遅延は1秒くらいになります。
opusdec コマンドに遅延に関する設定がないので、ここでバッファリングしているのでしょうか。

参考

昔私が書いた記事。
PCMのデータを自分でいじってデジタルオーディオを理解する

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15