Asterisk chan websocket
Asteriskの新しいチャネルとしてWebsocketチャネルが追加された。
使用可能なバージョンは 23.0.0,22.6,0, 21.11.0, 20.16.0 のそれぞれ以降のバージョン。メジャーバージョンによる追加ではなく、マイナーバージョンの途中から追加されているので注意。
従来からあるPjSIPのws/wssではなく、チャネルドライバとしてのWebsocket。
関連するモジュール
chan_websocket
res_websocket_client
*CLI> core show channeltype WebSocket
-- Info about channel driver: WebSocket --
Device State: no
Presence State: no
Indication: no
Transfer : no
Capabilities: (codec2|g723|ulaw|alaw|gsm|g726|g726aal2|adpcm|slin|slin12|slin16|slin24|slin32|slin44|slin48|slin96|slin192|lpc10|g729|speex|speex16|speex32|ilbc|g722|siren7|siren14|g719|opus|jpeg|png|h261|h263|h263p|h264|h265|mpeg4|vp8|vp9|red|t140|t38|silk8|silk12|silk16|silk24)
Digit Begin: no
Digit End: yes
Send HTML : no
Image Support: no
Text Support: no
*CLI> module show like res_websocket_client.so
Module Description Use Count Status Support Level
res_websocket_client.so WebSocket Client Support 2 Running core
注意点
Websocket接続ではあるものの、リアルタイムの場合には、RTPと同様に20m秒のペーシング(1フレームあたり20m秒)の送出間隔を守ること。AsteriskからWebsocketへの送出はこの20m秒フレームで送られるが、外部からAsteriskに送りつける場合にも20m秒を守る必要がある。これが乱れると音声の品質低下、あるいは再生されないといった問題が発生する。この問題は割とハマるので注意。
設定
AsteriskからWebsocketに対して発信する場合の例。
websocket_client.conf に以下のように記述する。"ws-connection1"が識別名。
[ws-connection1] type = websocket_client uri = ws://127.0.0.1:8765 protocols = media connection_type = per_call_config connection_timeout = 500 reconnect_interval = 500 reconnect_attempts = 5 tls_enabled = no
websocket_client.conf を変更した場合には CLI から module reload res_websocket_client.so を実行すると設定が反映される。
Websocketに対して発信する場合には以下のように書く
exten => 9805,1,NoOp exten => 9805,n,Dial(Websocket/ws-connection1/c(slin16)) exten => 9805,n,Hangup
テクノロジにWebsocket、/の後に識別名、その後にCODECを指定。c(slin16)はCODECにslin16(16kHzサンプリング 16bit LEのリニアPCM)の意味。CODECはチャネルで指定できるものが使えるが、Websocketのアプリケーション側で解釈できるものを使うこと。
なお、AudioSocketではslin(8kHz 16bit LE)しか使えないが、Websocketではslin16の16kHzが使える。
Asteriskを着信側に使う場合はちょっと面倒なので省略。使い勝手はあまりよくない。
Websocket側サンプルコード
Websocketで待ち受け、ALSAデバイスで通話するサンプル。
https://github.com/takao-t/asterisk-experimental/blob/main/websokect/ws_audio_server.py
Websocketで待ち受け、音声をエコーバックするサンプル。
https://github.com/takao-t/asterisk-experimental/blob/main/websokect/ws_echo.py
AsteriskのWebsocketチャネルではバイナリ(音声)データとテキストをサポートしている。テキストデータではステータスやコマンド等をやりとりできるので、サンプルコードに入れてあるが、この挙動(ANSWER)は今のところ効かない。Asterisk側の問題ではないかと思われる。
Dial時オプションに'n'を付けるとAuto Answerしないとドキュメントに書かれているものの、Dial(Websocket/ws-connection1/c(slin16)n) のように書いてもAnswerしてしまうので、サンプルコード中の"ANSWER"送信は実際には効かないが、コマンド送りの例として残してある。
バッファリングモード
20m秒のペーシングが行えない場合には、Asteriskのバッファを使う手段が使える。この場合、以下の手順で送信する(Websocket->Asterisk)。
WS->Asterisk TEXTでSTART_MEDIA_BUFFERINGを送信 Asteriskがバッファリング開始 WS->Asteriskに音声データ送信 Asterisk->WS バッファが9割になるとXOFF送出 WS->Asteriskは送出を停止 Asterisk->WS バッファが減ったらXON送出 Asterisk->WSは送出を再開
バッファリングモードのサンプルコード
使用例としてはAIが生成した音声ファイルを送り付けて再生する場合など。基本XON/XOFFに従って制御すれば大丈夫そうである。