SDP
SDP (Session Description Protocol, RFC 8866) — текстовый формат для описания медиа-сессий: какие потоки, какие кодеки, какие IP/порты, какие ключи шифрования. Используется в SIP-телефонии, WebRTC, RTSP, MulticastDNS-Service Discovery.
Формат
Одно поле на строку, формат <буква>=<значение>. Порядок фиксированный.
v=0
o=alice 2890844526 2890842807 IN IP4 host.example.com
s=Session Name
c=IN IP4 192.0.2.1
t=0 0
m=audio 49170 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
m=video 51372 RTP/AVP 99
a=rtpmap:99 VP8/90000
Обязательные поля
| Поле | Расшифровка | Пример |
|---|---|---|
| v= | Version (всегда 0) | v=0 |
| o= | Origin: имя, session-id, session-version, netType, addrType, addr | o=alice 2890844526 2890842807 IN IP4 host |
| s= | Session name (может быть " ") | s=WebRTC Call |
| t= | Timing: start/stop (0 0 = вечно) | t=0 0 |
Медиа-строка
m=<тип> <порт> <протокол> <форматы>
m=audio 49170 RTP/AVP 0 8
│ │ │ │
│ │ │ └── payload types (0=PCMU, 8=PCMA)
│ │ └────────── RTP/AVP = RTP + Audio-Video Profile
│ └───────────────── UDP-порт
└──────────────────────── audio | video | text | application
Attributes (a=)
Основной способ описать что угодно:
| Атрибут | Что |
|---|---|
a=rtpmap:99 VP8/90000 | Формат payload-type 99 = VP8 с clock 90000 |
a=fmtp:99 max-fr=30 | Параметры формата |
a=sendrecv / a=sendonly / a=recvonly / a=inactive | Направление потока |
a=setup:actpass | DTLS role: active/passive/actpass |
a=fingerprint:sha-256 ... | Отпечаток DTLS-сертификата |
a=ice-ufrag / a=ice-pwd | ICE credentials |
a=candidate:... | ICE-кандидат |
a=mid:0 | Media ID (для группировки) |
a=msid:... | MediaStream ID |
a=ssrc:12345 cname:... | RTP synchronization source |
a=rtcp-mux | RTP и RTCP на одном порту |
a=extmap:... | RTP header extensions |
Пример полного WebRTC offer
v=0
o=- 1234567890 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS stream1
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:F7gI
a=ice-pwd:x9cml/YzichV2+XlhiMu8g
a=fingerprint:sha-256 42:E5:...:FA
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:1001 cname:user1@example.com
m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:F7gI
a=ice-pwd:x9cml/YzichV2+XlhiMu8g
a=fingerprint:sha-256 42:E5:...:FA
a=setup:actpass
a=mid:1
a=sendrecv
a=rtcp-mux
a=rtpmap:96 VP8/90000
a=ssrc:1002 cname:user1@example.com
Offer/Answer
SDP используется через offer/answer model (RFC 3264). Одна сторона делает offer, другая отвечает answer с пересечением возможностей:
- Alice предлагает: «умею Opus и G.722, VP8 и VP9».
- Bob отвечает: «выбрал Opus и VP8».
Оба используют финальный список.
BUNDLE
Все медиа-потоки (audio, video, data) через один ICE-транспорт и один DTLS. Экономит на ICE/DTLS handshake и NAT-hole-punching.
a=group:BUNDLE audio video data
Trickle ICE
Классический SDP включает все ICE-кандидаты в offer/answer. Trickle ICE (RFC 8838) — шлём offer/answer без кандидатов, а потом обмениваемся ими через сигналинг по мере обнаружения. Быстрее старт соединения.
Плюсы и минусы
- Плюс: универсально, читаемо, гибко.
- Минус: сложно. Многие атрибуты, порядок важен, парсеры полны багов.
- WebRTC-приложения часто «munge» SDP — правят строчки регуляркой перед setLocalDescription (форсировать кодек, битрейт).
Munging пример
// Форсировать Opus stereo и максимальный битрейт
offer.sdp = offer.sdp.replace(
/a=fmtp:111 (.*)/,
'a=fmtp:111 $1;stereo=1;maxaveragebitrate=128000'
);
Альтернативы
SDP старый и клакозубистый. Есть попытки заменить:
- JSEP — обёртка WebRTC над SDP, тоже говно.
- Ordered Sessions — предложение W3C, не взлетело.
Пока живём с SDP.