WebRTC Gateways について
遠隔会議などで主に使用されている遠隔通信技術WebRTCであるが, ブラウザなどを使用せずに直接通信が可能になるWebRTC Gatewaysという規格が存在していることは意外にも知られていない. この技術は, WebRTC技術と同じようにP2P通信を最終的には可能にするのだが, WebRTCと違うのはブラウザやアプリといったものを繋げるのではなく, Gatewayと呼ばれるものを繋げる点にある. これによって, 規格に定められた方式を行うことなく直接通信することが出来るのがWebRTC Gatewaysの最大のメリットと言えるだろう.
Skyway WebRTC Gateway について
しかし, 上記のGatewayは通常のWebRTCと違って明確な定義はされていない. また, ブラウザのように標準的なものに実装されているものでもないため, 実装は通常のWebRTC実装に比べると格段に上がる. WebRTCは仕組み自体が複雑なので, 全てを実装しようと思うと相当な難易度であることは言うまでもない.
NTTコミュニケーションズはこれを比較的容易に実装出来るものを提供している. 今回は, その実装方法を説明した記事があまりにも少なかったので簡単ではあるが記載している. なお, 下記に公式ドキュメントのリンクを載せておく.
今回, 実装するもの
環境1のPCと環境2の別々のPCでSkyway Gatewayを介して通信を繋げる. 今回は, ビデオ映像や音声データを転送するMediaStreamとバイトや文字を繋げるDataChannelの両方を実装したものを載せている.
手順
主な手順は以下の通りになる.
- Skywayにアクセス後, ログイン(会員未登録の場合は会員登録)
- API Keyの発行
- Skyway WebRTC Gateway GitをGit Cloneする
- /skyway-webrtc-gateway/samplesへ移動
- API Keyを入力
- Gateway Server 起動
- プログラム実行
なお, API Keyについての説明は下記のサイトが分かりやすいので参考にどうぞ.
環境構築
実装環境:Ubuntu20.04LTS
それでは, 上記の手順から実際に必要コマンドを入力することで環境を構築していく. なお, Skyway WebRTC Gatewayで使用するGateway ServerはOSによっては動作しないことがあるので, 注意が必要である.
Skyway API Keyの発行
最初に上記のサイトを参考にAPI Keyを発行する. なお, 基本的にアドレスとして記入するものは「localhost」のみで良い. また, 取得出来たAPI Keyを記録しておく.
Skyway Gateway インストール
サンプルコードを入手するために下記コマンドを実行する.
git clone https://github.com/skyway/skyway-webrtc-gateway
同様に, Gateway Serverもリンクから, GUIで入手するか下記のコマンドを入力する. なお, 使用するデバイスがarm版なのかx64版なのかで動作するものが変更するので注意.
wget https://github.com/skyway/skyway-webrtc-gateway/releases/download/4.0.1/gateway_linux_arm
その後, インストールしたものに権限を付与する.
chmod +x gateway_linux_arm
環境1
今回, 環境1で使用したコードは以下の通りである. なお, ポートは上記のRCTPとSCTPともに全て空いている. 使用する場合は出力部分を増やし, 確認してほしい. 今回は, ビデオ送信部分とDatacahnel部分のみを出力している.
SKYWAY_API_KEY = ENV["API_KEY"]
PEER_ID = "callee"
TARGET_ID = "caller"
RECV_ADDR = "127.0.0.1"
VIDEO_RECV_PORT = 20000
AUDIO_RECV_PORT = 20001
VIDEO_RTCP_RECV_PORT = 20010
AUDIO_RTCP_RECV_PORT = 20011
DATA_RECV_ADDR = "127.0.0.1"
DATA_RECV_PORT = 10002
#connect to skyway server
peer_token = create_peer(SKYWAY_API_KEY, PEER_ID)
#port open request for sending data
(video_id, video_ip, video_port) = create_media(true)
(audio_id, audio_ip, audio_port) = create_media(false)
(video_rtcp_id, video_rtcp_ip, video_rtcp_port) = create_rtcp()
(audio_rtcp_id, audio_rtcp_ip, audio_rtcp_port) = create_rtcp()
(data_id, dest_ip, dest_port) = create_data
media_connection_id = wait_call(PEER_ID, peer_token)
data_connection_id = wait_connection(PEER_ID, peer_token)
wait_open(data_connection_id)
video_redirect = [RECV_ADDR, VIDEO_RECV_PORT]
audio_redirect = [RECV_ADDR, AUDIO_RECV_PORT]
video_rtcp_redirect = [RECV_ADDR, VIDEO_RTCP_RECV_PORT]
audio_rtcp_redirect = [RECV_ADDR, AUDIO_RTCP_RECV_PORT]
answer(media_connection_id, video_id, video_redirect, audio_id, audio_redirect, video_rtcp_id, video_rtcp_redirect, audio_rtcp_id, audio_rtcp_redirect)
wait_ready(media_connection_id)
manage_data_transmission_settings(data_connection_id, data_id, DATA_RECV_ADDR, DATA_RECV_PORT)
puts "Video Recv from #{RECV_ADDR}:#{VIDEO_RECV_PORT}"
puts "Data Send to #{dest_ip}:#{dest_port}"
puts "Data Recv from #{DATA_RECV_ADDR}:#{DATA_RECV_PORT}"
sleep(1000)
#closing
request(:delete, "/media/connections/#{media_connection_id}")
request(:delete, "/peers/#{PEER_ID}?token=#{peer_token}")
最初に, Gateway Serverを立ち上げる.
./gateway_linux_arm
ディレクトリを移動
cd skyway-webrtc-gateway/samples
サイトで取得したAPI Keyを下記コマンドで入力
export API_KEY="YOUR KEY"
最後に, 上記のプログラムを実行する. なお, peer部分はpeerなので何でも良い.
ruby callee.rb peer
一度, 待機させて環境2へ
環境2
環境1と同様に使用するコードを載せておく.
require './util.rb'
SKYWAY_API_KEY = ENV["API_KEY"]
PEER_ID = "caller"
TARGET_ID = "callee"
RECV_ADDR = "127.0.0.1"
VIDEO_RECV_PORT = 20000
AUDIO_RECV_PORT = 20001
VIDEO_RTCP_RECV_PORT = 20010
AUDIO_RTCP_RECV_PORT = 20011
DATA_RECV_ADDR = "127.0.0.1"
DATA_RECV_PORT = 10001
#connect to skyway server
peer_token = create_peer(SKYWAY_API_KEY, PEER_ID)
#port open request for sending data
(video_id, video_ip, video_port) = create_media(true)
(audio_id, audio_ip, audio_port) = create_media(false)
(video_rtcp_id, video_rtcp_ip, video_rtcp_port) = create_rtcp()
(audio_rtcp_id, audio_rtcp_ip, audio_rtcp_port) = create_rtcp()
(data_id, dest_ip, dest_port) = create_data
video_redirect = [RECV_ADDR, VIDEO_RECV_PORT]
audio_redirect = [RECV_ADDR, AUDIO_RECV_PORT]
video_rtcp_redirect = [RECV_ADDR, VIDEO_RTCP_RECV_PORT]
audio_rtcp_redirect = [RECV_ADDR, AUDIO_RTCP_RECV_PORT]
media_connection_id = call(PEER_ID, peer_token, TARGET_ID, video_id, video_redirect, audio_id, audio_redirect, video_rtcp_id, video_rtcp_redirect, audio_rtcp_id, audio_rtcp_redirect)
data_connection_id = connect(peer_token, PEER_ID, TARGET_ID, data_id, DATA_RECV_ADDR, DATA_RECV_PORT)
wait_ready(media_connection_id)
wait_open(data_connection_id)
puts "Video Send to #{video_ip}:#{video_port}"
puts "Data Send to #{dest_ip}:#{dest_port}"
puts "Data Recv from #{DATA_RECV_ADDR}:#{DATA_RECV_PORT}"
sleep(100000)
#closing
request(:delete, "/media/connections/#{media_connection_id}")
request(:delete, "/peers/#{PEER_ID}?token=#{peer_token}")
環境1と同じ手順である.
Gateway Serverを立ち上げる.
./gateway_linux_arm
ディレクトリを移動
cd skyway-webrtc-gateway/samples
サイトで取得したAPI Keyを下記コマンドで入力
export API_KEY="YOUR KEY"
最後に, 上記のプログラムを実行する. なお, peer部分は環境1と必ず同じにすること.
ruby callee.rb peer
すると, 下記のようにデバッグされれば正常に動作している. なお, ポート番号は変動するため下記と違っていても問題ない.
Video Recv from 127.0.0.1:20000
Data Send to 127.0.0.1:10002
Data Recv from 127.0.0.1:50001
Video Send to 127.0.0.1:50005
Data Send to 127.0.0.1:10001
Data Recv from 127.0.0.1:50001
あとは, 指定されているポートにUDPでパケットを送ってやれば良い. 試しに下記コマンドを記しておく.
nc -u -l 10002
nc localhost -u 50001
環境1側でhello worldと入力し, 環境2側で出力されていれば問題ない.
同様にビデオ側も
gst-launch-1.0 udpsrc port=20000 caps="application/x-rtp,payload=(int)100" ! rtpjitterbuffer latency=500 ! rtph264depay ! avdec_h264 output-corrupt=false ! videoconvert ! fpsdisplaysink sync=false
gst-launch-1.0 autovideosrc name=src0 ! video/x-raw,width=640,height=480 ! videoconvert ! x264enc bitrate=90000 pass=quant quantizer=25 rc-lookahead=0 sliced-threads=true speed-preset=superfast sync-lookahead=0 tune=zerolatency ! rtph264pay pt=100 mtu=1400 config-interval=3 ! udpsink port=50005 host=127.0.0.1 sync=false
そして, 環境1側でビデオ映像が流れるはずである.
まとめ
今回は, こんなにも便利に使用出来るWebRTC GatewaysであるSkyway Gatewayの記事が少なかったので記載した. 今後も, WebRTCに関連した記事や技術記事を上げていこうと思う.