マルチストリーム機能

概要

マルチストリームとは一つの PeerConnection の中で複数の映像や音声を動的に追加したり削除したりする仕組みです。 この機能を利用することで、複数の PeerConnection を管理せずに複数の映像や音声を使用できるようになります。

制限

  • 配信側は音声 1 トラック、映像 1 トラック固定です
  • 動的に配信側のトラックを追加したりするマルチトラックには対応していません

ブラウザ

Chrome、Firefox、Safari、Edge と主要ブラウザすべてでマルチストリームを利用できます。

シグナリング仕様

マルチストリームを利用する場合は、ユーザーが参加や離脱をするたびに SDP を交換する必要があります。

"type": "connect"

マルチストリームはデフォルトで有効になっています。

{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora"
}

マルチストリームを無効にする場合は "type": "connect" 時に "multistream": false を追加します。

{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora",
    "multistream": false
}

"type": "re-offer"

{
    "type": "re-offer",
    "sdp": ".."
}

"type": "re-answer"

"type": "re-offer" が送られてきた場合、 クライアントから Sora へ送るメッセージは "type": "re-answer" を送る必要があります。

{
    "type": "re-answer",
    "sdp": ".."
}

role

マルチストリームでは role に sendrecvsendonlyrecvonly を指定することができます。

  • sendrecv は配信と視聴を行います
  • sendonly は配信のみを行います
  • recvonly は視聴のみを行います

マルチストリームにおける映像ビットレート自動シェアリング機能

音声のビットレートには影響しません

マルチストリームでは複数の映像を大量に受信するため、 配信側の映像ビットレートを、参加している配信者全員でシェアする機能がデフォルトで有効になっています。

そのため、マルチストリームにおける video の bit_rate は、 非マルチストリームの bit_rate とは扱いが異なります。

例えば、 bit_rate を 1200 と指定した場合、 2 人で配信している場合はそれぞれ配信に 600 kbps ずつ使用します。 ここに 1 人が加わり 3 人になると、 1 人 400 kbps ずつ使用して配信するようになります。

また、ここに 5 人が加わり、合計で 8 人になると、 1 人 150 kbps ずつ使用して配信するようになります。

配信の合計のビットレートを指定するのが video の bit_rate です。

同じチャネルに参加している人が異なる bit_rate を指定した場合

2 人が同じチャネルに参加している状態で、1 人は映像のビットレートを 500 、もう 1 人は 1000 を指定して接続しているとします。 その場合、Sora では 500 を指定した人は配信に 250 kbps を使用し、 1000 を指定した人は配信に 500 kbps を使用します。

ビットレート自動シェアリング機能が適用されない条件

マルチストリームにおいても、以下の条件ではシェアされず、 bit_rate で指定した値を使います。

  • スポットライトの場合
  • サイマルキャストの場合

無効にする場合

sora.confmultistream_auto_sharing_video_bit_ratefalse に指定することで無効にできます。

シーケンス図

seqdiag { default_fontsize = 15; edge_length = 250; activation = none; === クライアント1 認証成功 === クライアント1 <<- Sora [label = '"type": "offer"']; クライアント1 ->> Sora [label = '"type": "answer"', noactivate]; === クライアント1 WebRTC 確立 === クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント1\n"type": "connection.craeted"']; === クライアント2 認証成功 === クライアント2 <<- Sora [label = '"type": "offer"']; クライアント2 ->> Sora [label = '"type": "answer"', noactivate]; クライアント1 <<- Sora [label = '"type": "re-offer"']; クライアント1 ->> Sora [label = '"type": "re-answer"', noactivate]; === クライアント2 WebRTC 確立 === クライアント2 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.craeted"']; クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.craeted"']; クライアント2 ->> Sora [label = '"type": "disconnect"', noactivate]; クライアント2 <<- Sora [label = 'WebSocket Close']; クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.destroyed"']; }