WebRTC SDP 用語チートシート:m=・a=・bundle・rtcp-mux を 10 分で総復習
WebRTC でリアルタイム通信を実装する際、SDP(Session Description Protocol)の仕様に直面して戸惑った経験はありませんか?ピア間で交換される SDP には、m=、a=、bundle、rtcp-mux といった専門用語が数多く登場します。これらの用語を正確に理解することで、WebRTC の接続トラブルシューティングや最適化がスムーズになるでしょう。本記事では、SDP の主要用語を 10 分で総復習できるよう、わかりやすく解説していきます。
SDP 用語早見表
| # | 用語 | 正式名称 | 役割 | 主な使用例 |
|---|---|---|---|---|
| 1 | m= | Media Description | メディアストリームの種類・ポート・プロトコルを定義 | m=audio 9 UDP/TLS/RTP/SAVPF 111 103 |
| 2 | a= | Attribute | メディアやセッションの属性を指定 | a=rtpmap:111 opus/48000/2 |
| 3 | bundle | BUNDLE | 複数のメディアストリームを 1 つのトランスポートに統合 | a=group:BUNDLE audio video |
| 4 | rtcp-mux | RTCP Multiplexing | RTP と RTCP を同じポートで多重化 | a=rtcp-mux |
| 5 | c= | Connection Data | 接続情報(IP アドレス)を記述 | c=IN IP4 192.0.2.1 |
| 6 | rtpmap | RTP Payload Type Mapping | ペイロードタイプとコーデックの対応付け | a=rtpmap:96 VP8/90000 |
| 7 | fmtp | Format 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 文字の識別子です。
主要な行タイプには以下のようなものがあります。
| # | タイプ | 名称 | スコープ | 必須 |
|---|---|---|---|---|
| 1 | v= | Version | セッション | ○ |
| 2 | o= | Origin | セッション | ○ |
| 3 | s= | Session Name | セッション | ○ |
| 4 | c= | Connection Data | セッション/メディア | △ |
| 5 | t= | Timing | セッション | ○ |
| 6 | m= | Media Description | メディア | ○ |
| 7 | a= | Attribute | セッション/メディア | △ |
これらの行が組み合わさって、完全な SDP ドキュメントを構成します。
課題
SDP の複雑さによる開発障壁
WebRTC を初めて扱う開発者にとって、SDP の仕様は非常に複雑で理解しづらいものです。
数十行にわたる SDP テキストには、暗号的な略語や数値が並んでおり、どの部分が何を意味するのか直感的にはわかりません。特にデバッグ時に SDP の内容を確認する必要がある場合、用語の意味を理解していないと問題の特定が困難になるでしょう。
m= 行の解釈の難しさ
m= 行は SDP の中でも特に重要な情報を含みますが、その構文は初見では理解しにくいものです。
例えば m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 という行を見ても、各要素が何を表しているのか、数値の意味は何なのかが即座にはわかりません。これらの情報を正しく解釈できないと、コーデックの選択やトランスポート設定の問題を診断できませんね。
属性行(a=)の多様性
a= で始まる属性行には、数十種類もの異なる属性が存在します。
rtpmap、fmtp、ice-ufrag、fingerprint、setup、mid、extmap など、それぞれが異なる役割を持っており、どの属性がどのような目的で使われるのかを把握するのは容易ではありません。特に、セッションレベルとメディアレベルで異なるスコープを持つ属性の使い分けは混乱を招きやすいです。
BUNDLE と rtcp-mux の必要性の理解
現代の WebRTC 実装では、BUNDLE と rtcp-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> ...
各要素の意味を表で整理します。
| # | 要素 | 説明 | 例 |
|---|---|---|---|
| 1 | media | メディアタイプ | audio, video, application |
| 2 | port | ポート番号 | 9(BUNDLE 使用時)、実際のポート番号 |
| 3 | proto | トランスポートプロトコル | UDP/TLS/RTP/SAVPF |
| 4 | fmt | フォーマット(ペイロードタイプ)のリスト | 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 では、主に以下のトランスポートプロトコルが使用されます。
| # | プロトコル | 説明 | セキュリティ |
|---|---|---|---|
| 1 | UDP/TLS/RTP/SAVPF | DTLS-SRTP での暗号化 RTP | 高 |
| 2 | TCP/TLS/RTP/SAVPF | TCP 上での DTLS-SRTP | 高 |
| 3 | UDP/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
各フィールドの意味は以下の通りです。
| # | フィールド | 値 | 説明 |
|---|---|---|---|
| 1 | foundation | 1 | 候補の基盤識別子 |
| 2 | component | 1 | コンポーネント ID(1=RTP, 2=RTCP) |
| 3 | transport | udp | トランスポートプロトコル |
| 4 | priority | 2130706431 | 優先度 |
| 5 | address | 192.168.1.10 | IP アドレス |
| 6 | port | 54321 | ポート番号 |
| 7 | type | host | 候補タイプ(host/srflx/relay) |
fingerprint 属性
fingerprint は、DTLS ハンドシェイクで使用される証明書のフィンガープリントです。
sdpa=fingerprint:sha-256 A1:B2:C3:D4:E5:F6:...
SHA-256 ハッシュアルゴリズムで計算された証明書のフィンガープリントを示し、セキュアな通信を確立します。
その他の重要な属性
以下の表で、その他の重要な属性をまとめます。
| # | 属性 | 説明 | 例 |
|---|---|---|---|
| 1 | mid | メディア識別子(BUNDLE で使用) | a=mid:audio |
| 2 | ice-ufrag | ICE ユーザー名フラグメント | a=ice-ufrag:F7gI |
| 3 | ice-pwd | ICE パスワード | a=ice-pwd:x9cml... |
| 4 | setup | DTLS の役割 | a=setup:actpass |
| 5 | sendrecv | メディアの方向 | a=sendrecv |
| 6 | extmap | RTP 拡張 | 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
この行は、audio と video という 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 | 拡張 | 説明 |
|---|---|---|---|
| 1 | 1 | ssrc-audio-level | 音声レベルの情報 |
| 2 | 2 | abs-send-time | 絶対送信時刻 |
| 3 | 3 | transport-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=audio → m=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 の内容を正確に読み解いていただければ幸いです。
関連リンク
- RFC 4566 - SDP: Session Description Protocol
- RFC 8829 - JavaScript Session Establishment Protocol (JSEP)
- RFC 8843 - Negotiating Media Multiplexing Using the Session Description Protocol (SDP)
- MDN Web Docs - RTCPeerConnection
- WebRTC 公式サイト
- RFC 5245 - Interactive Connectivity Establishment (ICE)
- RFC 3264 - An Offer/Answer Model with SDP
articleWebRTC SDP 用語チートシート:m=・a=・bundle・rtcp-mux を 10 分で総復習
articleWebRTC で自前 TURN サーバー構築:coturn を TLS/443 で堅牢運用する方法
articleWebRTC 最新動向 2025:AV1・SVC・WHIP/WHEP が変えるリアルタイム配信設計
articleWebRTC 本番運用の SLO 設計:接続成功率・初画出し時間・通話継続率の基準値
articleWebRTC が「connecting」のまま進まない:ICE 失敗を 5 分で切り分ける手順
articleWebRTC AV1/VP9/H.264 ベンチ比較 2025:画質・CPU/GPU 負荷・互換性を実測
articleZod 合成パターン早見表:`object/array/tuple/record/map/set/intersection` 実例集
articleバックアップ戦略の決定版:WordPress の世代管理/災害復旧の型
articleYarn 運用ベストプラクティス:lockfile 厳格化・frozen-lockfile・Bot 更新方針
articleWebSocket のペイロード比較:JSON・MessagePack・Protobuf の速度とコスト検証
articleWeb Components イベント設計チート:`CustomEvent`/`composed`/`bubbles` 実例集
articleWebRTC SDP 用語チートシート:m=・a=・bundle・rtcp-mux を 10 分で総復習
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来