「P2P音映像通信システム」WebRTCにおけるSDPの詳細解説

1. SDPの概要

1.1 SDPとは何か

SDP (Session Description Protocol)は「セッション記述プロトコル」の略称です。簡単に言えば、SDPは人々が電話をかける前に交換する「名刺」のようなもので、相手にどのような機能をサポートし、どの方法で通信するかを伝えます。

1.2 WebRTCにおけるSDPの役割

WebRTCビデオ通話において、SDP交換は次のプロセスを経て行われます:

  • 発信側がOfferを作成
  • Offerが信令サーバーを介して受信側に送信
  • 受信側がAnswerを作成
  • Answerが発信側に送信される
  • 両者がSDP情報に基づいてP2P接続を確立

1.3 SDPの4つの主要な役割

  1. メディアネゴシエーション - 双方がどのフォーマットを使用して通信するか
  2. ネットワークネゴシエーション - 双方がどのように相手を見つけるか
  3. セキュリティネゴシエーション - 通信の安全性をどのように確保するか
  4. 能力ネゴシエーション - 双方が何ができるか

2. SDPの構造の詳細

2.1 SDP全体構造

SDPは「セッションレベル」と「メディアレベル」の2つの主要な部分で構成されます:

  • セッションレベル: 通話全体の基本情報を記述
  • メディアレベル: 特定のオーディオまたはビデオストリームを記述

2.2 SDP行タイプの詳細

SDPの各行は特定の意味を持つ「タイプ=値」の形式です:

タイプ 名称 簡単な説明 必須
v= バージョン SDPのバージョン番号 必須
o= 発信元 セッションの発信者情報 必須
s= セッション名 セッションの名前 必須
t= タイミング セッションの開始と終了時間 必須
m= メディア記述 メディアタイプとコーデック 必須

2.3 完全なSDP例の解析

以下に実際のSDP例を示し、各行を詳細に解説します:

v=0
o=- 1234567890 1234567890 IN IP4 192.168.1.100
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS localStream

m=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:abcd
a=ice-pwd:abcdefghijklmnopqrstuvwx
a=ice-options:trickle
a=fingerprint:sha-256 12:34:56:78:90:AB:CD:EF...
a=setup:actpass
a=mid:0
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
a=ssrc:12345678 cname:user1
a=ssrc:12345678 msid:localStream audioTrack

m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 124 125
a=mid:1
a=rtpmap:96 VP8/90000
a=rtpmap:100 H264/90000
a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=ssrc:87654321 cname:user1
a=ssrc:87654321 msid:localStream videoTrack

3. 主要なSDPフィールドの詳細

3.1 セッションレベルフィールド

v= (バージョン)

v=0

SDPプロトコルのバージョン番号。現在は常に0です。

o= (発信元)

o=<username>   <nettype> <addrtype> 

セッションの発信者情報を示します。

a=group:BUNDLE

a=group:BUNDLE 0 1

オーディオ(mid:0)とビデオ(mid:1)を同じ接続にバンドルします。

3.2 メディアレベルフィールド

m= (メディア)

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

メディアタイプ、ポート、プロトコル、サポートされるコーデックを指定します。

a=ice-ufrag / a=ice-pwd

a=ice-ufrag:abcd
a=ice-pwd:abcdefghijklmnopqrstuvwx

ICE接続認証のためのユーザー名とパスワードです。

a=fingerprint

a=fingerprint:sha-256 12:34:56:78:90:AB:CD:EF...

DTLS証明書のハッシュ値で、接続の安全性を確認します。

a=sendrecv / sendonly / recvonly

a=sendrecv    // 双方向通信
a=sendonly    // 送信のみ
a=recvonly    // 受信のみ

メディアストリームの方向を指定します。

3.3 コーデック関連フィールド

a=rtpmap

a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>]

Payload Typeを特定のコーデックにマッピングします。

a=fmtp

a=fmtp:<payload type> <format specific parameters>

コーデックの詳細な設定パラメータを指定します。

4. Offer/Answerモデル

4.1 Offer/Answerとは

Offer/AnswerはSDP交換の標準モデルで、2つのデバイスがどのように通信するかをネゴシエートするプロセスです。

4.2 Offer/Answerの詳細な流れ

  1. 発信側がcreateOffer()を呼び出してOfferを作成
  2. 発信側がsetLocalDescription()を呼び出してローカル記述を設定
  3. Offerが受信側に送信される
  4. 受信側がsetRemoteDescription()を呼び出してリモート記述を設定
  5. 受信側がcreateAnswer()を呼び出してAnswerを作成
  6. 受信側がsetLocalDescription()を呼び出してローカル記述を設定
  7. Answerが発信側に送信される
  8. 発信側がsetRemoteDescription()を呼び出してリモート記述を設定

4.3 OfferとAnswerの主な違い

td>共通のコーデックを1つ選択
項目 Offer Answer
コーデックリスト サポートされるすべてのコーデックをリスト
DTLSロール a=setup:actpass(ロール未定) a=setup:activeまたはa=setup:passive(ロール確定)

5. SDPタイプの判定

5.1 SDPがOfferかAnswerかを判定する方法

fun parseSdpType(sdp: String): String {
    return if (sdp.contains("a=setup:actpass")) "offer" else "answer"
}

原理:Offerには"a=setup:actpass"が含まれ、Answerには"a=setup:active"または"a=setup:passive"が含まれます。

5.2 SDPの検証

fun validateSdp(sdp: String): Boolean {
    if (sdp.isEmpty()) {
        Log.e(TAG, "[sdp] SDP内容が空です")
        return false
    }
    
    if (!sdp.contains("v=")) {
        Log.e(TAG, "[sdp] SDP形式が無効です。バージョン行がありません")
        return false
    }
    
    return true
}

6. コーデックの詳細

6.1 オーディオコーデック

コーデック Payload Type サンプリングレート 特徴
Opus 111 48kHz 高品質、ビットレート自動調整
PCMU 0 8kHz G.711 μ-law、北米標準
PCMA 8 8kHz G.711 A-law、欧州標準

6.2 ビデオコーデック

コーデック Payload Type 特徴 推奨シーン
VP8 96 オープンソース、ソフトウェアエンコード効率が高い 一般的なシーン
H.264 100 ハードウェアアクセラレーションサポート良好、モバイルフレンドリー モバイルデバイス

6.3 コーデックネゴシエーションプロセス

発信側がサポートするコーデックのリストをOfferに含め、受信側が共通のコーデックを選択してAnswerで返信します。

7. SDPとICEの関係

7.1 ICE候補者のSDPでの表現

a=candidate:<foundation>  <transport> <priority>  <port> typ  [raddr  rport ]

ICE候補者のタイプ:

  • host: ローカルアドレス(LAN IP)
  • srflx: サーバーリフレクションアドレス(グローバルIP)
  • relay: リレーアドレス(TURNサーバー)

7.2 Trickle ICE

Trickle ICEは、ICE候補者が収集されるたびに段階的に送信する方式で、接続確立を高速化します。

a=ice-options:trickle

8. SDPの再ネゴシエーション

8.1 再ネゴシエーションが必要な場合

  • メディアトラックの追加/削除
  • メディア方向の切り替え
  • ICEの再起動(ネットワーク切り替え時)
  • 画面共有の開始/停止

8.2 再ネゴシエーションプロセス

再ネゴシエーションのプロセスは初期ネゴシエーションと同じOffer/Answerモデルに従います。

9. SDPデバッグ手法

9.1 SDPログの読み方

SDPログを確認する際の重要なポイント:

  • コーデックネゴシエーションの結果
  • ICE認証情報
  • DTLS設定
  • メディア方向

9.2 一般的な問題のトラブルシューティング

  • ビデオが再生されない:コーデックネゴシエーションの失敗
  • ICE接続がCHECKING状態のまま:ICE候補者の交換に問題
  • DTLS接続の失敗:フィンガープリントの不一致
  • 相手が音声を聞けない:メディア方向の設定エラー

10. SDPのベストプラクティス

10.1 処理に関する推奨事項

  • SDPを手動で変更しない
  • SDP交換の順序を正しく処理する
  • ICE候補者を適切なタイミングで処理する
  • 再ネゴシエーションを実装する

10.2 パフォーマンスの最適化

  • BUNDLEを使用する
  • Trickle ICEを使用する
  • 適切なコーデックを選択する
  • RTCPフィードバックを有効にする

11. 参考資料

11.1 関連RFCドキュメント

RFC番号 タイトル 説明
RFC 4566 SDP: Session Description Protocol SDPプロトコル仕様
RFC 3264 An Offer/Answer Model with SDP Offer/Answerモデル
RFC 5245 Interactive Connectivity Establishment (ICE) ICEプロトコル

11.2 プロジェクト関連ファイル

td>WebRTCクライアント、Offer/Answerの作成と処理を含む
ファイルパス 説明
SdpManager.kt SDP管理、検証、タイプ判定、キャッシュ処理を含む
WebRTCClient.kt
IceCandidateManager.kt ICE候補者管理

タグ: WebRTC SDP P2P 音映像通信 Offer/Answer

5月20日 10:14 投稿