WebRTC(七):媒體能力協商

目的

在 WebRTC 中,每個瀏覽器或終端支持的音視頻編解碼器、分辨率、碼率、幀率等可能不同。媒體能力協商的目的就是:

  • 確保雙方能“聽得懂”對方發的媒體流;
  • 明確誰發送、誰接收、怎么發送;
  • 保障連接的互操作性兼容性

P2P的基本流程

在這里插入圖片描述

參與角色

角色說明
peerA發起連接的端(通常是主叫)
peerB接收連接的端(通常是被叫)
signal信令服務器,用于中轉 SDP 和 ICE 信息,但不參與媒體傳輸
stun/turnSTUN/TURN 服務器,用于穿透 NAT 或作為中繼,輔助建立 P2P 或 Relay 通信

流程詳解

連接信令服務器

  • peerApeerB 分別通過 WebSocket 或其他方式連接信令服務器,用于后續中轉 SDP 和 ICE 數據。

PeerConnection 創建 + 添加媒體流(媒體準備)

peerA

  • 創建 RTCPeerConnection 實例。
  • 通過 getUserMedia() 獲取本地音視頻流。
  • addTrack()addStream() 將媒體加入連接對象。

創建 Offer SDP(發起協商)

  • peerA 調用 createOffer()
    • 生成包含自身媒體能力(支持的音視頻編解碼器、方向、SSRC、碼率等)的 SDP。
  • peerA 調用 setLocalDescription(offer)
    • 表示將該 SDP 用作自己的本地描述。
    • 瀏覽器會開始進行 ICE 候選收集(即尋找可用的 IP/端口路徑)。

發送 Offer SDP(信令交換)

  • peerA 將 Offer SDP 通過 signal 發送給 peerB
  • 此時可以看到 peerA → signal → peerB 的 “Send SDP Offer”。

接收方處理 Offer

peerB

  • 創建 RTCPeerConnection 實例。
  • setRemoteDescription(offer) 設置遠端描述(即 peerA 的 SDP)。
  • 瀏覽器據此了解 peerA 的媒體能力,并開始準備回答。

創建 Answer SDP(應答協商)

  • peerB 調用 createAnswer(),根據雙方交集生成 Answer SDP。
  • 調用 setLocalDescription(answer) 設置為自己的本地描述。

發送 Answer SDP(信令交換)

  • peerB → signal → peerA 發送 Answer SDP。
  • peerA 調用 setRemoteDescription(answer),設置為遠端描述,協商正式完成。

到這一步為止,媒體能力協商完成(Codec、方向等確認)

ICE 候選協商(網絡通路探測)

  • 雙方瀏覽器后臺通過 STUN 向公網發送綁定請求,收集本地的候選地址(ICE candidate)。
  • 每收集到一個 ICE 候選地址,會觸發 onicecandidate 事件。

發送和添加 ICE 候選(網絡路徑建立)

  • 每次 onicecandidate 被觸發,候選地址通過信令發送給對方:
    • peerAsignalpeerB
    • peerBsignalpeerA
  • 收到對方候選后,使用 addIceCandidate() 添加。

當 ICE 連接狀態變為 connectedcompleted 時,即可開始進行媒體傳輸。

媒體流建立

  • 媒體協商完成,網絡路徑打通后:
    • peerB 觸發 onAddStreamontrack 事件,表示收到遠端音視頻流。
    • 同樣地,peerA 也會收到對方的流。

重點流程

階段關鍵函數作用
媒體協商createOffer / createAnswer生成 SDP
setLocalDescription / setRemoteDescription設置 SDP 本地/遠端描述
網絡協商onicecandidate / addIceCandidate交換并使用候選地址建立連接
信令傳輸signal中轉 SDP 和 ICE,但不傳輸媒體
媒體傳輸addTrack / ontrack接收對方音視頻流

重要函數

createOffer()

作用

生成一個 SDP Offer,描述本地支持的音視頻媒體能力(如 codec、媒體方向、分辨率、帶寬等)。

使用示例

const offer = await pc.createOffer();

應用場景

  • 發起方調用,用于開始媒體協商;
  • 會觸發 ICE 候選的收集。

createAnswer()

作用

接收到對方 SDP Offer 后,根據自己的能力生成一個 SDP Answer。

使用示例

const answer = await pc.createAnswer();

應用場景

  • 接收方調用,用于回應媒體協商;
  • 也會觸發 ICE 候選收集。

setLocalDescription(desc)

作用

設置本地描述(Offer 或 Answer),并開始 ICE 候選收集。

使用示例

await pc.setLocalDescription(offer); // offer 或 answer 都可以

說明

  • 必須在發送 SDP 之前調用;
  • 必須配合 createOffercreateAnswer 使用。

setRemoteDescription(desc)

作用

設置遠端 SDP 描述(對方發送的 offer 或 answer),用于協商建立媒體連接。

使用示例

await pc.setRemoteDescription(remoteOffer);

注意

  • 必須在 createAnswer() 前調用(即先設置遠端再生成應答);
  • SDP 是通過信令服務器中轉接收的。

onicecandidate

作用

監聽本地收集到的每一個 ICE 候選地址(IP + port),用于網絡路徑穿透。

示例

pc.onicecandidate = (event) => {if (event.candidate) {sendCandidateToPeer(event.candidate); // 通過信令發送}
};

注意

  • 每收集一個候選地址就觸發一次;
  • 全部收集完畢會收到一個 nullevent.candidate

addIceCandidate(candidate)

作用

將從對方接收到的 ICE 候選加入本地 ICE 代理中,用于連接建立。

示例

await pc.addIceCandidate(remoteCandidate);

注意

  • 一定要在 setRemoteDescription 之后調用;
  • 多次調用用于添加多個候選。

addTrack

作用

添加音頻或視頻軌道(MediaStreamTrack)。

示例

const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const pc = new RTCPeerConnection();stream.getTracks().forEach(track => {pc.addTrack(track, stream); // 同一個 MediaStream 確保同步
});

特性

特性說明
精細軌道控制每次添加單個 MediaStreamTrack(音頻或視頻)
支持多軌道發送可多次調用添加多個音頻/視頻軌
支持軌道同步若多個軌道來自同一個 MediaStream,瀏覽器會自動嘗試同步播放
返回 RTCRtpSender可動態設置編碼參數、帶寬、分辨率等
支持動態添加軌道連接建立后也可添加軌道,會觸發重新協商
可用于替代 addStream現代 WebRTC 標準推薦使用,addStream() 已廢棄
ontrack 配套使用遠端通過 ontrack 事件接收媒體軌道
軌道標簽與 ID 傳遞SDP 會攜帶軌道的 id 和所屬流 stream id(用于標識同步組)
支持 simulcast(多編碼)搭配 RTCRtpSender.setParameters() 支持多編碼流發送

ontrack

作用

當遠端添加了新的媒體軌(音軌/視頻軌)時觸發,一般用于播放遠程視頻或音頻。

示例

pc.ontrack = (event) => {remoteVideo.srcObject = event.streams[0];
};

特性

  • 可接收多個軌道;
  • addTrack()recvonly 類型媒體方向配合使用的標準回調。

發起端與接收端

發起端

const pc = new RTCPeerConnection();pc.onicecandidate = e => sendCandidate(e.candidate);
pc.ontrack = e => remoteVideo.srcObject = e.streams[0];localStream.getTracks().forEach(track => {pc.addTrack(track, localStream);
});const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
sendOffer(offer);

接收端

const pc = new RTCPeerConnection();pc.onicecandidate = e => sendCandidate(e.candidate);
pc.ontrack = e => remoteVideo.srcObject = e.streams[0];await pc.setRemoteDescription(offer);
localStream.getTracks().forEach(track => {pc.addTrack(track, localStream);
});
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
sendAnswer(answer);

總結

  • 目的:確保雙方選用兼容的音視頻編解碼器、分辨率、碼率和傳輸參數,實現高質量的實時通信。
  • 載體:基于 SDP(Session Description Protocol)協議,描述媒體的相關能力。
  • 流程
    • 一方創建并發送包含自身支持能力的 SDP Offer
    • 對方收到后生成 SDP Answer,確認兼容參數
    • 雙方通過設置本地和遠端描述完成協商
  • 內容包括
    • 編解碼器列表(如 VP8、H.264、Opus)
    • 媒體流方向(發送、接收、雙向)
    • 帶寬限制和媒體屬性
    • 網絡傳輸細節(ICE、DTLS安全層)
  • 結果:協商成功后,雙方基于共同支持的參數建立安全穩定的音視頻流通道。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84924.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84924.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84924.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

可信啟動方案設計

安全之安全(security)博客目錄導讀 目錄 一、引言 二、關鍵數據(Critical Data) 三、度量槽(Measurement Slot) 四、可信啟動后端 1、事件日志(Event Log) 2、離散型 TPM(Discrete TPM) 3、RSE(運行時安全引擎) 五、平臺接口 平臺接口的職責: 1、函數:b…

?通義萬相2.1深度解析:AI視頻生成引擎FLF2V-14B全流程指南(命令行參數+模型架構+數據流)

🌟 從零詳解:如何用AI模型生成視頻?命令行、模型結構、數據流全解析! 本文通過一個實際案例,詳細解析使用AI模型生成視頻的整個流程。從命令行參數解讀到模型結構,再到數據在模型間的流動,一步步…

在 TypeScript 前端中使用 Umi-Request 調用 Java 接口的完整指南

下面我將詳細介紹如何在基于 TypeScript 的前端項目中使用 umi-request 調用 IntelliJ IDEA 中開發的 Java 接口,包括完整的實現方案和代碼示例。 整體方案設計 一、Java 后端接口準備 1. 創建 Spring Boot 控制器 // src/main/java/com/example/demo/controller…

GO Gin Web框架面試題及參考答案

目錄 Gin 與 net/http 有哪些主要區別?為什么選擇 Gin? 如何使用 Gin 啟動一個 HTTP 服務并設置默認路由? Gin 的默認路由和自定義路由器組是如何工作的? 如何在 Gin 中綁定請求參數(Query、Form、JSON、XML)? 如何在 Gin 中使用中間件?中間件執行順序是怎樣的? …

asp.net core Razor動態語言編程代替asp.net .aspx更高級嗎?

For Each item In products<tr><td>item.Id</td><td>item.Name</td><td>item.Price.ToString("C")</td></tr>Next為什么要用<tr> ? 在Blazor的Razor語法中&#xff0c;使用<tr>是為了在VB.NET代碼塊中…

css語法中的選擇器與屬性詳解:嵌套聲明、集體聲明、全局聲明、混合選擇器

嵌套聲明 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>嵌套聲明</title> <!-- 這里p span 的含義是p標簽下面的span標簽 所以有嵌套關系--><style>p span {font-weight:…

Linux 系統中,/usr/bin/ 和/bin/的區別?

在 Linux 系統中&#xff0c;/bin/ 和 /usr/bin/ 都是存放可執行程序&#xff08;命令&#xff09;的目錄&#xff0c;但它們在歷史定位、用途、掛載策略和系統設計上有一定區別。 ? 快速對比總結 項目/bin//usr/bin/全稱含義binary&#xff08;核心二進制&#xff09;user b…

蒼穹外賣--WebSocket、來單提醒、客戶催單

WebSocket 1.介紹 WebSocket是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工通信——瀏覽器和服務器只需要一次握手&#xff0c;兩者之間就可以創建持久性的連接&#xff0c;并進行雙向數據傳送。 HTTP協議和WebSocket協議對比&#xff1a; ①Http是短連接 ②W…

Linux 信號(Signal)與信號量(Semaphore)區別

特性信號 (Signal)信號量 (Semaphore)本質軟件中斷進程間同步機制用途通知進程發生了某個事件控制對共享資源的訪問通信方向單向 (內核→進程 或 進程→進程)多進程共享數據類型整數信號編號內核維護的計數器持久性瞬時,不排隊持久,直到顯式釋放實現層次內核實現內核或用戶空…

華為OD機考-觀看文藝匯演問題-區間問題(JAVA 2025B卷)

import java.util.*; /*** version Ver 1.0* date 2025/6/20* description 觀看文藝匯演*/ public class WatchMovie {public static void main(String[] args) {Scanner sc new Scanner(System.in);int num Integer.parseInt(sc.nextLine());List<Movie> movies new …

DeepSeek今天喝什么隨機奶茶推薦器

用DeepSeek生成了一個隨機奶茶推薦器-今天喝什么&#xff0c;效果非常棒&#xff01;UI界面美觀。 提示詞prompt如下 用html5幫我生成一個今天喝什么的網頁 點擊按鈕隨機生成奶茶品牌等&#xff0c;要包括中國常見的知名的奶茶品牌 如果不滿意還可以隨機再次生成 ui界面要好看 …

【國產AI服務器】全國產PCIE5.0交換板,替代博通89104/89144,支持海光、龍芯等平臺

實物圖 核心硬件配置 1、控制器芯片? 采用國產TL63104控制芯片?&#xff0c;支持2.5GT/s、5GT/s、8GT/s、16GT/s、32GT/s的PCIe傳輸速率&#xff0c;支持968Lanes。支持6個x16的group和1個x8的group&#xff0c;每個group支持1至8個端口。x16group支持x16、x8、x4、x2端口…

GPIO-LED驅動

一、LED引腳說明 寄存器地址地圖&#xff1a; 原理圖&#xff1a; 關于MOS管的說明&#xff1a; 總結&#xff1a;當GPIO0_B5這個引腳輸出高電平的時候&#xff0c;對應的N-MOS管導通—LED點亮 當GPIO0_B5這個引腳輸出低電平的時候&#xff0c;對應的N-MOS管截止---LED熄滅 二…

Gartner《Generative AI Use - Case Comparison for Legal Departments》

概述 這篇文章由 Gartner, Inc. 出品,聚焦于生成式人工智能(GenAI)在法律部門中的應用情況,通過對 16 個較為突出的 GenAI 法律技術應用場景進行分析,從商業價值和可行性兩個維度進行評估,旨在為法律總顧問等提供戰略對話依據,以便更好地做出技術投資決策,推動法律部門…

Vue 中 filter 過濾的語法詳解與注意事項

Vue 中 filter 過濾的語法詳解與注意事項 在 Vue.js 中,"過濾"通常指兩種不同概念:模板過濾器(Vue 2 特性)和數組過濾(數據過濾)。由于 Vue 3 已移除模板過濾器,我將重點介紹更實用且通用的數組過濾語法和注意事項。 一、數組過濾核心語法(推薦方式) 1. …

webpack+vite前端構建工具 -6從loader本質看各種語言處理 7webpack處理html

6 從loader本質看各種語言處理 語法糖&#xff1f; 6.1 loader的本質 loader本質是一個方法&#xff0c;接收要處理的資源的內容&#xff0c;處理完畢后給出內容&#xff0c;作為打包結果。 所有的loader&#xff08;例如babel-loader, url-loader等&#xff09;export出一個方…

算法第41天|188.買賣股票的最佳時機IV、309.最佳買賣股票時機含冷凍期、714.買賣股票的最佳時機含手續費

188.買賣股票的最佳時機IV 題目 思路與解法 基于 買賣股票的最佳時機iii&#xff0c;得出的解法。關鍵在于&#xff0c;每一天的賣或者買都由前一天推導而來。 class Solution { public:int maxProfit(int k, vector<int>& prices) {if(prices.size() 0) return …

【AI News | 20250623】每日AI進展

AI Repos 1、tools Strands Agents Tools提供了一個強大的模型驅動方法&#xff0c;通過少量代碼即可構建AI Agent。它提供了一系列即用型工具&#xff0c;彌合了大型語言模型與實際應用之間的鴻溝&#xff0c;涵蓋文件操作、Shell集成、內存管理&#xff08;支持Mem0和Amazon…

Python裝飾器decorators和pytest夾具fixture詳解和使用

此前一直認為fixture就叫python中的裝飾器&#xff0c;學習后才發現decorators才是裝飾器&#xff0c;fixture是pytest框架的夾具&#xff0c;只是通過裝飾器去定義和使用。所以要了解fixture就得先了解python裝飾器。 一、裝飾器(decorators) 1.定義 裝飾器&#xff08;dec…

目標檢測之YOLOv5到YOLOv11——從架構設計和損失函數的變化分析

YOLO&#xff08;You Only Look Once&#xff09;系列作為實時目標檢測領域的標桿性框架&#xff0c;自2016年YOLOv1問世以來&#xff0c;已歷經十余年迭代。本文將聚焦YOLOv5&#xff08;2020年發布&#xff09;到YOLOv11&#xff08;2024年前后&#xff09;的核心技術演進&am…