<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WebRTC 入門指南:實時通信完全解析

      WebRTC 入門指南:實時通信完全解析

      ?? 簡介

      WebRTC(Web 實時通信)是一項強大的技術,支持瀏覽器和移動應用實時交換音視頻與數據——無需中間服務器中轉。它是現代視頻通話、屏幕共享工具及實時協(xié)作平臺的核心底層技術。

      本文將完整覆蓋 WebRTC 技術流程:從獲取用戶媒體到建立安全的點對點(P2P)連接,并提供基于 TypeScript 風格的 JavaScript 實戰(zhàn)示例。

      ?? 捕獲媒體流

      什么是媒體流(Media Stream)?

      流(Stream)是連續(xù)的數據傳輸流——在 WebRTC 中,特指實時傳輸的音頻或視頻數據。

      使用 getUserMedia 捕獲音視頻

      通過 navigator.mediaDevices.getUserMedia() 方法可請求訪問用戶的麥克風和攝像頭,示例如下:

      const constraints = { audio: true, video: true }; // 配置:同時捕獲音頻和視頻
      
      navigator.mediaDevices
        .getUserMedia(constraints)
        .then((mediaStream) => {
          console.log('成功獲取媒體流:', mediaStream);
        })
        .catch((err) => {
          console.error('獲取媒體流失敗:', err);
        });
      

      ?? 注意:瀏覽器會先彈出權限請求,僅在用戶允許后才會提供音視頻訪問權限。

      在 <video> 元素中顯示視頻

      首先在 HTML 中定義用于顯示視頻的元素:

      <video autoplay playsinline id="local-video"></video>
      <!-- autoplay:自動播放;playsinline:在頁面內播放(避免全屏) -->
      

      再通過 JavaScript 將捕獲到的媒體流綁定到視頻元素:

      const videoElement = document.getElementById('local-video') as HTMLVideoElement;
      
      navigator.mediaDevices.getUserMedia({ video: true }) // 僅捕獲視頻
        .then((stream) => {
          videoElement.srcObject = stream; // 將媒體流賦值給視頻元素
        });
      

      ?? 枚舉與選擇設備

      枚舉所有設備

      通過以下方法可列出設備上所有可用的音視頻輸入/輸出設備(如麥克風、攝像頭、揚聲器):

      navigator.mediaDevices.enumerateDevices()
        .then((devices) => {
          devices.forEach((device) => {
            console.log(`${device.kind}:${device.label}`); 
            // 示例輸出:videoinput:USB 攝像頭、audioinput:內置麥克風
          });
        });
      

      監(jiān)聽設備變化

      當有新設備(如外接攝像頭)連接或設備斷開時,可通過事件監(jiān)聽實時更新設備列表:

      navigator.mediaDevices.addEventListener('devicechange', () => {
        console.log('設備列表已更新!');
        // 可在此處重新調用 enumerateDevices() 刷新設備列表
      });
      

      ?? 使用媒體約束(Media Constraints)

      媒體約束允許精細化配置音視頻參數,例如指定使用某臺攝像頭、設置視頻分辨率或幀率:

      const preferredDeviceId = 'abc123'; // 從 enumerateDevices() 獲取的目標設備 ID
      
      const constraints = {
        video: {
          deviceId: { exact: preferredDeviceId }, // 精確指定使用某臺設備
          width: { ideal: 1280 }, // 理想寬度:1280px
          height: { ideal: 720 }, // 理想高度:720px(720P)
          frameRate: { ideal: 30 }, // 理想幀率:30fps
        },
        audio: {
          echoCancellation: true, // 開啟回聲消除
        },
      };
      
      // 按約束條件獲取媒體流
      navigator.mediaDevices.getUserMedia(constraints);
      

      ?? 捕獲屏幕

      通過 getDisplayMedia() 方法可捕獲屏幕內容(如整個屏幕、特定窗口或應用),示例如下:

      const screenStream = await navigator.mediaDevices.getDisplayMedia({
        video: true, // 屏幕捕獲僅支持視頻(無音頻)
      });
      // 將屏幕流綁定到視頻元素顯示
      document.querySelector('video').srcObject = screenStream;
      

      ?? 注意:瀏覽器會彈出選擇窗口,要求用戶指定要捕獲的屏幕、窗口或應用。

      ?? 管理媒體軌道(Media Tracks)

      每個媒體流(Stream)包含一個或多個軌道(Track),分別對應音頻軌道或視頻軌道。可對軌道進行單獨禁用、停止等操作:

      // 獲取僅含視頻的媒體流
      const stream = await navigator.mediaDevices.getUserMedia({ video: true });
      // 提取流中的所有軌道
      const tracks = stream.getTracks();
      
      // 1. 禁用軌道(臨時關閉,可重新啟用)
      tracks[0].enabled = false; // 禁用第一個軌道(此處為視頻軌道)
      
      // 2. 完全停止軌道(釋放設備資源,無法恢復)
      tracks.forEach((track) => track.stop());
      

      ?? 建立對等連接(Peer Connection)

      WebRTC 的核心是 RTCPeerConnection 接口,它負責在兩個對等端(如兩臺設備)之間建立直接連接:

      // 配置 ICE 服務器(用于穿透 NAT,建立 P2P 連接)
      const config = {
        iceServers: [
          { urls: 'stun:stun.l.google.com:19302' } // 谷歌公共 STUN 服務器
        ],
      };
      
      // 創(chuàng)建對等連接實例
      const peerConnection = new RTCPeerConnection(config);
      

      ?? ICE、STUN、TURN 概念解析

      WebRTC 依賴以下三種技術實現對等端之間的網絡連接:

      • ICE(Interactive Connectivity Establishment,交互式連接建立):核心框架,負責尋找對等端之間可用的網絡路徑。
      • STUN(Session Traversal Utilities for NAT,NAT 會話穿越工具):幫助設備發(fā)現自身在公網中的 IP 地址和端口(解決 NAT 遮擋問題)。
      • TURN(Traversal Using Relays around NAT,通過中繼穿越 NAT):當 P2P 直接連接失敗時,作為中繼服務器轉發(fā)音視頻數據(確保通信不中斷)。

      含 TURN 服務器的配置示例

      const config = {
        iceServers: [
          // 優(yōu)先使用 STUN 嘗試直接連接
          { urls: ['stun:stun.l.google.com:19302'] },
          // 備用 TURN 服務器(需自行部署或使用商業(yè)服務)
          {
            urls: 'turn:turn.example.com', // TURN 服務器地址
            username: 'user', // 認證用戶名
            credential: 'pass' // 認證密碼
          },
        ],
      };
      

      ?? ICE 候選者交換

      ICE 候選者(ICE Candidate)是包含設備網絡信息(如 IP、端口、傳輸協(xié)議)的數據,對等端需交換候選者才能找到可通信的路徑。交換需通過信令服務器(如 WebSocket)完成:

      發(fā)送 ICE 候選者(本地 → 遠程)

      // 監(jiān)聽本地 ICE 候選者生成事件
      peerConnection.onicecandidate = (event) => {
        if (event.candidate) {
          // 通過信令服務器將候選者發(fā)送給遠程對等端
          signalingServer.send('ice-candidate', event.candidate);
        }
      };
      

      接收 ICE 候選者(遠程 → 本地)

      // 監(jiān)聽信令服務器的 ICE 候選者消息
      signalingServer.on('ice-candidate', async (candidate) => {
        // 將遠程候選者添加到本地對等連接
        await peerConnection.addIceCandidate(candidate);
      });
      

      ?? 提議/應答交換(SDP)

      對等連接建立前,需交換 SDP(Session Description Protocol,會話描述協(xié)議)信息,用于協(xié)商媒體格式、編碼方式等參數。交換過程分為“提議(Offer)”和“應答(Answer)”兩步:

      1. 發(fā)起方創(chuàng)建并發(fā)送提議

      // 1. 創(chuàng)建提議(包含本地媒體配置)
      const offer = await peerConnection.createOffer();
      // 2. 將提議設置為本地描述(保存本地配置)
      await peerConnection.setLocalDescription(offer);
      // 3. 通過信令服務器發(fā)送提議給接收方
      signalingServer.send('offer', offer);
      

      2. 接收方處理提議并發(fā)送應答

      // 1. 接收并設置遠程描述(保存發(fā)起方的配置)
      peerConnection.setRemoteDescription(offer).then(async () => {
        // 2. 創(chuàng)建應答(包含接收方的媒體配置)
        const answer = await peerConnection.createAnswer();
        // 3. 將應答設置為本地描述(保存接收方配置)
        await peerConnection.setLocalDescription(answer);
        // 4. 通過信令服務器發(fā)送應答給發(fā)起方
        signalingServer.send('answer', answer);
      });
      

      ?? 向連接添加本地媒體

      將本地捕獲的音視頻流添加到對等連接,才能向遠程對等端傳輸媒體:

      // 1. 獲取本地音視頻流
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
      // 2. 將流中的所有軌道添加到對等連接
      stream.getTracks().forEach((track) => {
        peerConnection.addTrack(track, stream);
      });
      

      接收遠程媒體

      監(jiān)聽 track 事件,獲取遠程對等端發(fā)送的媒體流并顯示:

      peerConnection.addEventListener('track', (event) => {
        // 從事件中提取遠程媒體流
        const remoteStream = event.streams[0];
        // 將遠程流綁定到視頻元素(顯示對方畫面)
        document.getElementById('remote-video').srcObject = remoteStream;
      });
      

      ?? 動態(tài)管理軌道

      連接建立后,可動態(tài)調整媒體軌道(如關閉麥克風、切換攝像頭):

      切換麥克風(禁用/啟用音頻軌道)

      // 1. 找到音頻軌道的發(fā)送器(Sender)
      const audioSender = peerConnection
        .getSenders()
        .find((sender) => sender.track?.kind === 'audio');
      
      // 2. 禁用/啟用音頻軌道
      if (audioSender) audioSender.track.enabled = false; // 禁用(靜音)
      // if (audioSender) audioSender.track.enabled = true; // 啟用(取消靜音)
      

      連接后添加新軌道

      // 假設已獲取新的視頻軌道(如切換攝像頭后的軌道)
      const newVideoTrack = stream.getVideoTracks()[0];
      // 將新軌道添加到對等連接
      peerConnection.addTrack(newVideoTrack, stream);
      

      ? 關閉 WebRTC 連接

      結束通信時,需停止所有媒體軌道并關閉對等連接,釋放資源:

      // 1. 停止所有發(fā)送器的軌道
      peerConnection.getSenders().forEach((sender) => sender.track.stop());
      // 2. 關閉對等連接
      peerConnection.close();
      

      ?? 群組通話:Mesh、SFU 與 MCU 對比

      當通話參與者超過 2 人時,需選擇合適的架構方案。以下是三種主流群組通話架構的對比:

      Mesh 架構

      • 原理:每個參與者直接與其他所有參與者建立 P2P 連接(如 3 人通話需建立 3 條連接)。
      • 優(yōu)點:架構簡單,無需專用媒體服務器,延遲低。
      • 缺點:參與者數量越多,CPU 占用和網絡帶寬消耗呈指數級增長(僅適合 4 人以下小規(guī)模通話)。

      SFU(選擇性轉發(fā)單元)

      • 原理:所有參與者將媒體流發(fā)送到 SFU 服務器,服務器不解碼媒體,僅根據需求將流轉發(fā)給其他參與者(如只轉發(fā)說話者的流)。
      • 優(yōu)點:客戶端負載低(僅需處理 1 條上傳流和 N 條下載流),支持中等規(guī)模群組(20 人以內)。
      • 主流方案:LiveKit、mediasoup、Mirotalk。

      MCU(多點控制單元)

      • 原理:所有參與者將媒體流發(fā)送到 MCU 服務器,服務器解碼并混合所有流(如將多個人的畫面合成一個分屏畫面),再將混合后的單一流轉發(fā)給所有參與者。
      • 優(yōu)點:客戶端負載極低(僅需處理 1 條上傳流和 1 條下載流)。
      • 缺點:服務器解碼/混合需大量計算資源,延遲較高,服務器成本高(適合大規(guī)模但對延遲不敏感的場景)。

      ?? 總結

      WebRTC 僅需幾行 JavaScript 代碼,就能實現實時音視頻與數據傳輸。雖然入門簡單,但它涉及 ICE、SDP、信令等深層技術概念。

      無論你是想開發(fā)類似 Zoom 的視頻會議工具,還是實時代碼面試平臺——理解如何捕獲、發(fā)送和接收點對點媒體流,都是邁出的第一步。

      擴展鏈接

      SpreadJS+GCExcel全棧解決方案--協(xié)同編輯的框架搭建(三)

      BI使用WebSocket創(chuàng)建物聯(lián)網數據

      低代碼對接WebSocket

      posted @ 2025-08-26 08:56  葡萄城技術團隊  閱讀(1137)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 亚洲色欲在线播放一区二区三区| 国产精品香港三级国产av| 一区二区亚洲人妻av| 亚洲 一区二区 在线| 好吊妞视频这里有精品| 午夜国产小视频| 国产盗摄视频一区二区三区| 国产va免费精品观看| 精品无码国产污污污免费| 精品综合久久久久久97| 漂亮人妻中文字幕丝袜| 少妇人妻综合久久中文字幕| 9久9久热精品视频在线观看| 亚洲一区二区三区在线激情| 国产成人综合色视频精品| 午夜视频免费试看| 老色鬼永久精品网站| 午夜精品国产自在| 成人无码潮喷在线观看| 亚洲精品一品二品av| 午夜男女爽爽影院免费视频下载| 国产日韩一区二区在线| 无码综合天天久久综合网| 人妻18毛片A级毛片免费看| 亚洲色婷婷综合开心网 | 国产精品进线69影院| 国产99视频精品免费专区| 亚洲精品国产美女久久久| 久久国产免费观看精品3| 色悠久久网国产精品99| 久久99九九精品久久久久蜜桃| 国产普通话对白刺激| 天堂а√在线地址中文在线| 亚洲尤码不卡av麻豆| 熟妇人妻不卡中文字幕| 无码免费大香伊蕉在人线国产| 国产麻传媒精品国产av| 99在线小视频| 久久久精品94久久精品| 亚洲国产精品综合色在线| 狠狠v日韩v欧美v|