Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
時雨堂 WebRTC SFU Sora 開発ログ

時雨堂 WebRTC SFU Sora 開発ログ

日時:2017-06-23
作:時雨堂
バージョン:18.1.0
url:https://sora.shiguredo.jp/

概要

時雨堂 で開発/販売中の WebRTC SFU の開発ログです。

WebRTC SFU Sora

興味がある方は sora at shiguredo.jp までご連絡ください

時雨堂ノハナシ

Medium にて WebRTC SFU Sora についての技術的な記事を公開しています。是非覗いてみてください。

https://medium.com/shiguredo

Anzu

Sora の配信や録画機能を簡単に体験できるサービスを提供しています。

GitHub のアカウントがあればすぐに体験可能ですので、是非体験してみてください。

WebRTC SFU as a Service Anzu

また、 API を利用することで Web サイトに配信される映像を埋め込んだりすることができます。

リアルタイム配信

WebRTC はその名の通り、リアルタイムが強みです。リアルタイムとは遅延が 1 秒未満を想定しています。 もちろん、回線性能に寄って異なりますができる限り遅延を抑えた配信方式です。

リアルタイム動画配信コトハジメ

SFU

SFU は Selective Forwarding Unit の略で、簡単に言えば SFU というサーバが動画を配信者に変わって複数の視聴者に配信してくれる仕組みです。

配信者は Chrome や Firefox 、さらには iOS や Android といった WebRTC クライアントへの対応を目標とします。

SFU は動画を再変換せず配信するため、サーバを経由したとしても遅延をほとんど感じることはありません。

1:N

SFU を利用すれば 1:N の配信を気軽に行う事ができます。

                      / -> WebRTC -> 視聴者
                      / -> WebRTC -> 視聴者
配信者 -> WebRTC -> SFU -> WebRTC -> 視聴者
                      \ -> WebRTC -> 視聴者
                      \ -> WebRTC -> 視聴者

複数人

SFU の配信機能を応用することで複数人の配信を一つの PeerConnection で利用することができます。

この機能は「マルチストリーム」と呼ばれています。つまり自分の映像を複数人に配信せず、そこは SFU に任せ、他の人の映像のみを受け取るとい仕組みです。

参加者 A <- (WebRTC) ->     <- (WebRTC) -> 参加者 D
参加者 B <- (WebRTC) -> SFU <- (WebRTC) -> 参加者 E
参加者 C <- (WebRTC) ->     <- (WebRTC) -> 参加者 F

全員がそろってから開始するため、その人の映像や音声は後から設定されます。マルチストリームを利用することで、一つの PeerConnection 上に動的に映像や音声を追加削除する仕組みがマルチストリームです。

クライアントは onaddstream や ontrack 、onremovestream のコールバックを利用し、複数人数での映像音声の仕組みを利用することができます。

参加者の詳細:

         -> 自分 A の映像       (WebRTC) ->
参加者 A <- 他の参加者 B の映像 (WebRTC) <- SFU
         <- 他の参加者 C の映像 (WebRTC) <-

さらに Sora を利用すればこの複数人数の映像を全てサーバサイドで録画することができます。

SFU をもっと詳しく知りたい方向け

WebRTC SFU コトハジメ

Edge 対応

Sora 17.04 から Edge に対応しています。Windows 10 1703 と呼ばれるバージョンの Edge は WebRTC 1.0 に対応しました。実際まだ開発版ではありますが、 1:N であれば正常に動作しております。

また、マルチストリームにブラウザが対応すれば追従させてく予定です。

Safari 対応

SOra 17.06 から Safari に対応しています。現時点では Safari Technology Preview 32 以降でのみ検証しております。Safari 11 がリリースされ次第対応していく予定です。

目的

WebRTC は映像と音声をリアルタイムに配信する仕組みです。ただ P2P の場合は大量の配信を行うことは難しくなります。 そこでサーバを経由することで遅延が少ない状態で配信を 300 人といった規模に対して配信が可能になります。

通常の WebRTC はブラウザとブラウザの間で実現する仕組みですが、サーバサイド WebRTC ではブラウザとサーバの間で WebRTC を実現します。

サーバサイドでの録画を行う場合はサーバサイドでの WebRTC スタックが無ければできません。録画以外にもスター型で WebRTC を繋ぐ場合にも必要です。

サーバでの WebRTC 可能性を探るためにフルスクラッチな WebRTC スタックを開発しています。

WebRTC SFU Sora の特徴

低遅延

WebRTC SFU Sora は低遅延を目的に作られた製品です。遅延は環境にも寄りますが基本的には 1 秒未満です。

Sora サイトのリアルタイム配信デモで是非体験してみてください https://sora.shiguredo.jp/#demo-box

無変換

WebRTC SFU は映像のコーデックなど変換を一切行わないで、複数の視聴者に映像や音声を配信する仕組みです。 変換を行わないため、サーバリソースを節約することが可能です。

さらに Sora は録画やストリーミング配信、スナップショットの作成なども全て無変換で行います。

サーバ主導

サーバ側がクライアントをコントロールし、サーバ側が色々吸収するため、クライアント側の開発コストが下がります。

またサーバ側でクライアントの切断などをコントロールしやすいため、ビジネス用途に向いています。

サーバでの録画

WebRTC SFU は映像の暗号化をいったんほどいてから配信しているため、サーバ側で映像を保存することが可能になります。

つまり好きなタイミングで配信している映像を保存可能です。

さらに変換せずその流れている映像そのままの画質で保存が可能です。VP8 + Opus または VP9 + Opus の二種類の映像を無変換で録画可能です。

無変換で録画するため、サーバのリソースを配信に集中することができます。またすぐに録画したファイルを見ることができます。

無変換録画体験

Sora の録画機能は WebRTC SFU as a Service Anzuかんたん配信機能 での録画で体験頂けます。

録画したファイルがすぐに利用できることを是非体験してみてください。

マルチストリーム

Firefox と Chrome 両方で動作するように対応済み

WebRTC では複数の映像を 1 本のセッションで束ねる マルチストリーム が Firefox/Chrome には採用されています。 この マルチストリーム を使うことで複数人からの映像を 1 本にまとめられます。

SFU を使った場合は配信は 1 つですが、視聴は複数になる事があるため、 マルチストリーム と SFU の相性はよく、今後は マルチストリーム が主流になっていくと考えています。

SFU で マルチストリーム を使うと DTLS セッションを 1 本だけ張れば良くなります。WebRTC API の onaddstream/onremovestream イベントを活用することで、参加者の通知を気軽に行えます。

動的にクライアント側の実装がとてもシンプルになります。

実際に Firefox と WebRTC SFU を使った マルチストリーム のデモを動画にしてみました。

Firefox 45 と WebRTC SFU Sora を使った マルチストリーム のデモ - YouTube

詳細は Sora のドキュメント マルチストリーム をご覧ください

マルチストリームの最大参加人数

マルチストリームでの最大参加人数は 12 名です。制限はかかっていないため最大人数は増やすことはできますが、これ以上はクライアント側が耐えられない可能性が高いです。これ以上を利用する場合は MCU の検討を想定してください。

ビットレートシェアリング

マルチストリームのビットレート指定は現在マルチストリームに upstream で参加している人数でわった値で配信するという機能です。

たとえばボットレートの指定を 1000kbps にして、そのマルチストリームに 4 名参加している場合、配信する映像のビットレートは 250kbps となります。もし 1 名参加者が減って 3 名になった場合は 333kbps となります。

マルチストリームでは全員で共有する最大で利用可能な配信ビットレートの値を指定することになります。

マルチストリームでの録画

マルチストリームでの録画を実現しました。指定したグループに対しての録画を事前に指定できます。

録画を指定してからその録画有効期限が切れるまでは、そのグループでの映像や音声は自動で録画されるようになります。

この機能を利用することで、気軽に複数人数の録画が可能になります。

さらに録画したファイルの生成が完了したタイミングや、録画が開始されたタイミングでウェブフックから通知がくるため、アプリとの連携が簡単になります。

視聴専用機能

マルチストリームで配信している映像を、映像を配信せず視聴のみで参加することができます。

この機能を使うことで同じチャネルに 4 人が参加して配信をしているのを、他の人がみるという事が可能になります。

視聴者参加機能

Chrome が最新の仕様に追従していないため Firefox のみ対応

マルチストリーム を上手く使う事で途中参加を 1 本の接続だけで実現することができるようになります。

例えば配信者が 1 名、視聴者が 50 名いたとします。その中で視聴者から配信者に対して質問をしたいという場合、 その質問している情報は配信者にも視聴者にも伝わる必要があります。

つまり一時的に配信者になり、質問が終わったら視聴者へと戻る機能です。

TURN 機能

Sora は TURN 機能を内蔵しているため、 TURN サーバを別に立てる必要がなくなります。 現時点では TURN-UDP と TURN-TCP に対応しています。今後は TURN-TLS への対応も予定しています。

TURN 機能を内蔵することで TURN 利用時に必須な認証などを全て自動で行ってくれます。また WebRTC 通信自体に認証がかからないため TURN を前提とすることで、よりセキュアに WebRTC を利用することが可能になります。

詳細は Sora のドキュメント TURN 機能 をご覧ください

TURN-TLS 払い出し機能

Sora では TURN-TLS 自体を処理する機能は搭載しません。 TURN-TLS は TURN-TCP の TLS 版です。 この機能は TURN-TLS の urls turns: を払い出すようにする機能です。

実際の TLS の処理は Nginx などを利用して前段で終端して、そのご TURN-TCP に繋ぐという仕組みです。

TCP serverをSSL/TLS化するのに nginx の stream_ssl_module/stream_proxy_module が便利 - たごもりすメモ

Sora では Nginx などを前段において貰うことを前提としています。そのため、 TLS 部分の処理も前段に任せてしまうという方針です。

シグナリング

シグナリングとはクライアントと SFU が WebRTC の通信を始めるために事前にやりとりをするための仕組みです。

どんな映像コーデックを使うのか、音声は配信するのかどうか、などを指定します。認証などもここで行います。

WebRTC でのシグナリングは仕様的には定義されていません。 Sora のシグナリングは WebSocket を利用しています。

WebSocket を使い、内部で JSON 形式での通信を行います。

詳細は Sora のドキュメント シグナリング をご覧ください

認証ウェブフック

Sora 自体は認証機能を持っていません。ただし、認証の処理を外部の認証サーバに委譲することができます。

外部への認証は Sora が HTTP 経由で設定に指定されたサーバに問い合わせます。そのため Sora がデータベース連携を行う必要がありません。

詳細は Sora のドキュメント 認証ウェブフック をご覧ください。

認証ウェブフックでの払い出し機能

Sora では認証サーバが払い出した JSON を利用することができます

  • event_metadata の指定
    • この機能はイベントフックで、接続、切断、更新時に送ってくる値をサーバ側から好きな値を指定することができます
    • 例えばプライマリキーなどを保存しておくことで、アプリ側の処理を単純かすることが可能です
    • この値は接続毎に保持し、クライアントに通知されることはありません
  • オーディオ、ビデオの設定の指定
    • サーバ側から利用するオーディオやビデオのコーデックやビットレートを指定することができます
    • チャネルで利用するコーデックを統一したい場合に利用可能です
  • ipv4_address_list や ipv6_address_list の指定
    • サーバ側から、クライアントが利用する IP アドレスのリストを送ることができます
    • これによりプライベートネットワークだけで通信して欲しい場合など、クライアントの接続をネットワークレベルでコントロールすることができるようになります

イベントウェブフック

Sora は状態の変化などを全てウェブフック経由でアプリケーションに通知します。

この Web フック機能を使うことで、アプリ側は通常の HTTP API アプリを書く事で Sora と連携することが可能になります。

詳細は Sora のドキュメント イベントウェブフック をご覧ください。

API

API は Sora が持っている HTTP API です。この API を操作することで指定したユーザを切断したり、指定したグループ全員にプッシュで情報を送るなどが利用可能になります。

詳細は Sora のドキュメント をご覧ください。

スナップショット機能

この機能はブラウザは Chrome 、映像コーデックに VP8 を選択した場合のみ利用可能です

省エネ配信機能は映像を配信する代わりに、映像のスナップショットを一定間隔で配信する仕組みです。

シグナリングで利用している WebSocket 経由で映像のスナップショットが送られてきます。

映像の場合は再生に CPU や通信のリソースを必要としますが、省エネ機能を利用した場合、スナップショットが送られてくる間隔が 10 秒だとしたら 640x480 の画像が 10 キロバイト程度ですので、実質 100 分の一違うことになります。

この機能はモバイルでも大変効果的です。 スナップショット画像と音声にすることで劇的なリソース削減が可能となります。

WebM-DASH による HTTP 経由の配信機能

この機能はブラウザは Chrome 、映像コーデックに VP8 または VP9 、音声コーデックに Opus を選択した場合にのみ利用可能です

サーバ録画機能を応用した機能です。 WebM-DASH と呼ばれる MPEG-DASH 形式で保存し、 MPD と呼ばれるプレイリストを生成することで、 ブラウザなどで視聴可能な HTTP 経由のライブストリーミングを行う事が可能になります。

WebRTC のようなプッシュ型のストリーミングではなく、HTTP 経由のプル型のストリーミングになるため、WebRTC より多くの人数に耐えることが可能になります。CDN などを利用することで同時に 10 万人への配信なども可能になります。

サーバ側では一切変換を行わないため、トランスコードと比較すると遅延も少なく、サーバへの負担もほとんどありません。

SDK

Sora には現在 JavaScript と iOS の SDK が存在しています。

JavaScript SDK と iOS SDK はマルチストリームに対応済です。クライアントから簡単にマルチストリームを利用することができます。

Android (Kotlin) の SDK は 2017 年の夏までにはリリース予定です。

SDK の有償サポートは行っておりません。 OSS で、ラインセスも Apache 2.0 にて提供している事もあり、自由に使って頂く事を想定しています。

JavaScript SDK

iOS SDK

React-Native

React-Native の SDK を提供するのは難しいため、サンプルアプリを提供しております。

SFU でのマルチストリームを利用したサンプルになっています。 ただ、まだ整理できていません。

https://github.com/shiguredo/sora-react-native-demos

Safari への配信

https://dl.dropboxusercontent.com/u/89936/webrtc_sfu/sfu_to_safari.png

Sora と FFmpeg を利用することで Safari に対しても WebRTC の映像を配信することが可能です。 FFmpeg 側で Sora から送られてきた RTP を HLS 形式に変換する仕組みです。

この機能は Sora の音声/映像の転送機能と FFmpeg を利用した機能で、 Sora 単体が持っている機能ではありません。

サンプル

これは WebRTC SFU Sora を利用して録画した映像のサンプル画像です。このサンプルには音声は含まれておりません。

https://dl.dropboxusercontent.com/u/89936/webrtc_sfu/fhd_5000k.png

コーデックは VP9 を利用し、ビットレートは 5000kbps で解像度はフル HD 、フォーマットは WebM 形式で録画しております。

映像はこちら、 26M バイト程度あります。

https://dl.dropboxusercontent.com/u/89936/8d096fb4-6fd2-40d6-9637-115062a82bc6.webm

Firefox または Chrome で録画した WebM ファイルを見ることができます。このサンプルには音声は含まれておりません。

遅延の少なさ

遅延のなさを実感して貰えるように、 Sora のサイトにてデモサービスを用意してあります。

リアルタイムな配信デモとセミナー・授業デモをお試しください。 https://sora.shiguredo.jp/#demo-box

ゴール

SFU (+TURN) 機能を持った WebRTC Live Broadcast サーバを目指します

  • 最新版の Chrome と Firefox と Edge (1703) と Safari 11 が繋がる WebRTC サーバを製品として提供します
  • サーバ経由での 1:N での映像配信を可能にします
    • SFU 1 台で WebRTC 経由で 300 の配信を可能にします
  • マルチストリーム を使用した N:N の映像配信を可能にします
    • 常に マルチストリーム 前提で動作させます
    • マルチストリームでは最大 10 人の同時配信を可能にします
    • マルチストリームでの一人当たりの利用帯域を人数関係なく固定することを可能にします
  • 常に組み込みでの TURN 経由アクセスを行います
    • Username/Credential な認証の仕組み自体は組み込みます
    • TURN 機能もサーバ側に盛り込みます
    • TURN-UDP 機能
    • TURN-TCP 機能
    • TURN-TLS 機能
  • 録画/録音機能を組み込みます
    • VP8, VP9, H.264 の録画に対応
    • WebM 形式での出力が可能
    • 音声のみの Opus または PCMU 録音機能
      • Opus は webm で PCMU は wav 形式での保存
    • Simulcast を使った複数画質を WebM 形式で録画可能
  • IPv6 対応
  • WebP を利用したスナップショット機能
    • 映像が重い場合、画像のみを表示する機能を追加します
    • WebP に変換してシグナリング経由で画像を配信します
  • WebM を利用した MPEG-DASH Live Streaming 機能
    • MPEG-DASH に利用する MPD ファイルの動的生成
  • Simulcast と帯域推定による動的な配信映像の変更を行います
    • 帯域が厳しいと判断した場合は低画質の映像を配信します
  • 音声が一定量を超えた配信者のみの映像を配信する機能
    • 方針を変える場合あり
  • クライアント SDK の提供
    • クライアント SDK はすべて Apache 2.0 ライセンスにて OSS として公開します
    • JavaScript
      • マルチストリーム対応
    • iOS (Swift)
      • マルチストリーム対応
    • Android (Kotlin)
      • マルチストリーム対応
    • C#
      • マルチストリーム対応
  • サンプルアプリの提供
    • Apache 2.0 ライセンスにて公開します
    • iOS (Swift)
    • Android (Kotlin)
    • React-Native
  • Ubuntu 16.04 on ARM64 パッケージの提供

優先度が低い機能

  • クラスタリング機能を搭載し、より多くの接続ユーザに耐えられる仕組み
  • 音声変換機能

実装しない機能

  • P2P 経由への対応
  • メディアチャネルのみの実装とし、データチャネルのスタックは実装しません
    • データチャネルの実装が QUIC ベースになった場合は検討します
  • HLS へのトランスコード配信機能
    • iOS が H.264/AAC|MP3 以外の配信に対応したら検討します
    • 外部に RTP だけを出力し FFmpeg でその機能を実現できるようにします
  • 映像トランスコード機能
  • 映像合成機能
  • ファイルアップロード機能
  • WebM 形式以外のファイルの出力機能
  • 独自の認証機能

動作環境

CPU

  • x86_64
  • ARM64
    • OS は Ubuntu 16.04 固定です

OS

Linux のみに対応します

  • Ubuntu 14.04 64bit
    • Ubuntu 18.04 リリースのタイミングでサポートから外れる予定です
  • Ubuntu 16.04 64bit
  • CentOS 6.9 64bit
    • CentOS 8.x リリースのタイミングでサポートから外れる予定です
  • CentOS 7.3 64bit

ブラウザ

最新の安定版ブラウザのみに対応します

  • Chrome M58 ~
  • Firefox 53 ~
  • Windows 10 Creators Update 適用済 Edge

最新のブラウザのみ動作を保証します。

要求スペック

コア数:100 ユーザで 4 コア以上
メモリ:100 ユーザで 2G 以上
  • 800Kbps のビットレート指定で映像と音声を配信する場合、暗号化/復号化の処理に最低でも 1 ユーザあたり 1 コアを 100% として 2-4% を使用します
    • 映像と音声は別世界と考えてもらえればよいです。それぞれに暗号化/復号化が発生します
  • Generic NACK という再送機能のため、サーバ側で RTP パケットをキャッシュしているため、ユーザが増える分だけメモリが必要です
    • 1 パケット 1400 バイトで 1 ユーザあたり 1000 パケットキャッシュしています。
    • 1 ユーザあたり 14M 程度キャシュにメモリを使用します

現状

接続試験

あくまで接続検証試験のため、最大値を保証するものではありません

この試験はシグナリング機能を省略したシミュレータを利用した試験で実際にブラウザを接続した試験ではありません

検証環境はグローバルで、 Packet の ARM64 サーバ (96 コア / 128G) を利用しました。

Chrome 56 または Firefox 51 にて 800kbps で 1:500 の映像のみ配信 x 8 の合計 4000 接続に成功しています。

https://dl.dropboxusercontent.com/u/89936/webrtc_sfu/arm64_4000.png

連続稼働

連続した安定的な配信を可能にします。 1 ヶ月以上の連続配信を実現します。

パケットロストした RTP パケットを再取得する Generic-NACK 機能に対応しており、画質を安定して配信することが可能です。

リリースノート

正式版は以下をご覧ください

https://sora.shiguredo.jp/doc/RELEASE_NOTE.html

ロードマップ

ブラウザの追従は Chrome/Firefox/Edge リリースのタイミングにて確認し、 動作しない場合は早急に修正版をリリースします。

17.08

8 月末リリース予定

新機能よりもブラウザへの追従と安定性を重視していきます

SDK

  • Android SDK 1.0.0 リリース
    • iOS SDK 1.x と同等の機能を提供予定
  • iOS SDK 外部フレーム取り込み機能追加
    • 2.0.0 としてリリース予定

ライセンス

パッケージライセンス

ライセンスは 1 年間毎での更新となります。

WebRTC SFU Sora は時雨堂が1から開発したパッケージ製品です。自社のサーバにインストールしてご利用頂けます。

採用事例を許可いただく前提で 100 同時 接続利用可能なライセンスが 60 万円/年でご利用頂けます。

ライセンス費用の詳細につきましては、 https://sora.shiguredo.jp/price をご確認ください。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment