21
SFUの話 tnoho

SFUの話

  • Upload
    tnoho

  • View
    1.769

  • Download
    0

Embed Size (px)

Citation preview

SFUの話tnoho

自己紹介

tnoho

• 某通信会社 新卒入社3年目

• Web会議システムMCUサーバ担当

• Androidエンジニア→ Javaエンジニア

• 趣味は電子工作

WebRTCは Native Client / SFU / MCU を比較的よく調べています。

まあ、間も開いたのでおさらいから…

WebRTCは…

• リアルタイム通信をブラウザで行う技術です

• Javascriptで利用でき、映像はVideoタグから出せます

ブラウザで映像・音声通話ができるなんてすばらしい!この技術を使った新しいサービスを作ろう!

あれ?5人くらいしかつなげなくない?

問題の原因はP2Pであるゆえの通信量と負荷

• WebRTCは標準で1人当たり2Mbps• 4人でつなげば6Mbps必要

• 動画エンコードに暗号化と処理が高負荷

WebRTCを利用したサービスを作ると必ずぶつかる問題 A

C D

B

モバイル端末には特に辛い。この問題を解決するのが SFU / MCU

MCU (Multi-point Control Unit)

サーバーサイドで映像加工を行う仕組み

• メリット• PeerConnectionは一本でよい• サーバーでデコードするため異種接続可• 自動応答や動画再生も可能

• デメリット• 画質の劣化が発生する• サーバー負荷が非常に高い• Videoが結合されて送られるため、参加者ごとに別枠表示や拡大は難しい

MCU

A B C D

A B C D

デコード

エンコード

結合A B

C D

A B C D

1フレームに4人を収める

A BC D

A BC D

A BC D

A BC D

SFU (Selective Forwarding Unit)

サーバーが配信を代行する仕組み

• メリット• クライアントはSFUにだけ、映像を送ればよい• サーバー負荷がMCUに比べ非常に低い• 個別の映像で来るため、Videoタグを分けて自由なレイアウトが可能

• デメリット• デコードの数は変わらず端末負荷がある• 仕組みとして複雑なため、実装も複雑になる

MCU

A

C D

B

SFU

A

B C D

分配のみ

A A A

WebRTC接続方式の種類(まとめ)

SFU (Selective Forwarding Unit)

クライアントはサーバと通信する。上りは一本で良くなる

すべての通信がサーバを経由するためサーバの通信速度がネックになる

実装に高い理解を要する非常に難しいアーキテクチャ

表示人数分デコードするためモバイルでは多人数では負荷が高い

P2P (WebRTC自体はこれが前提)

もっとも高解像度で自由度も高い

全員と送受信するため通信量とクライアント負荷が大きい

モバイルの場合は少人数でも非常に負荷が高くなる

MCU (Multi-point Control Unit)

映像/音声をサーバで合成する。録画再生も行うこともできる

参加人数が増えても負荷や通信量が増えない(モバイルでも多人数可)

レイアウトの自由度が失われる

サーバに負荷が集中するため、そこがネックになる(高スペック要)

SFU (Selective Forwarding Unit)

P2P (WebRTC自体はこれが前提)

MCU (Multi-point Control Unit)

クライアント サーバ

クライアント サーバ

クライアント サーバ

わかりやすく書くと

商用 SFU 商用 MCU

OSS MCUOSS SFU

WebRTC SFU / MCUの代表例

このあたりはSIP向けならイロイロあります

前置きが長くなりましたが、今回はSFUの話…

SFU (Selective Forwarding Unit)サーバーが配信を代行する仕組み

SFU

A

B C D

PeerConnectionはSFUとクライアント間で張る

A A A

SFUは配信しかしない

クライアントは配信者の映像を受け取る

配信のみの場合はHLS (Http Live Streaming)が存在する

SFUの抱える問題点WebRTCは通信状況や端末負荷に応じて細かく制御されている

複数人と繋いだ場合は、一番状況の悪い人に合わせざるを得ない⇒結果、映像音声品質が悪化する (どこで切り捨てるかはSFU次第)

SFU

A

B C D

A A A

A

B

A

解像度下げてよ

パケットかけたよ

キーフレーム送って

転送だけだと全員からくるRTCP Feedback

映像品質低下を避ける技術

SFU

A B

C D

送信者 有線

WiFi携帯

SFU

A B

C D

送信者 有線

WiFi携帯

赤い電車が走ってきた。駅のホームに。汽笛をならして。

赤い電車が走ってきた。駅のホームに。汽笛をならして。

赤い電車が走ってきた。駅のホームに。

赤い電車が走ってきた。

simulcast SVC

送信者が複数サイズの映像をSFUに送る→送信者の負荷が高い

送信者がSVCコーデック映像をSFUに送る→特許技術

SFUが受信相手の状況を把握して、送るパケットを変えるしかない

MultiStream(MultiTrack)複数の映像音声を一本のPeerConnectionに入れる機能

SFU

A B

C D

SFU

A B

C D

張ってあるConnectionにメディアを追加するため、接続処理が不要

MultiStreamなし MultiStreamあり

しかし、MultiStreamの実装が難しい

今のところブラウザで挙動差異があるし、SDPも読めないといけないし…

Javascriptだけならともかく、ネイティブでまでこれをやるのは若干憂鬱…

ユーザー

PeerConnection

<video>

ユーザー

<video> <video>

ユーザー ユーザー

<video><video>

MultiStreamなし MultiStreamあり

ユーザー単位の括りではなくなる

SDP

PeerConnection

jvb-module

部屋管理

Jitsi Video Bridgeをnodeで動かす

Jitsi Video Bridge (SFU)

node

jvb module

Socket.IO

Browser

RESTful (Colibri)

WebSocket

作った

SDP解析

Colibri生成

SDP生成

Colibri解析

SSRC-ユーザー紐づけ

JVBはXMPPサーバとセットで動かす前提⇒ Socket.IOにしたかった

インターフェイス

新規参加者ダミーSDP Offer

参加者ブラウザ側処理SDP Answer解析ssrc-user紐づけColibri生成Jvb側処理Colibri解析SDP生成全員にSDP Offer

全員ブラウザ側処理新規ストリーム追加完了

Jitsi video bridgeのソースコード読んで作りました…

JVBの自主メンテはおすすめしません…

まとめ

SFU が入ってくるとWebRTCはもっと難しい

SDKで簡単に利用したい!

端末

SFU/MCUの力を借りれば非力なハードウェアでも配信することが可能になる

端末

動画エンコーダー(圧縮)

暗号化 暗号化 暗号化

B C D

通信帯域

SFU/MCU

動画エンコーダー(圧縮)ハードウェアが代行

暗号化 暗号化 暗号化

B C D

復号

暗号化

ハードウェアエンコーダー対応

WebRTC Native Library (ChromeのWebRTC部分) では

かなり対応が進んでいる(意図しなくても使えている)

• iOS ⇒ H.264 HW Encoderに対応

• Android ⇒端末依存(H.264, VP8に対応)

• RaspberryPi⇒ H.264 HW Encoder 搭載!が対応はしていない⇒というわけで、自分で書いて対応させてみた!(っていう話をどこかでしたい

これらを使えば、電池の寿命を延ばすことができる

EOF