国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

上傳了網(wǎng)站源碼怎么做新聞最新熱點

上傳了網(wǎng)站源碼怎么做,新聞最新熱點,廣告聯(lián)盟賺錢平臺,滎陽市網(wǎng)站建設(shè)介紹 WebRTC (Web Real-Time Communications) 是一個實時通訊技術(shù),也是實時音視頻技術(shù)的標(biāo)準(zhǔn)和框架。簡單來說WebRTC是一個集大成的實時音視頻技術(shù)集,包含了各種客戶端api、音視頻編/解碼lib、流媒體傳輸協(xié)議、回聲消除、安全傳輸?shù)取τ陂_發(fā)者來說可以…

介紹

WebRTC (Web Real-Time Communications) 是一個實時通訊技術(shù),也是實時音視頻技術(shù)的標(biāo)準(zhǔn)和框架。簡單來說WebRTC是一個集大成的實時音視頻技術(shù)集,包含了各種客戶端api、音視頻編/解碼lib、流媒體傳輸協(xié)議、回聲消除、安全傳輸?shù)取τ陂_發(fā)者來說可以借助webrtc非常方便的實現(xiàn)低延時視頻通話能力。目前大多主流的直播系統(tǒng)、會議系統(tǒng)基本都是基于WebRTC來實現(xiàn)。

三種架構(gòu)

WebRTC針對不同場景以及性能考慮提供了三種架構(gòu)Mesh架構(gòu)、MCU、FSU。
在這里插入圖片描述

Mesh架構(gòu)

Mesh架構(gòu),需要所有參與連接的peer建立與所有其他peer的媒體連接(兩兩連接)。該架構(gòu)需要n-1個上下行,以此帶來的帶寬消耗(流量)、編/解碼消耗(設(shè)備性能)成線性增長。該架構(gòu)只能適用3-4個人的小型會議場景。

MCU架構(gòu)

所有參與連接的peer將本地媒體流推到遠(yuǎn)程媒體服務(wù)器,由媒體服務(wù)器進(jìn)行混流,然后再推到所有連接的peer端。該架構(gòu)的優(yōu)點就是只需要1路上下行,隨著peer人數(shù)不斷增加,依然不會對用戶造成帶寬、手機(jī)性能影響。該架構(gòu)將壓力轉(zhuǎn)嫁到服務(wù)端,由專用媒體服務(wù)器來完成混流,轉(zhuǎn)推等功能。

SFU架構(gòu)

相對于MCU來說SFU只做轉(zhuǎn)發(fā),媒體服務(wù)器壓力有限。與Mesh架構(gòu)相比,只需要n-1個下行,1個上行,減少了服務(wù)器壓力。在大規(guī)模的場合該架構(gòu)具有伸縮性。

點對點視頻連接

根據(jù)上面,我們對基本W(wǎng)ebRTC有了最基本的認(rèn)識,下面就從點對點實際例子來從代碼角度進(jìn)一步了解其原理。

先從下圖來看看使用MCU來實現(xiàn)點對點需要哪些東西在這里插入圖片描述
在介紹流程之前,先簡單介紹下上圖中出現(xiàn)的名詞代表什么意思:

  • Peer:通信雙方設(shè)備。
  • Signaling Server: 信令服務(wù)器,用于交互連接雙方的信令數(shù)據(jù)(SDP、ICE等),以保證通信的對等連接建立。
  • NAT:處理私有網(wǎng)絡(luò)和公共網(wǎng)絡(luò)之間的地址轉(zhuǎn)換問題(因為大多數(shù)設(shè)置都處于內(nèi)網(wǎng)中,需要轉(zhuǎn)換為公共網(wǎng)絡(luò)才能進(jìn)行外網(wǎng)訪問)
  • STUN:用于發(fā)現(xiàn)設(shè)備的公共地址(通過NAT轉(zhuǎn)換的公網(wǎng)地址),輔助穿越NAT進(jìn)行點對點連接。
  • TURN:在無法建立直接連接時提供數(shù)據(jù)中繼,確保通信的可靠性。對等連接異常時的兜底方案。
  • SDP:會話描述協(xié)議,用于描述和協(xié)商媒體會話的協(xié)議,它定義了會話的所有技術(shù)細(xì)節(jié),包括媒體格式、編解碼器、網(wǎng)絡(luò)地址等。,
  • ICE:用于發(fā)現(xiàn)和選擇最優(yōu)網(wǎng)絡(luò)路徑的框架,確保在各種網(wǎng)絡(luò)環(huán)境下都能成功建立和維持連接。

代碼實現(xiàn)

實現(xiàn)點對點連接主要是兩點:1、信令數(shù)據(jù)交互 2、對等連接建立
在代碼中使用到了socket.io來將設(shè)備和信令服務(wù)器通信,使用了simple-peer來建立對等連接,由于該demo在本地運(yùn)行所以沒有使用STUN/TRUN服務(wù)器,有興趣的可以使用Chrome提供的公共服務(wù)器stun:stun.l.google.com:19302
主要步驟如下:

  • 1、和信令服務(wù)器建立連接,并獲取自身的socketId作為唯一標(biāo)識
  • 2、申請方將信令(由simple-peer生成)通過信令服務(wù)器到達(dá)接受方
  • 3、接受方接受,將發(fā)起方的信令保存到對等連接peer中,并且將自己的信令通過信令服務(wù)器給到發(fā)送方
  • 4、發(fā)送方將接受方的信令數(shù)據(jù)保存到對等連接peer中,至此發(fā)送方-接受方對等連接建立完成
  • 5、在發(fā)送方和接受方監(jiān)聽peer的stream,來獲取視頻流,然后展示在頁面

和信令服務(wù)器建立連接

新建一個server,js使用node+express搭建的簡易信令服務(wù)器,用于交換雙方信令。通過create-react-app來創(chuàng)建一個前端頁面。

信令服務(wù)器代碼如下:

const express = require("express");
const http = require("http");
const cors = require("cors");const app = express();
const server = http.createServer(app);
app.use(cors);
const io = require("socket.io")(server, {cors: {origin: "*",methods: ["POST", "GET"],},
});server.listen(5001, () => {console.log("listening on 5000 ...");
});io.on("connection", (socket) => {// 分發(fā)socket idsocket.emit("offer", socket.id);// 發(fā)送發(fā)起方的信令數(shù)據(jù)別answersocket.on("callUser", (data) => {io.to(data.answerId).emit("callUser", data);});// 發(fā)送接收放信令給申請方socket.on("answerSignalInfo", (data) => {io.to(data.to).emit("answerSignalInfo", data);});socket.on("disconnect", () => {socket.broadcast.emit("callEnded", socket);});
});
// frontend
// 通過socket.io和服務(wù)器進(jìn)行連接
const socket = io("http://localhost:5001");// 獲取自身的socket id
socket.on("offer", (offerId) => {console.log("offer socket ID", offerId);setOfferId(offerId);getLocalStream(); // 獲取本地視頻流
});

傳遞信令數(shù)據(jù)

// 通過simple-peer 交換信令數(shù)據(jù) offer -> 信令服務(wù)器 -> answer
const peer = new Peer({initiator: true, // 是否是發(fā)起方stream: localStream, // 傳遞的視頻流trickle: false, // 點對點傳輸,獲取單個信號// 設(shè)置STUN服務(wù)器,Chrome提供的公共服務(wù)器config: {iceServers: [{ urls: "stun:stun.l.google.com:19302" }],},
});
peer.on("signal", (data: any) => {socket.emit("callUser", {singleData: data, // 發(fā)送通話方的信令數(shù)據(jù)answerId: answerId, // 需要和誰通話from: offerId, // 誰申請通話});
});

接收信令數(shù)據(jù)

接收方接收發(fā)起方的信令數(shù)據(jù),并保存到Peer中,然后將自身的信令數(shù)據(jù)返回給發(fā)起方

const peer = new Peer({initiator: false,stream: localStream,trickle: false,config: {iceServers: [{ urls: "stun:stun.l.google.com:19302" }],},
});
peer.on("signal", (data) => {socket.emit("answerSignalInfo", {answerSignalInfo: data,to: offerUserInfo?.id,from: offerId,});
});if (offerUserInfo?.singleData) {peer.signal(offerUserInfo.singleData);
}

對等連接建立,獲取雙方視頻流

交互信令之后,通過simple-peer成功建立對等連接,監(jiān)聽stream視頻流然后顯示在頁面上

// 監(jiān)聽通過對等連接傳遞的stream
peer.on("stream", (stream) => {if (remoteVideoRef.current) {remoteVideoRef.current.srcObject = stream;remoteVideoRef.current.play();}
});

完整頁面代碼:CSS樣式文件省略

import React, { useCallback, useEffect, useRef, useState } from "react";
import { io } from "socket.io-client";
import Peer from "simple-peer";
import "./App.css";const socket = io("http://localhost:5001");type UserInfo = {singleData: any;id: string;
};function App() {// 用于引用 DOM 元素const localVideoRef = useRef<HTMLVideoElement>(null);const remoteVideoRef = useRef<HTMLVideoElement>(null);// 用于管理狀態(tài)const [localStream, setLocalStream] = useState<MediaStream | undefined>();const [offerId, setOfferId] = useState("");const [answerId, setAnswerId] = useState("");const [offerUserInfo, setOfferUserInfo] = useState<UserInfo>();// 獲取本地視頻流const getLocalStream = useCallback(async () => {try {const stream = await navigator.mediaDevices.getUserMedia({video: {width: { ideal: 200 }, // 理想的寬度height: { ideal: 200 }, // 理想的高度},audio: false,});console.log("local media", stream);setLocalStream(stream);if (localVideoRef.current) {localVideoRef.current.srcObject = stream;}} catch (error) {console.error("Error accessing media devices.", error);}}, []);// 手動設(shè)置通話方idconst onChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {console.log("onChange call id", e);setAnswerId(e.target.value);}, []);// 獲取信令牌服務(wù)器發(fā)送的socket idconst init = useCallback(() => {socket.on("offer", (offerId) => {console.log("offer socket ID", offerId);setOfferId(offerId);getLocalStream(); // 獲取本地視頻流});// 監(jiān)聽信令服務(wù)器發(fā)送的通話申請方的信令牌數(shù)據(jù)socket.on("callUser", ({ singleData, answerId, from }) => {console.log(`${from}發(fā)起通話`, from);setOfferUserInfo({singleData: singleData,id: from,});});}, [getLocalStream]);// 創(chuàng)建和發(fā)送 offerconst startCall = useCallback(async () => {// 通過simple-peer 交換信令數(shù)據(jù) offer -> 信令服務(wù)器 -> answerconst peer = new Peer({initiator: true,stream: localStream,trickle: false,// 設(shè)置STUN服務(wù)器,Chrome提供的公共服務(wù)器config: {iceServers: [{ urls: "stun:stun.l.google.com:19302" }],},});peer.on("signal", (data: any) => {socket.emit("callUser", {singleData: data, // 發(fā)送通話方的信令數(shù)據(jù)answerId: answerId, // 需要和誰通話from: offerId, // 誰申請通話});});// 獲取到接收方的信令數(shù)據(jù)socket.on("answerSignalInfo", (data) => {console.log(`${data.from}已經(jīng)接受通話`, data, peer);peer.signal(data.answerSignalInfo);});// 監(jiān)聽通過對等連接傳遞的streampeer.on("stream", (stream) => {if (remoteVideoRef.current) {remoteVideoRef.current.srcObject = stream;remoteVideoRef.current.play();}});// setPeer(peer);}, [answerId, localStream, offerId, remoteVideoRef]);const acceptCall = useCallback(() => {const peer = new Peer({initiator: false,stream: localStream,trickle: false,config: {iceServers: [{ urls: "stun:stun.l.google.com:19302" }],},});peer.on("signal", (data) => {socket.emit("answerSignalInfo", {answerSignalInfo: data,to: offerUserInfo?.id,from: offerId,});});if (offerUserInfo?.singleData) {peer.signal(offerUserInfo.singleData);}// 監(jiān)聽通過對等連接傳遞的streampeer.on("stream", (stream) => {if (remoteVideoRef.current) {remoteVideoRef.current.srcObject = stream;remoteVideoRef.current.play();}});}, [localStream, offerUserInfo, offerId, remoteVideoRef]);useEffect(() => {init();}, [init]);return (<div className="App"><video autoPlay muted ref={localVideoRef} className="video" /><video autoPlay muted ref={remoteVideoRef} className="video" /><input value={answerId} onChange={onChange} placeholder="call id" /><button onClick={startCall}>發(fā)起通話</button><button onClick={acceptCall}>同意通話</button></div>);
}export default App;

至此可以啟動項目,并本地瀏覽器打開兩個tab即可體驗點對點視頻服務(wù)。

總結(jié)

點對點通信,主要就是信令數(shù)據(jù)的交換,知道通信雙方具體的配置信息(通信參數(shù)、IP地址等)以保證對等連接的成功建立,然后傳遞視頻流在頁面展示。
其中信令服務(wù)器僅用于對等連接前的信令交換,不會進(jìn)行數(shù)據(jù)傳輸。NAT是將設(shè)備內(nèi)網(wǎng)地址轉(zhuǎn)換為外網(wǎng)公共地址。STUN來獲取設(shè)置的公網(wǎng)地址。TURN服務(wù)器是用于對等連接異常時的兜底方案,可進(jìn)行數(shù)據(jù)傳輸。

http://aloenet.com.cn/news/42339.html

相關(guān)文章:

  • 桓臺網(wǎng)站開發(fā)廣州:推動優(yōu)化防控措施落地
  • 中國互聯(lián)網(wǎng)網(wǎng)站性能丈哥seo博客工具
  • 錦州網(wǎng)站建設(shè)多少錢網(wǎng)站排名掉了怎么恢復(fù)
  • wordpress 地址 .html臺州seo
  • 別人抄襲網(wǎng)站設(shè)計怎么辦設(shè)計師必備的6個網(wǎng)站
  • 尋花問柳一家專注做男人喜愛的網(wǎng)站什么網(wǎng)站推廣比較好
  • 諸城盟族網(wǎng)站建設(shè)北京做網(wǎng)站公司哪家好
  • 網(wǎng)上營銷活動長沙網(wǎng)站seo分析
  • 學(xué)校校園網(wǎng)站建設(shè)方案上海網(wǎng)站營銷seo方案
  • 做圖片的網(wǎng)站外貿(mào)建站
  • 網(wǎng)站開發(fā)研究背景域名搜索
  • 做網(wǎng)站 警察佛山抖音seo
  • macos做網(wǎng)站快速網(wǎng)站推廣
  • 網(wǎng)站開發(fā)技術(shù)項目北京seo相關(guān)
  • 免費(fèi)做網(wǎng)站方案新手怎么做seo優(yōu)化
  • win2012 iis 部署網(wǎng)站運(yùn)營是做什么的
  • 網(wǎng)站轉(zhuǎn)化分析百度優(yōu)化怎么做
  • 大連市建委官方網(wǎng)站推廣一般收多少錢
  • java python 做網(wǎng)站武漢seo認(rèn)可搜點網(wǎng)絡(luò)
  • 北京營銷型網(wǎng)站建設(shè)價格西安百度推廣運(yùn)營公司
  • 色母粒對網(wǎng)站的建議和優(yōu)化
  • 西安未央?yún)^(qū)網(wǎng)站建設(shè)微博推廣效果怎么樣
  • 網(wǎng)站admin密碼西安seo外包
  • 網(wǎng)站收錄是怎么回事免費(fèi)網(wǎng)絡(luò)推廣網(wǎng)址
  • 中山網(wǎng)站推廣服務(wù)提高seo關(guān)鍵詞排名
  • 怎么自己用手機(jī)做網(wǎng)站門戶網(wǎng)站軟文
  • 做個類似淘寶的網(wǎng)站怎么做搜索引擎推廣的方法有哪些
  • 網(wǎng)站360自然排名要怎么做百度手機(jī)版
  • 廣州番禺網(wǎng)站建設(shè)工作室網(wǎng)站搭建
  • 網(wǎng)絡(luò)集資網(wǎng)站怎么做中國宣布取消新冠免費(fèi)治療