webrtc 視頻 demo

webrtc 視頻 demo

webrtc網上封裝的很多,demo很多都是一個頁面里實現的,今天實現了個完整的 , A 發視頻給 B

A webrtc.html作為offer?

復制代碼
<!DOCTYPE html>
<html id="home" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scal
able=no"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><style>p { padding: 1em; }li {border-bottom: 1px solid rgb(189, 189, 189);border-left: 1px solid rgb(189, 189, 189);padding: .5em;}</style></head><body><script>var mediaConstraints = {optional: [],mandatory: {OfferToReceiveAudio: false,OfferToReceiveVideo: true}};</script><script>var offerer,answererWinwindow.RTCPeerConnection = window.mozRTCPeerConnection || window.webkit
RTCPeerConnection;window.RTCSessionDescription = window.mozRTCSessionDescription || windo
w.RTCSessionDescription;window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCand
idate;navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitG
etUserMedia;window.URL = window.webkitURL || window.URL;window.iceServers = {iceServers: [{url: 'stun:23.21.150.121'}]};</script><script>/* offerer */function offererPeer(video_stream) {offerer = new RTCPeerConnection(window.iceServers)offerer.addStream(video_stream)offerer.onaddstream = function (event) {// 本地顯示video}offerer.onicecandidate = function (event) {if (!event || !event.candidate) returnsendToP2({'action' : 'candidate','candidate' :event.candidate})}offerer.createOffer(function (offer) {offerer.setLocalDescription(offer)sendToP2({'action' : 'create','offer':offer})}, function() {}, mediaConstraints)}</script><script>var video_constraints = {mandatory: {},optional: []}function getUserMedia(callback) {var n = navigatorn.getMedia = n.webkitGetUserMedia || n.mozGetUserMedian.getMedia({audio: false,video: video_constraints}, callback, onerror)function onerror(e) {alert(JSON.stringify(e, null, '\t'))}}</script><script>function sendToP2(data){answererWin.postMessage(JSON.stringify(data) ,
window.location)}function receiveMessage(data){data = JSON.parse(data.data)switch ( data.action) {case 'answer' :offerer.setRemoteDescription(ne
w RTCSessionDescription(data.answer))breakcase "candidate":offerer.addIceCandidate(new RTC
IceCandidate(data.candidate))break}console.log('msg' ,data)}window.addEventListener("message", receiveMessage, fals
e)answererWin = window.open('webrtc2.html' ,'t')getUserMedia(function (video_stream) {offererPeer(video_stream)});</script></body></html>
復制代碼

?

B?webrtc2.html 作為answer

?

復制代碼
<!DOCTYPE html>
<html id="home" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css"><style>audio, video {-moz-transition: all 1s ease;-ms-transition: all 1s ease;-o-transition: all 1s ease;-webkit-transition: all 1s ease;transition: all 1s ease;vertical-align: top;}p { padding: 1em; }li {border-bottom: 1px solid rgb(189, 189, 189);border-left: 1px solid rgb(189, 189, 189);padding: .5em;}.videos-container {display: inline-block;border: 2px solid black;padding: .1em;border-radius: 0.2em;margin: 2em .2em;background: white;vertical-align: top;}.videos-container h2 {border: 0;border-top: 1px solid black;margin: 0;text-align: center;display:block;}video {width:20em;height: 15em;background: black;}</style><!-- for HTML5 el styling --><script>document.createElement('article');</script></head><body><article><div style="text-align:center;"><div class="videos-container"><video id="peer1-to-peer2" autoplay controls></video><h2>Offerer-to-Answerer</h2></div></div><script>var mediaConstraints = {optional: [],mandatory: {OfferToReceiveAudio: true,OfferToReceiveVideo: true}};</script><script>var offerer, answerer;var offererToAnswerer = document.getElementById('peer1-to-peer2');window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;window.URL = window.webkitURL || window.URL;window.iceServers = {iceServers: [{url: 'stun:23.21.150.121'}]};</script><script>/* answerer */function answererPeer(offer, video_stream) {answerer = new RTCPeerConnection(window.iceServers);// answerer.addStream(video_stream);answerer.onaddstream = function (event) {offererToAnswerer.src = URL.createObjectURL(event.stream);offererToAnswerer.play();};answerer.onicecandidate = function (event) {if (!event || !event.candidate) return;sendToP1({'action' : 'candidate','candidate' :event.candidate})//offerer.addIceCandidate(event.candidate);};answerer.setRemoteDescription(new RTCSessionDescription(offer));answerer.createAnswer(function (answer) {answerer.setLocalDescription(answer);sendToP1({'action' : 'answer' ,'answer' : answer})//offerer.setRemoteDescription(answer);}, function() {}, mediaConstraints);}function receiveMessage(data){data = JSON.parse(data.data)console.log(data)switch(data.action){case "create":answererPeer(data.offer , data.stream)breakcase "candidate":answerer.addIceCandidate(new RTCIceCandidate(data.candidate))break}}window.addEventListener("message", receiveMessage, false)function sendToP1(data) {opener.postMessage(JSON.stringify(data) , window.location)}</script></article></body></html>
復制代碼

?

demo用 postMessage傳遞數據, 業務使用可以用websocket

A 先?createOffer ,生成的offer 供自己setLocalDescription ,并發給B

B 拿A的offer ,setRemoteDescription(offer) ,?然后?createAnswer ,生成的answer?供自己setLocalDescription ,并發給A

A 拿B的answer 設置?setRemoteDescription(answer)

?

?

A?onicecandidate 事件被觸發 將得到的通道發給B

B?addIceCandidate(new RTCIceCandidate(candidate)) 建立通道

B?onicecandidate 事件被觸發 將得到的通道發給A

A addIceCandidate(new RTCIceCandidate(candidate)) 建立通道

?

通道建立后視頻就可以共享了

?

參考網址

http://www.html5rocks.com/en/tutorials/webrtc/basics/?redirect_from_locale=fr
https://github.com/muaz-khan/WebRTC-Experiment/blob/master/demos/client-side.html

轉載于:https://www.cnblogs.com/developer-ios/p/6517348.html

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

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

相關文章

條件注釋判斷瀏覽器版本!--[if lt IE 9](轉載)

<!--[if !IE]><!--> 除IE外都可識別 <!--<![endif]--> <!--[if IE]> 所有的IE可識別 <![endif]--> <!--[if IE 6]> 僅IE6可識別 <![endif]--> <!--[if lt IE 6]> IE6以及IE6以下版本可識別 <![endif]--> <!--[if …

[轉]阿里開源低代碼引擎LowCodeEngine

一、什么是低代碼引擎 低代碼引擎是具備強大擴展能力的低代碼研發框架&#xff0c;使用者只需要基于低代碼引擎便可以快速定制符合自己業務需求的低代碼平臺。同時&#xff0c;低代碼引擎還在標準低代碼設計器的基礎上提供了簡單易用的定制擴展能力&#xff0c;能夠滿足業務獨特…

Beyond Istio OSS——Istio服務網格的現狀與未來

作者&#xff1a;宋凈超&#xff08;Jimmy Song&#xff09;&#xff0c;原文地址&#xff1a;https://jimmysong.io/blog/beyond-istio-oss/本文根據筆者在 GIAC 深圳 2022 年大會上的的演講《Beyond Istio OSS —— Istio 的現狀及未來》[1] 整理而成&#xff0c;演講幻燈片見…

js多維數組扁平化

數組扁平化&#xff0c;就是將多維數組碾平為一維數組&#xff0c;方便使用。 一&#xff1a;例如&#xff0c;一個二維數組 var arr [a, [b, 2], [c, 3, x]]&#xff0c;將其扁平化&#xff1a; 1. 通過 apply 借用數組的 concat 方法&#xff1a; [].concat.apply([], arr)…

第16講 用戶程序的結構與執行

轉載于:https://www.cnblogs.com/atuo/p/5609843.html

兩種方法清除Excel保護密碼

一、利用VBA腳本直接清除 打Excel&#xff0c;打開腳本編輯器&#xff08;AltF11&#xff09;或者如圖&#xff0c;右鍵sheet名稱 輸入代碼并運行&#xff0c;即可清除密碼保護&#xff1a; Sub DeletePW()ActiveSheet.Protect DrawingObjects:True, Contents:True, AllowFil…

jsonp-反向代理-CORS解決JS跨域問題的個人總結

jsonp-反向代理-CORS解決JS跨域問題的個人總結 網上說了很多很多&#xff0c;但是看完之后還是很混亂&#xff0c;所以我自己重新總結一下。解決 js 跨域問題一共有8種方法&#xff0c; jsonp&#xff08;只支持 get&#xff09;反向代理CORSdocument.domain iframe 跨域windo…

URAL 1682 Crazy Professor (并查集)

【題目鏈接】 http://acm.timus.ru/problem.aspx?space1&num1682 【題目大意】 給出k&#xff0c;從1開始不斷地加一并把這個數寫在黑板上&#xff0c;如果寫上的數字和之前的數字滿足   (ab*b)%k0或者(ba*a)%k0就在他們之間連一條線&#xff0c;如果黑板上出現環就結束…

利用Python隨機或暴力生成密碼

""" Title: python 密碼生成 Author: JackieZheng Date: 2022-04-09 12:47:33 LastEditTime: 2022-04-09 14:00:46 LastEditors: Please set LastEditors Description: FilePath: \\pythonCode\\python_pwd_generater.py """import itertools im…

EasyNetQ-用于使用 RabbitMQ 的 .NET API開源的工具庫

Part1介紹EasyNetQ 的目標是提供一個庫&#xff0c;用于在 .NET 中使用 RabbitMQ 盡可能簡單。為了做到這一點&#xff0c;它通過強制執行一些簡單的約定來以靈活性換取簡單性。這些包括&#xff1a;消息應該由 .NET 類型表示。消息應按其 .NET 類型進行路由。這意味著消息是由…

python 中 __name__ 的使用

1. 如果模塊是被導入&#xff0c;__name__的值為模塊名字2. 如果模塊是被直接執行&#xff0c;__name__的值為’__main__’Py1.py #&#xff01;/usr/bin/env python def test():print __name__ ,__name__ if __name__ __main__:test() Py2.py #&#xff01;/usr/bin/env pyt…

第6章 循環

6.1 range 函數用來創建一個數字列表&#xff0c;它的范圍是從起始數字開始到結束數字之前 1 >>> for x in range(0,5): 2 print(Hello %s % x) 3 4 Hello 0 5 Hello 1 6 Hello 2 7 Hello 3 8 Hello 4 1 >>> print(list(range(10,20))) 2 [10, 11, 12, …

C# 實例解釋面向對象編程中的依賴反轉原則

在面向對象編程中&#xff0c;SOLID 是五個設計原則的首字母縮寫&#xff0c;旨在使軟件設計更易于理解、靈活和可維護。這些原則是由美國軟件工程師和講師羅伯特C馬丁(Robert Cecil Martin)提出的許多原則的子集&#xff0c;在他2000年的論文《設計原則與設計模式》中首次提出…

Linux學習筆記之一————什么是Linux及其應用領域

1.1認識Linux 1&#xff09;什么是操作系統 2&#xff09;現實生活中的操作系統 win7 Mac Android iOS 3&#xff09; 操作系統的發展史 &#xff08;1&#xff09;Unix 1965年之前的時候&#xff0c;電腦并不像現在一樣普遍&#xff0c;它可不是一般人能碰的起的&#xff0c;…

Flex中寬度計算

flex 有三個屬性值&#xff0c;分別是 flex-grow&#xff0c; flex-shrink&#xff0c; flex-basis&#xff0c;默認值是 0 1 auto。 發現網上詳細介紹他們的文章比較少&#xff0c; 今天就詳細說說他們&#xff0c;先一個一個看。 flex-grow 定義項目的放大比例&#xff0c;默…

Lucene詳解

一.lucene原理 Lucene 是apache軟件基金會一個開放源代碼的全文檢索引擎工具包&#xff0c;是一個全文檢索引擎的架構&#xff0c;提供了完整的查詢引擎和索引引擎&#xff0c;部分文本分析引擎。它不是一個完整的搜索應用程序&#xff0c;而是為你的應用程序提供索引和搜索功能…

.NET 6.0中使用Identity框架實現JWT身份認證與授權

原文作者&#xff1a;Sarathlal Saseendran原文鏈接&#xff1a;https://www.c-sharpcorner.com/article/jwt-authentication-and-authorization-in-net-6-0-with-identity-framework/翻譯&#xff1a;沙漠盡頭的狼&#xff08;谷歌翻譯加持&#xff09;介紹微軟于 2021 年 11 …

adb devices 里面有很多 emulator-XXXX的解決方法

2019獨角獸企業重金招聘Python工程師標準>>> adb kill-server 轉載于:https://my.oschina.net/sfshine/blog/700354

MQ(Message Queue)簡介

一、何為MQ&#xff1f; MQ全稱為Message Queue, 消息隊列&#xff08;MQ&#xff09;是一種應用程序對應用程序的通信方法。應用程序通過讀寫出入隊列的消息&#xff08;針對應用程序的數據&#xff09;來通信&#xff0c;而無需專用連接來鏈接它們。消息傳遞指的是程序之間通…

【GlobalMapper精品教程】015:矢量面圖層的創建及數字化操作

本文講解在Globalmapper中文23.0中創建矢量面狀數據(政區數據),并進行面狀數據采集及編輯的詳細操作流程,數據為配套案例數據包中的data015.rar。 參考閱讀: ArcGIS實驗教程——實驗三:矢量數據采集與編輯(矢量化) 文章目錄 一、認識工具條1. 數字化(創建)工具條2. 選…