webRTC——瀏覽器里的音視頻通話

背景

webRTC是Google在2010年收購GIP公司之后獲得的一項技術。如下圖所示,它提供了音視頻的采集、處理(降噪,回聲消除等)、編解碼、傳輸等技術。

webRTC的目標是實現無需安裝任何插件就可以通過瀏覽器進行P2P的實時音視頻通話及文件傳輸,來看看Google的demo,是不是很酷?本文將帶你分析webRTC的原理,并逐步編寫一個簡單的demo。

原理

如圖,瀏覽器之間媒體流的傳輸是P2P的,但是這并不意味著webRTC不需要服務器支持。建立P2P視頻連接需要的信息,如用來初始化通信的session信息,雙方的ip、端口,視頻分辨率,編解碼格式等等,還是需要通過服務器來傳輸的。webRTC沒有規定這些信息傳輸的機制,XHR、webSocket、Socket.io等都是可以的,因為Socket.io自帶了房間的概念,便于雙向視頻的撮合,所以我在demo里選擇了Socket.io。

當然,連接建立的過程不會這么簡單。首先,提到P2P就繞不開NAT(Network Address Translation),webRTC使用ICE(Interactive Connectivity Establishment)框架,ICE是一種綜合性的NAT穿越技術,它整合了STUN、TURN。當穿越網絡時,ICE會先嘗試STUN,查出自己位于哪種類型的NAT之后以及NAT為某一個本地端口所綁定的Internet端端口從而建立UDP連接,如果失敗了ICE就會再嘗試TCP(先嘗試HTTP,再嘗試HTTPS),如果仍然失敗就使用中繼的TURN服務器。

再來看看建立連接過程中的具體步驟:

  1. 調用getUserMedia獲取本地的MediaStreams;
  2. 從STUN獲取自己的外網IP及端口,通過Signaling Server向對方發送Offer(SDP協議),并收到Answer;
  3. 同時webRTC會生成一些包含自己的內網、外網IP等信息的candidate,同樣通過Signaling Server相互傳輸;
  4. 建立P2P連接,傳輸媒體信息。

API

  • getUserMedia: 獲取本地視頻、音頻,可以傳入constraints調整分辨率、幀率,返回一個promise;
  • RTCPeerConnection: 生成一個RTCPeerConnection實例,傳輸視頻、音頻流;
  • createOffer: 會話發起方生成SDP Offer,包含了本地媒體流信息;
  • setLocalDescription:在此方法被調用之前oncandidate事件不會被觸發;
  • setRemoteDescription: 接收到offer或者answer之后調用;
  • addIceCandidate: 接收到icecandidate之后調用;

Steps

獲取媒體流

var constraints = {audio: false,video: true
};navigator.mediaDevices.getUserMedia(constraints)
.then(gotStream)
.catch(function(e) {alert('getUserMedia() error: ' + e.name);
});function gotStream(stream) {localVideo.srcObeject = stream;localStream = stream;
}
復制代碼

getUserMedia存在兼容性問題,需要在項目中引用webRTC官方給出的adapter.js。constraints還可以配置video的分辨率、幀率、對移動端還可以選擇前后攝像頭: var constraints = { video: { width: { min:640, ideal: 1280, max: 1920 }, height: { min: 480 ideal: 720, max: 1080 }, facingMode: 'user' // 前置攝像頭 } };

定義RTCPeerConnection

var serverConfig = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]
};function createPeerConnection() {var pc = new RTCPeerConnection(serverConfig);pc.onicecandidate = function(e) {if (e.candidate) {pc.addIceCandidate(e.candidate);}};// 添加對方的媒體流pc.onaddstream = function(e) {remoteVideo.srcObeject = e.stream;remoteStream = stream;};
}
復制代碼

由STUN、TURN配置生成對應的RTCPeerConnection實例,再定義相關的事件處理函數,如onicecandidate、onaddstream、onremovestream等。

創建連接

function start() {pc.addstream(localStream);if (isCaller) {pc.createOffer(function(sessionDescription) {pc.setLocalDescription(sessionDescription);send(sessionDescription);  // 根據不同的Signaling方式實現});if (receiveAnswer) {pc.setRemoteDescription(answer.sessionDescription);}} else {if (receiveOffer) {pc.setRemoteDescription(offer.sessionDescription);}pc.createAnswer(function(sessionDescription) {pc.setLocalDescription(sessionDescription);send(sessionDescription);});}
}
復制代碼

必須先getUserMedia后才能生成sessionDescription,并且只有在setLocalDescription后onicecandidate事件才會觸發。上面代碼中的只是為了說明大致流程,實際項目中結合socket.io的事件更容易實現。

中斷會話

function stop() {pc.stop();pc = null;
}
復制代碼

關于socket.io有關的代碼本文沒有貼出,詳情可參考socket.io的用法。

可行性

按照上面的步驟可以成功地搭建webRTC的小demo,但是能否將webRTC運用到實際項目中去呢?下面從瀏覽器兼容性和webRTC本身的性能兩個方面去分析。

兼容性

  • IOS: 只有最新的ios11支持webRTC,且僅限safari瀏覽器,微信內置瀏覽器尚不支持getUserMedia,不支持DataChannel,視頻編解碼格式為H.264;

  • Android: 安卓4.4以上(不含4.4),經測試各大手機廠商自帶瀏覽器均不支持getUserMedia,但微信內置瀏覽器可以正常運行,另外61版本以上的Chrome for Android也都支持;

  • PC: Chrome49以上,Firefox55以上,Edge支持,Safari只有11支持,IE不支持。

性能

誠然webRTC在回聲消除,圖像編解碼等方面已經做得十分出色,但它在性能上的問題還是不可忽視的:

  • 由于需要進行視頻編解碼,所以CPU占用率非常高,尤其是在移動設備上;
  • 在移動設備上獲取的視頻分辨率有限,最高只能達到640 * 480;
  • 帶寬有限時,音視頻質量較差,延時明顯;

綜上所述,雖然webRTC具有不需安裝插件或者客戶端,開源免費,強大的網絡穿透能力,出色的音視頻處理技術等等優點,但由于兼容性及性能上的問題,要投入到生產中還需要時間,主要是IOS11的普及以及CPU占用率和延時的問題。

參考文章

  • WebRTC in the real world: STUN, TURN and signaling

  • How to Select a Signaling Protocol for Your Next WebRTC Project?

  • Getting Started with WebRTC

  • 使用WebRTC搭建前端視頻聊天室——入門篇

轉載于:https://juejin.im/post/5c866629f265da2d8d6a1466

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

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

相關文章

面對 this 指向丟失,尤雨溪在 Vuex 源碼中是怎么處理的

1. 前言大家好,我是若川。好久以前我有寫過《面試官問系列》,旨在幫助讀者提升JS基礎知識,包含new、call、apply、this、繼承相關知識。其中寫了 面試官問:this 指向 文章。在掘金等平臺收獲了還算不錯的反饋。最近有小伙伴看我的…

轉:Python: threading.local是全局變量但是它的值卻在當前調用它的線程當中

原文地址:http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213958.html 在threading module中,有一個非常特別的類local。一旦在主線程實例化了一個local,它會一直活在主線程中,并且又主線程啟動的子線程調用這個local實例時&#xff0c…

matlab的邊緣檢測方法,常用圖像邊緣檢測方法及Matlab研究

2011 年 2 月 15 日第 34 卷第 4 期 現代電子技術 Modern Electronics Technique Feb. 2011 Vol. 34 No. 4 常用圖像邊緣檢測方法及 Matlab 研究 韋  煒 (西安文理學院 , 陜西 西安   710065) 摘  要 :邊緣檢測在數字圖像處理中有著重要的作用。為了在實際應用中能夠選擇最佳…

單選按鈕步驟流程向導 js_創建令人愉快的按鈕的6個步驟

單選按鈕步驟流程向導 jsThere is no modern interactive UI without buttons. They are an fundamental part of every digital solution. Learn how to improve the style of your buttons and delight users with perfect style.沒有按鈕,就沒有現代的交互式UI。…

Android 四大組件之 Activity

什么是 Activity? Activity 是 Android 的四大組件之一,是用戶操作的可視化界面,它為用戶提供了一個完成操作指令的窗口。 當我們創建完 Activity 之后,需要調用 setContentView(view) 方法來完成界面的顯示,以此來為用…

axios怎么封裝,才能提升效率?

大家好,我是若川。今天分享一篇axios封裝的文章。學習源碼系列、面試、年度總結、JS基礎系列。作為前端開發者,每個項目基本都需要和后臺交互,目前比較流行的ajax庫就是axios了,當然也有同學選擇request插件,這個蘿卜白…

圖片有花

http://www.56.com/u50/v_NTUwMzE1NDM.html http://www.56.com/u39/v_NTUwMzE2MjA.html http://www.cnblogs.com/coffee_cn/archive/2009/11/30/1613823.html http://www.imagemagick.org/script/binary-releases.php?ImageMagickmm3e9bn5mtos6eiaelh9d4aoe4#windows 轉載于:h…

java 代碼執行el,專屬于java的漏洞——EL表達式注入

前言“FSRC經驗分享”系列文章,旨在分享焦點科技信息安全部工作過程中的經驗總結,包括但不限于漏洞分析、運營技巧、sdl推行、等保合規、自研工具等等。歡迎各位安全從業者持續關注~0x01EL簡介表達式語言(Expression Language 以下簡稱EL)是以JSTL(JavaS…

護膚產生共鳴_通過以人為本的設計編織共鳴的20個指針

護膚產生共鳴Deep into a project right now, I can’t help but reflect on how I practice empathy in design. Human centered design means empathising with and designing for people, keeping our focus on people throughout. It is not just one stage, it is a minds…

谷歌已推送 Android Q Beta 1

開發四年只會寫業務代碼,分布式高并發都不會還做程序員? >>> 今日凌晨,谷歌正式推送了 Android Q 的首個 Beta 版本,Pixel 全系列手機可以嘗鮮體驗這款最新的系統。 據官方博客介紹,Android Q 為用戶帶來了…

對使用CodeSmith模板生成NHibernate的代碼的分析

CodeSmith是我們常用的代碼生成工具,其跟據不同的模板生成不同代碼的方式能大大加快我們的項目開發,減少重復勞動。NHibernate模板就是其常用模板之一。從這里可以下載到最新的模板文件。現在最新的版本為NHibernate-v1.2.1.2125,可以生成NHi…

若川誠邀你加源碼共讀群,每周一起學源碼

小提醒:若川視野公眾號面試、源碼等文章合集在菜單欄中間【源碼精選】按鈕,歡迎點擊閱讀,也可以星標我的公眾號,便于查找。回復pdf,可以獲取前端優質書籍。最近我創建了一個源碼共讀的前端交流群,希望嘗試幫…

matlab 規范,matlab-代碼-規范

matlab-代碼-規范 1. 標識符命名原則 標識符的名字應當直觀,其長度應當符合“最小長度,最大信息量”原則。 1) 非矩陣變量: 變量名應該以小寫字母開頭的大小寫混合形式 譬如:shadowFadingTable,servingSector&#xf…

zoom視頻會議官網_人性化視頻會議的空間(Zoom等)

zoom視頻會議官網第二部分:房間的創造力 (Part Two: The Creativity of Rooms) In Part One I shared thoughts on how virtual spaces can often leave little room to embody our most human selves. The lack of a public sphere that parallels our shared publ…

KOFLive Postmortem

為期兩個月的團隊項目完成了,我們的游戲也已經發布。在這個名叫KOFLive的小游戲里,我們集成了五個真人角色,每個角色有拳腳基本招數以及三個小招、一個大招,硬值、防御、集氣、雙人對戰、人機對戰、練習模式等格斗游戲的Feature基…

單調隊列優化多重背包

就是按照 % 體積的余數來分組&#xff0c;每組單調隊列優化。 直接上模板好了。 1 #include <bits/stdc.h>2 3 typedef long long LL;4 const int N 100010;5 6 int n, V, cnt[N], cost[N];7 LL f[2][N], val[N], p[N], top, head;8 9 inline void Max(LL &a, const…

2021年7月 蝦皮、貨拉拉、有贊等面經總結

大家好&#xff0c;我是若川&#xff0c;加我微信 ruochuan12 進源碼交流群。今天分享一篇7月份新鮮出爐的面經&#xff0c;文章較長&#xff0c;可以收藏再看。學習源碼系列、面試、年度總結、JS基礎系列。本文來自作者幾米陽光 投稿 原文鏈接&#xff1a;https://juejin.cn/p…

Oracle對表名大小寫敏感嗎,讓Oracle 大小寫敏感 表名 字段名 對像名

一、解決方案1、在表名、字段名、對象名上加上雙引號&#xff0c;即可實現讓oracle大小寫區分。2、但是這又引起了另一個問題&#xff1a;在數據庫操作中&#xff0c;sql語句中相應的表名、字段名、對象名上一定要加雙引號。解決辦法是&#xff1a;使用"\"轉義。如&a…

谷歌抽屜_Google(最終)會殺死導航抽屜嗎?

谷歌抽屜A couple of months ago Google has celebrated with enthusiasm 15 years of Google Maps, one of the most used and appreciated services worldwide from the company.幾個月前&#xff0c;Google熱情地慶祝Google Maps誕生15周年&#xff0c;這是該公司在全球范圍…

MySQL——安裝

MySQL——安裝 1. 下載源&#xff1a; http://repo.mysql.com/yum/mysql-8.0-community/el/7/x86_64/mysql80-community-release-el7-2.noarch.rpm 該源目前為8.0版本&#xff0c;如果需要最新請退至根目錄找。 1wget http://repo.mysql.com/yum/mysql-8.0-community/el/7/x86_…