T-CREATOR

WebRTC SDP 用語チートシート:m=・a=・bundle・rtcp-mux を 10 分で総復習

WebRTC SDP 用語チートシート:m=・a=・bundle・rtcp-mux を 10 分で総復習

WebRTC でリアルタイム通信を実装する際、SDP(Session Description Protocol)の仕様に直面して戸惑った経験はありませんか?ピア間で交換される SDP には、m=a=bundlertcp-mux といった専門用語が数多く登場します。これらの用語を正確に理解することで、WebRTC の接続トラブルシューティングや最適化がスムーズになるでしょう。本記事では、SDP の主要用語を 10 分で総復習できるよう、わかりやすく解説していきます。

SDP 用語早見表

#用語正式名称役割主な使用例
1m=Media Descriptionメディアストリームの種類・ポート・プロトコルを定義m=audio 9 UDP​/​TLS​/​RTP​/​SAVPF 111 103
2a=Attributeメディアやセッションの属性を指定a=rtpmap:111 opus​/​48000​/​2
3bundleBUNDLE複数のメディアストリームを 1 つのトランスポートに統合a=group:BUNDLE audio video
4rtcp-muxRTCP MultiplexingRTP と RTCP を同じポートで多重化a=rtcp-mux
5c=Connection Data接続情報(IP アドレス)を記述c=IN IP4 192.0.2.1
6rtpmapRTP Payload Type Mappingペイロードタイプとコーデックの対応付けa=rtpmap:96 VP8​/​90000
7fmtpFormat Parametersコーデック固有のパラメータを指定a=fmtp:111 minptime=10

背景

SDP とは何か

SDP(Session Description Protocol)は、マルチメディアセッションを記述するための標準プロトコルです。

WebRTC では、ピア間でメディア情報やネットワーク情報を交換する際に SDP を使用します。SDP は RFC 4566 で定義されており、セッションの開始、変更、終了を管理するための情報を含んでいますね。

WebRTC における SDP の役割

WebRTC では、2 つのピアがリアルタイム通信を確立する前に、お互いの対応するコーデック、ネットワークアドレス、メディアの種類などを知る必要があります。

この情報交換のプロセスを「シグナリング」と呼び、SDP がその中心的な役割を果たします。各ピアは Offer SDP と Answer SDP を交換することで、通信に必要な設定を合意するのです。

以下の図で、WebRTC におけるシグナリングフローと SDP の役割を示します。

mermaidsequenceDiagram
    participant A as ピア A
    participant S as シグナリング<br />サーバー
    participant B as ピア B

    A->>A: createOffer()
    A->>A: setLocalDescription()
    A->>S: Offer SDP 送信
    S->>B: Offer SDP 転送
    B->>B: setRemoteDescription()
    B->>B: createAnswer()
    B->>B: setLocalDescription()
    B->>S: Answer SDP 送信
    S->>A: Answer SDP 転送
    A->>A: setRemoteDescription()

    A->>B: メディアストリーム確立
    B->>A: メディアストリーム確立

この図から、SDP が Offer と Answer の形で交換され、最終的にメディアストリーム確立に至ることがわかります。

SDP の基本構造

SDP は行ベースのテキスト形式で記述されます。各行は <type>=<value> の形式を取り、type は 1 文字の識別子です。

主要な行タイプには以下のようなものがあります。

#タイプ名称スコープ必須
1v=Versionセッション
2o=Originセッション
3s=Session Nameセッション
4c=Connection Dataセッション/メディア
5t=Timingセッション
6m=Media Descriptionメディア
7a=Attributeセッション/メディア

これらの行が組み合わさって、完全な SDP ドキュメントを構成します。

課題

SDP の複雑さによる開発障壁

WebRTC を初めて扱う開発者にとって、SDP の仕様は非常に複雑で理解しづらいものです。

数十行にわたる SDP テキストには、暗号的な略語や数値が並んでおり、どの部分が何を意味するのか直感的にはわかりません。特にデバッグ時に SDP の内容を確認する必要がある場合、用語の意味を理解していないと問題の特定が困難になるでしょう。

m= 行の解釈の難しさ

m= 行は SDP の中でも特に重要な情報を含みますが、その構文は初見では理解しにくいものです。

例えば m=audio 9 UDP​/​TLS​/​RTP​/​SAVPF 111 103 104 という行を見ても、各要素が何を表しているのか、数値の意味は何なのかが即座にはわかりません。これらの情報を正しく解釈できないと、コーデックの選択やトランスポート設定の問題を診断できませんね。

属性行(a=)の多様性

a= で始まる属性行には、数十種類もの異なる属性が存在します。

rtpmapfmtpice-ufragfingerprintsetupmidextmap など、それぞれが異なる役割を持っており、どの属性がどのような目的で使われるのかを把握するのは容易ではありません。特に、セッションレベルとメディアレベルで異なるスコープを持つ属性の使い分けは混乱を招きやすいです。

BUNDLE と rtcp-mux の必要性の理解

現代の WebRTC 実装では、BUNDLErtcp-mux がほぼ必須の機能となっています。

しかし、なぜこれらの機能が必要なのか、使わないとどのような問題が発生するのかを理解していないと、SDP の設定を適切に行えません。特に、NAT トラバーサルやファイアウォールの問題、帯域幅の効率化といった実践的な観点から、これらの機能の重要性を理解する必要があるでしょう。

以下の図で、BUNDLE を使わない場合と使う場合の違いを示します。

mermaidflowchart TB
    subgraph without["BUNDLE なし"]
        audio1["音声ストリーム"] -->|ポート 10000| ice1["ICE 候補 1"]
        video1["映像ストリーム"] -->|ポート 10002| ice2["ICE 候補 2"]
        data1["データストリーム"] -->|ポート 10004| ice3["ICE 候補 3"]
    end

    subgraph with["BUNDLE あり"]
        audio2["音声ストリーム"] -->|ポート 10000| ice4["ICE 候補 1"]
        video2["映像ストリーム"] -->|ポート 10000| ice4
        data2["データストリーム"] -->|ポート 10000| ice4
    end

BUNDLE を使うことで、複数のメディアストリームを 1 つのトランスポートに統合でき、ICE 候補の数を大幅に削減できます。

解決策

m= 行の詳細解説

m= 行はメディア記述行と呼ばれ、各メディアストリームの基本情報を定義します。

m= 行の構文

m= 行の基本構文は以下の通りです。

textm=<media> <port> <proto> <fmt> ...

各要素の意味を表で整理します。

#要素説明
1mediaメディアタイプaudio, video, application
2portポート番号9(BUNDLE 使用時)、実際のポート番号
3protoトランスポートプロトコルUDP/TLS/RTP/SAVPF
4fmtフォーマット(ペイロードタイプ)のリスト111 103 104

実例での解説

実際の SDP から m= 行を見てみましょう。

sdpm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104

この行を要素ごとに分解すると、以下のようになります。

  • media: audio(音声メディア)
  • port: 9(BUNDLE を使用するため、実際のポートではなくプレースホルダー)
  • proto: UDP​/​TLS​/​RTP​/​SAVPF(DTLS-SRTP を使用した RTP)
  • fmt: 111 103 104(対応するペイロードタイプのリスト)

ペイロードタイプ(111、103、104)は、後続の a=rtpmap: 行でコーデックにマッピングされます。

トランスポートプロトコルの種類

WebRTC では、主に以下のトランスポートプロトコルが使用されます。

#プロトコル説明セキュリティ
1UDP/TLS/RTP/SAVPFDTLS-SRTP での暗号化 RTP
2TCP/TLS/RTP/SAVPFTCP 上での DTLS-SRTP
3UDP/DTLS/SCTPデータチャネル用

現代の WebRTC では、セキュリティのため SAVPF(Secure Audio Video Profile with Feedback)が標準となっています。

a= 行の主要属性解説

属性行(a=)は、セッションやメディアに関する追加情報を提供します。

rtpmap 属性

rtpmap は、ペイロードタイプとコーデックを対応付ける最も重要な属性の 1 つです。

sdpa=rtpmap:111 opus/48000/2

この行の構成要素を解説します。

  • 111: ペイロードタイプ(動的ペイロードタイプ)
  • opus: コーデック名
  • 48000: サンプリングレート(Hz)
  • 2: チャンネル数

Opus コーデックが 48kHz のサンプリングレートで、ステレオ(2 チャンネル)で使用されることを示しています。

fmtp 属性

fmtp(Format Parameters)は、コーデック固有のパラメータを指定します。

sdpa=fmtp:111 minptime=10;useinbandfec=1

この例では、ペイロードタイプ 111(Opus)に対して以下のパラメータを設定しています。

  • minptime=10: 最小パケット時間を 10ms に設定
  • useinbandfec=1: インバンド FEC(前方誤り訂正)を有効化

これらのパラメータにより、ネットワークの品質に応じた最適化が可能になりますね。

candidate 属性

candidate 属性は、ICE(Interactive Connectivity Establishment)の候補を記述します。

sdpa=candidate:1 1 udp 2130706431 192.168.1.10 54321 typ host

各フィールドの意味は以下の通りです。

#フィールド説明
1foundation1候補の基盤識別子
2component1コンポーネント ID(1=RTP, 2=RTCP)
3transportudpトランスポートプロトコル
4priority2130706431優先度
5address192.168.1.10IP アドレス
6port54321ポート番号
7typehost候補タイプ(host/srflx/relay)

fingerprint 属性

fingerprint は、DTLS ハンドシェイクで使用される証明書のフィンガープリントです。

sdpa=fingerprint:sha-256 A1:B2:C3:D4:E5:F6:...

SHA-256 ハッシュアルゴリズムで計算された証明書のフィンガープリントを示し、セキュアな通信を確立します。

その他の重要な属性

以下の表で、その他の重要な属性をまとめます。

#属性説明
1midメディア識別子(BUNDLE で使用)a=mid:audio
2ice-ufragICE ユーザー名フラグメントa=ice-ufrag:F7gI
3ice-pwdICE パスワードa=ice-pwd:x9cml...
4setupDTLS の役割a=setup:actpass
5sendrecvメディアの方向a=sendrecv
6extmapRTP 拡張a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level

BUNDLE の詳細と利点

BUNDLE は、複数のメディアストリームを 1 つのトランスポート接続にまとめる技術です。

BUNDLE の仕組み

BUNDLE を使用すると、音声、映像、データチャネルなどの異なるメディアタイプを、単一の UDP ポートペアで送受信できます。

これは a=group:BUNDLE 属性で指定されます。

sdpa=group:BUNDLE audio video

この行は、audiovideo という 2 つのメディアストリームを BUNDLE グループにまとめることを示しています。

BUNDLE の利点

BUNDLE を使用する主な利点を以下にまとめます。

1. ICE 候補の削減

BUNDLE を使わない場合、各メディアストリームごとに個別の ICE 候補を収集する必要があります。

音声、映像、データの 3 つのストリームがあれば、3 倍の ICE 候補が必要になり、接続確立時間が大幅に増加してしまいますね。BUNDLE を使うことで、1 つの ICE 候補セットで全メディアを処理できるでしょう。

2. NAT トラバーサルの効率化

多くのファイアウォールや NAT は、開けるポート数に制限を設けています。

BUNDLE により必要なポート数を最小限に抑えることで、NAT トラバーサルの成功率が向上します。特に企業ネットワークなどの厳格な環境で効果を発揮しますね。

3. 帯域幅の効率化

各トランスポートには、DTLS ハンドシェイクや STUN/TURN のオーバーヘッドが発生します。

BUNDLE により単一のトランスポートを共有することで、これらのオーバーヘッドを削減し、実際のメディアデータに利用できる帯域幅を増やせるでしょう。

mid 属性との関係

BUNDLE を使用する場合、各メディアストリームには mid(Media ID)が割り当てられます。

sdpm=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:audio

m=video 9 UDP/TLS/RTP/SAVPF 96
a=mid:video

受信側は、RTP ヘッダーの拡張フィールドに含まれる mid 値を見て、どのメディアストリームのパケットかを識別します。

rtcp-mux の詳細と利点

rtcp-mux は、RTP(Real-time Transport Protocol)と RTCP(RTP Control Protocol)を同じポートで多重化する技術です。

rtcp-mux の仕組み

従来、RTP と RTCP は別々のポートを使用していました(例:RTP がポート 5000、RTCP がポート 5001)。

rtcp-mux を有効にすると、両方のプロトコルが同じポートを使用するようになります。

sdpa=rtcp-mux

この単純な 1 行の属性により、ポートの使用が半減します。

RTP と RTCP の識別方法

同じポートで RTP と RTCP を区別するため、パケットタイプフィールドが使用されます。

RTP のペイロードタイプ範囲と RTCP のパケットタイプ範囲は重複しないよう設計されており、受信側は最初のバイトを見てパケットタイプを判別できるのです。

rtcp-mux の利点

rtcp-mux の主な利点を整理します。

1. ポート消費の削減

各メディアストリームで必要なポート数が半分になります。

これにより、NAT やファイアウォールでの設定が簡素化され、ポート枯渇の問題も軽減されますね。

2. ICE の効率化

rtcp-mux を使用すると、RTCP 用の ICE 候補を収集する必要がなくなります。

BUNDLE と組み合わせることで、複数のメディアストリームを持つセッションでも、最小限の ICE 候補で済むでしょう。

3. 対称 NAT での接続性向上

対称 NAT 環境では、異なるポートからのトラフィックが異なる外部ポートにマッピングされます。

RTP と RTCP が同じポートを使用することで、NAT マッピングの一貫性が保たれ、接続性が向上するのです。

具体例

完全な SDP の例と解説

実際の WebRTC セッションで生成される SDP の例を見ながら、これまで学んだ用語を確認しましょう。

セッションレベルの情報

まず、セッションレベルの基本情報から始まります。

sdpv=0
o=- 1234567890 2 IN IP4 127.0.0.1
s=-
t=0 0

各行の意味は以下の通りです。

  • v=0: SDP のバージョン(常に 0)
  • o=: セッションの発信者情報(ユーザー名、セッション ID、バージョン、アドレス)
  • s=-: セッション名(WebRTC では通常 - を使用)
  • t=0 0: セッションの開始時刻と終了時刻(0 0 は永続セッションを意味)

BUNDLE グループの定義

次に、BUNDLE グループを定義します。

sdpa=group:BUNDLE audio video
a=msid-semantic: WMS stream-id

これにより、audio と video メディアが 1 つのトランスポートにバンドルされます。

ICE 関連の属性

ICE(Interactive Connectivity Establishment)に関する属性を設定します。

sdpa=ice-ufrag:F7gI
a=ice-pwd:x9cml+wNNBMNJTHJKT5qlA
a=ice-options:trickle
a=fingerprint:sha-256 A1:B2:C3:D4:E5:F6:G7:H8:I9:J0:K1:L2:M3:N4:O5:P6:Q7:R8:S9:T0:U1:V2:W3:X4:Y5:Z6
a=setup:actpass

各属性の役割を整理します。

  • ice-ufrag/ice-pwd: ICE 認証情報
  • ice-options: Trickle ICE をサポート(候補を段階的に送信)
  • fingerprint: DTLS 証明書のフィンガープリント
  • setup: DTLS の役割(actpass は active または passive を意味)

音声メディアの記述

音声ストリームの詳細な設定を記述します。

sdpm=audio 9 UDP/TLS/RTP/SAVPF 111 103
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=mid:audio
a=sendrecv

主要な属性の意味は以下の通りです。

  • m=audio 9: 音声メディア、ポート 9(BUNDLE のプレースホルダー)
  • a=rtcp-mux: RTP と RTCP を同じポートで多重化
  • a=mid: メディア ID として "audio" を設定
  • a=sendrecv: 双方向通信(送受信両方)

コーデックの詳細設定

次に、サポートするコーデックとそのパラメータを定義します。

sdpa=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1

これらの行では、ペイロードタイプ 111 を Opus コーデックにマッピングし、各種パラメータを設定しています。

  • rtpmap: Opus、48kHz、ステレオ
  • rtcp-fb: トランスポート全体の輻輳制御をサポート
  • fmtp: 最小パケット時間 10ms、FEC 有効化

続いて、別のペイロードタイプも定義します。

sdpa=rtpmap:103 ISAC/16000

こちらは、ペイロードタイプ 103 を ISAC コーデックにマッピングしています。

RTP 拡張の設定

RTP ヘッダー拡張により、追加の機能を提供します。

sdpa=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01

各拡張の役割は以下の通りです。

#ID拡張説明
11ssrc-audio-level音声レベルの情報
22abs-send-time絶対送信時刻
33transport-wide-ccトランスポート全体の輻輳制御

SSRC と MSID の設定

SSRC(Synchronization Source)とストリーム識別子を設定します。

sdpa=ssrc:1111111111 cname:user@example.com
a=ssrc:1111111111 msid:stream-id audio-track-id
a=ssrc:1111111111 mslabel:stream-id
a=ssrc:1111111111 label:audio-track-id

これらの属性により、メディアストリームとトラックが識別されます。

映像メディアの記述

映像ストリームも同様に記述します。

sdpm=video 9 UDP/TLS/RTP/SAVPF 96 97
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=mid:video
a=sendrecv

映像コーデックの設定を追加します。

sdpa=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli

VP8 コーデックに対して、以下のフィードバック機能を有効化しています。

  • goog-remb: Receiver Estimated Maximum Bitrate
  • transport-cc: トランスポート全体の輻輳制御
  • ccm fir: Full Intra Request(キーフレーム要求)
  • nack: Negative Acknowledgement(再送要求)
  • nack pli: Picture Loss Indication

ICE 候補の例

最後に、ICE 候補をいくつか示します。

sdpa=candidate:1 1 udp 2130706431 192.168.1.10 54321 typ host
a=candidate:2 1 udp 1694498815 203.0.113.10 54321 typ srflx raddr 192.168.1.10 rport 54321
a=candidate:3 1 udp 16777215 198.51.100.10 12345 typ relay raddr 203.0.113.10 rport 54321

3 種類の ICE 候補を示しています。

  • candidate 1: host 候補(ローカルアドレス)
  • candidate 2: srflx 候補(STUN で取得した外部アドレス)
  • candidate 3: relay 候補(TURN サーバー経由)

JavaScript での SDP 操作例

実際のコードで SDP を扱う方法を見ていきましょう。

Offer の作成と SDP の取得

まず、RTCPeerConnection を作成し、Offer を生成します。

javascript// PeerConnection の作成
const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
});

次に、メディアストリームを追加します。

javascript// メディアストリームの追加
const stream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true,
});

stream.getTracks().forEach((track) => {
  pc.addTrack(track, stream);
});

Offer SDP を作成します。

javascript// Offer の作成
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

// SDP の内容を確認
console.log('Offer SDP:', offer.sdp);

SDP の内容を変更する

SDP の内容を動的に変更することもできます。

javascript// SDP を文字列として取得
let sdp = offer.sdp;

// 特定のコーデックを優先する例(Opus を最優先)
sdp = sdp.replace(
  'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104',
  'm=audio 9 UDP/TLS/RTP/SAVPF 111'
);

ただし、SDP の手動変更は慎重に行う必要があります。誤った変更は接続の失敗を引き起こす可能性があるでしょう。

変更した SDP を適用します。

javascript// 変更した SDP で新しい SessionDescription を作成
const modifiedOffer = new RTCSessionDescription({
  type: 'offer',
  sdp: sdp,
});

await pc.setLocalDescription(modifiedOffer);

SDP のパース例

SDP から特定の情報を抽出する例を示します。

javascript// SDP から ice-ufrag を抽出
function getIceUfrag(sdp) {
  const match = sdp.match(/a=ice-ufrag:(\S+)/);
  return match ? match[1] : null;
}

const iceUfrag = getIceUfrag(offer.sdp);
console.log('ICE Username Fragment:', iceUfrag);

コーデック情報を抽出する関数も作成できます。

javascript// SDP からコーデック一覧を抽出
function getCodecs(sdp, mediaType) {
  const codecs = [];
  const lines = sdp.split('\r\n');
  let inMediaSection = false;

  for (const line of lines) {
    if (line.startsWith(`m=${mediaType}`)) {
      inMediaSection = true;
      continue;
    }

    if (inMediaSection && line.startsWith('m=')) {
      break;
    }

    if (inMediaSection && line.startsWith('a=rtpmap:')) {
      const match = line.match(/a=rtpmap:(\d+) (\S+)/);
      if (match) {
        codecs.push({
          payloadType: match[1],
          codec: match[2],
        });
      }
    }
  }

  return codecs;
}

const audioCodecs = getCodecs(offer.sdp, 'audio');
console.log('Audio Codecs:', audioCodecs);

トラブルシューティング例

SDP 関連の一般的な問題とその解決方法を見ていきましょう。

エラー: Failed to set remote answer sdp: Called in wrong state: kStable

このエラーは、PeerConnection の状態管理が適切でない場合に発生します。

javascript// 問題のあるコード例
await pc.setRemoteDescription(answer);
await pc.setRemoteDescription(answer); // エラー: 2回呼び出している

解決策として、状態を確認してから setRemoteDescription を呼び出します。

javascript// 正しいコード
if (pc.signalingState !== 'stable') {
  await pc.setRemoteDescription(answer);
}

エラー: The order of m-lines in answer doesn't match order in offer

Answer SDP の m= 行の順序が Offer と異なる場合に発生します。

Offer で m=audiom=video の順序だった場合、Answer でも同じ順序を維持する必要がありますね。

javascript// SDP の m= 行の順序を確認する関数
function getMediaOrder(sdp) {
  const lines = sdp.split('\r\n');
  const mediaTypes = [];

  for (const line of lines) {
    if (line.startsWith('m=')) {
      const mediaType = line.split(' ')[0].substring(2);
      mediaTypes.push(mediaType);
    }
  }

  return mediaTypes;
}

console.log('Offer media order:', getMediaOrder(offer.sdp));
console.log(
  'Answer media order:',
  getMediaOrder(answer.sdp)
);

コーデックネゴシエーション失敗

Offer と Answer で共通のコーデックがない場合、メディアストリームを確立できません。

javascript// SDP から対応コーデックを確認
function hasCommonCodec(offerSdp, answerSdp, mediaType) {
  const offerCodecs = getCodecs(offerSdp, mediaType);
  const answerCodecs = getCodecs(answerSdp, mediaType);

  return offerCodecs.some((oc) =>
    answerCodecs.some((ac) => ac.codec === oc.codec)
  );
}

if (!hasCommonCodec(offer.sdp, answer.sdp, 'audio')) {
  console.error('警告: 共通の音声コーデックがありません');
}

以下の図で、Offer と Answer のコーデックネゴシエーションプロセスを示します。

mermaidflowchart TD
    offer["Offer SDP<br/>対応コーデック:<br/>Opus, ISAC, PCMU"] --> negotiation["コーデック<br/>ネゴシエーション"]
    answer["Answer SDP<br/>対応コーデック:<br/>Opus, PCMU, G722"] --> negotiation

    negotiation --> common["共通コーデック:<br/>Opus, PCMU"]
    common --> select["優先度が最も高い<br/>Opus を選択"]
    select --> result["確立されたコーデック:<br/>Opus"]

コーデックネゴシエーションでは、Offer と Answer の両方でサポートされているコーデックから、優先度が最も高いものが選択されます。

まとめ

本記事では、WebRTC の SDP における主要用語について詳しく解説してきました。

m= 行は各メディアストリームの基本情報を定義し、メディアタイプ、ポート、トランスポートプロトコル、対応コーデックを指定します。a= 行は多様な属性を提供し、rtpmap、fmtp、candidate、fingerprint など、セッション確立に必要な詳細情報を記述しますね。

BUNDLE により複数のメディアストリームを 1 つのトランスポートにまとめることで、ICE 候補の削減、NAT トラバーサルの効率化、帯域幅の最適化が実現できます。rtcp-mux は RTP と RTCP を同じポートで多重化し、ポート消費を半減させ、対称 NAT 環境での接続性を向上させるでしょう。

これらの用語を理解することで、WebRTC のデバッグやトラブルシューティングが格段に容易になります。SDP は一見複雑に見えますが、各要素の役割を理解すれば、リアルタイム通信の仕組みを深く把握できるようになるのです。

今後 WebRTC を扱う際には、この記事をチートシートとして活用し、SDP の内容を正確に読み解いていただければ幸いです。

関連リンク