一、 什么是 WebRTC
想象一下一个这样的世界:你能利用你的手机、或你的电脑,或电视在一个公共的平台——web浏览器上与他人交流,这样人与人之间的沟通,文件分享该有多便利啊。利用WebRTC(web real time communication)就能做到这点。
二、 WebRTC API 介绍
WebRTC is a new front in the long war for an open and unencumbered web. —— Brendan Eich
WebRTC实现了下列三个 API:
(1)MediaStream(别名 getUserMedia)
(2)RTCPeerConnection
(3)RTCDataChannel
利用 getUserMedia 可以从设备上获取数据流,比如说摄像头和麦克风。
利用 RTCPeerConnection 能够实现音视频通话,包括设备加密和带宽管理。
利用 RTCDataChannel 可以实现 p2p 通话。(其实我现在还没有理解它的作用, ~~o(>_<)o ~~)
三、 getUserMedia 介绍
我们直接从例子开始吧。(demo网址:https://simpl.info/getusermedia)
这个 demo 是HTML+JavaScript 写的,主要包括两个文件:index.html(用于构造简单的HTML页面)以及 main.js(JavaScript 脚本文件),可以在点击 demo下面的 View source on GitHub 链接按钮查看这两个源代码文件,关于 index.html 构造界面的内容我就不讲述了,我简单讲一下 main.js 文件中对于 getUserMedia 这个API的使用吧。
(1)用法
getUserMedia 这个 API 实际名字叫 MediaDevices.getUserMedia()。
MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise会reject回调一个 PermissionDeniedError 或者 NotFoundError 。
通常你可以使用 navigator.mediaDevices 来获取 MediaDevices ,例如:
- 1.
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) { /* 使用这个stream stream */ })
.catch(function(err) { /* 处理error */ });
(2)在 main.js 中的使用。
main.js 代码:
constrains 中的内容表示要获取的媒体流的类型(audio 为 true 表示要获取音频流, video 为 true 表示要获取视频流),而在main.js 中只获取视频流。
then 里面的函数表示当获取指定的媒体流成功后,应当由 handleSuccess 这个函数来把 video 的 src 属性设置为已获取的媒体流,这样你才能在demo网页中看到自己摄像头所显示的内容。
catch 里面的函数表示当获取指定的媒体流失败后,应当有 handleError 这个函数来处理,在 console 里面输出错误日志。
四、用 peer.js 简单实现两人聊天室
源代码如下:
Index.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="peer.js"></script>
<script type="text/javascript" src="ps-webrtc-peerjs-start.js"></script>
</head>
<body>
<div id="video-container">
Your Friend<video id="their-video" autoplay class="their-video"></video>
<video id="my-video" muted="true" autoplay class="my-video"></video>You
</div>
<div>
<h2>Super-simple PeerJS video chat with manual signaling</h2>
<div id="step1">
<p>please click allow</p>
<div id="step1-error">
<p>failed</p>
<a href="#" id="step1-retry" class="button">Try again</a>
</div>
</div>
<div id="step2">
<p>Your id:<span id="my-id">...</span></p>
<p> share this id</p>
<p><span id="subhead">Make a call</span><br/>
<input type="text" placeholder="Call user id..." id="callto-id">
<a href="#" id="make-call">Call</a>
</p>
</div>
<div id="step3">
<p>Currently in call with <span id="their-id">...</span></p>
<p><a href="#" id="end-call">End call</a></p>
</div>
</div>
</body>
</html>
ps-webrtc-peerjs-start.js:
navigator.getWebcam=( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var peer = new Peer({
debug:3,
config:{'iceServers': [
{ url:'turn:numb.viagenie.ca',username:"your_id",credential:"your_password"}
]}});
peer.on('open',function(){
$('#my-id').text(peer.id);
});
peer.on('call',function(call){
call.answer(window.localstream);
step3(call);
});
$(function() {
$('#make-call').click(function(){
var call = peer.call($('#callto-id').val(),window.localstream);
step3(call);
});
$('#end-call').click(function(){
window.existingCall.close();
step2();
});
$('#step1-retry').click(function(){
$('#step1-error').hide();
step();
});
step1();
});
function step1(){
navigator.getWebcam({audio:false,video:true},function(stream){
$('#my-video').prop('src',URL.createObjectURL(stream));
window.localstream=stream;
step2();
},function () {$('#step1-error').show();});
}
function step2() {
$('#step1','#step3').hide();
$('#step2').show();
}
function step3(call) {
if(window.existingCall){
window.existingCall.close();
}
call.on('stream',function(stream){
$('#their-video').prop('src',URL.createObjectURL(stream));
});
$('#step1','#step2').hide();
$('#step3').show();
}
在服务器上运行后如下图所示(可是不知道为什么我不能和其他用户正常连接 o(╥﹏╥)o),不知道大家能不能帮我找一下原因。
参考博客:
https://www.html5rocks.com/en/tutorials/webrtc/basics/
https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia