UV4Lを使う(3)

前回”UV4Lを使う(2)”は、Raspberry PIから音声と画像のStreamingが出来る様になりました。でも、UV4L、ソケット通信、P2P通信、WebRTCの関係が良く理解出来ていません。今回はこれらに付いて調べてみます。

そもそも、UV4Lとは

UV4Lは、User space Video4Linuxの略です。また、Video4Linuxは、Linuxで映像や音声を扱う時に使用するデバイスの1つです。頭に付いている”User space”の意味がいまいち分かりませんが、Video4Linuxを元にそれに付加するプラグイン(例えば、UBSカメラを使う等)の集まり全体をUV4Lと言っているようです。

UV4Lをインストールした時に使用したコマンドと、実際にインストールされたパッケージを以下に示します。


pi@raspberrypi:~ $ sudo apt-get install uv4l uv4l-webrtc uv4l-uvc

pi@raspberrypi:~ $ dpkg -l | grep uv4l
ii  uv4l            1.9.17   armhf   User space Video4Linux Framework Core
ii  uv4l-decoder2   1.3      armhf   Video Hardware Decoder support for the
ii  uv4l-encoder    1.20     armhf   Video Hardware Encoder support for the
ii  uv4l-renderer   1.10     armhf   Video Renderer for the WebRTC Extension
ii  uv4l-server     1.1.129  armhf   Streaming Server module for UV4L with HTTP/HTTPS front-end.
ii  uv4l-uvc        1.11     armhf   Usb Video Class driver module for UV4L.
ii  uv4l-webrtc     1.92     armhf   WebRTC extension for the
pi@raspberrypi:~ $ 

インストールしたのは、uv4l、 uv4l-webrtc、 uv4l-uvc の3つ。 uv4lはFramework Core。uv4l-webrtcはWebRTC用の、uv4l-uvcはUSBカメラ用のプラグインと思われます。その他の4つは自動的にインストールされました。StreamingをWebブラウザで行っているので、uv4l-serverは必要。その他も必要なパッケージなんでしょう。

UV4Lに関する資料ですが下記を見つけました。

ソケット通信、P2P通信、WebRTC とは

各項目の簡単な説明と関係は以下の様になります。

  • WebRTC:”Web Real-Time Communication”
    • Webブラウザやモバイルアプリでリアルタイム通信を実現するAPI。
  • P2P通信:”Peer-to-Peer”
    • サーバを介さずに、端末同士で直接データを通信する技術。
    • WebRTCの通信方式として使用される。
  • ソケット通信
    • 通信プロトコルの1つ。サーバーは必要。
    • P2Pが確立する前にPC間で情報を交換する通信手段として使用。

ソケット通信の開始

ソケット通信は”UV4Lを使う(2)”の簡略化したコードの98行で”ws”として宣言されています。

  • 98行: ws = new WebSocket(protocol + ‘//raspberrypi.local:8090/stream/webrtc’);

第一引数の相手先URLですが、’ws://raspberrypi.local:8090/stream/webrtc’ となります。これはUV4L内のパスです。どうもUV4Lがソケット通信用のサーバーを管理している様です。

P2Pの開始

P2Pを開始する関すは、”UV4Lを使う(2)”の簡略化したコードの28行で、function createPeerConnection()と定義されています。これは、97行の ws.onopen = function () 内で呼び出されています。

P2Pを確立には、Session Description Protocol (SDP)とICE Candidateを交換する必要が有ります。

  • Session Description Protocol (SDP)は以下の情報を含んでいます。
    • 通信するメディアの種類(音声、映像)、メディアの形式(コーデック)
    • IPアドレス、ポート番号
    • 暗号化の鍵 等
  • ICE Candidate
    • P2P通信を行う際に使われる通信経路の候補
    • どのような通信経路が使えるかは、お互いのネットワーク環境に依存。
    • 通信相互で経路の候補を挙げ、通信が繋がった時にその経路を使う。

SDPの交換は通常以下の様に行われます。

  • 要求元が自身のデータを作成後、相手に、”offer”としてデータを送信。
  • 送信を受けた相手は受信データを保存後、自分自身のデータを作成し、”answer”として相手側に返送

情報を交換している時点では、P2P通信は確立していません。よってお互いの通信はソケット通信(WS)を使って行われます。この処理は ”signaling” と呼ばれ、WebRTC signalingはそのマニュアルです。データの通信方法はこのマニュアルを参考に行います。 

Raspberry PIから送られて来たデータは110行目の ws.onmessage = function (evt) { で処理されます。118行のSwitch文で、メッセージの種類によって処理を分けています。PCに送られて来るメッセージが、”offer” と ”iceCandidate” の2つなので、最初に接続を要求しているのは、UV4Lの方だと分かります。

  • 119行:メッセージが ”offer” の場合
    • 120行: pc.setRemoteDescription(…….. 送られて来たSDPの登録と、”answer” の返信。
      • 最初の引数:new RTCSessionDescription(JSON.parse(data))
        •  送られて来たSDPを自身に登録
      • 次の引数:function onRemoteSdpSuccess() {
        •  SDPの登録が出来た時にこの関数が実行される。
        • 123行: addIceCandidates(); SDPの情報にIECの情報は無いはず。ここでこの関数を呼ぶのは何故? 無くてもよいのでは?
        • 125行: pc.createAnswer(function (sessionDescription) ”answer”の作成
        • 131行: ws.send(JSON.stringify(request)); 作成された”answer”を相手に返送。
  • 146行:メッセージが ”iceCandidate” の場合
    • 155行: addIceCandidates(); この部分で送られて来た ”iceCandidate” を追加しています。

Raspberry PIから”WS”を使ってメッセージが届く度にこの ”ws.onmessage” が実行されます。SDPを互いに交換し、通信経路が見つかった時点で、P2Pが確立します。ちなみにPC側からRaspberry PIへの ”iceCandidate” の送信は42行の function onIceCandidate(event) で行っていました。

WebRTCは何処に

P2Pの接続が始まった時点でWebRTCが開始したと見ても良いのですが、Streamingの設定は何処で行われいるか。HTMLコード34行の ”pc.ontrack = onTrack;” がそれです。本体は73行で定義しています。ここで、Raspberry PIから送られて来たStreamingデータをブラウザの画面に関連付けています。

ここまでの話は、全てPC側の処理に付いてです。同じような処理がRaspberry PIでも行われているはずですが、多分UV4Lの中の話になるのでソースを見る事は出来ません。実際Raspberry PIから音声と映像のStreamingが出来ているので、WebRTCのルールに合わせてPC側から音声データを送ればRaspberry PI側で音声のStreamingが出来るはずです。

今回はここまで。次回はPC側からRaspberry PI 側に音声を送って見ます。