webrtc服务器搭建怎样将接收到的stream打包成rtc包

19.简单了解的 HTML5 WebRTC
(window.slotbydup=window.slotbydup || []).push({
id: '2611110',
container: s,
size: '240,200',
display: 'inlay-fix'
您当前位置: &
[ 所属分类
| 时间 2015 |
作者 红领巾 ]
WebRTC是Web Real-Time Communication(网页实时通信)。WebRTC 包含有三个组件:
访问用户摄像头及麦克风的 getUserMedia
穿越 NAT 及防火墙建立视频会话的 PeerConnection
在浏览器之间建立点对点数据通讯的 DataChannels
分别对应三个API接口:
Network Stream API 代表媒体数据流
RTCPeerConnection 一个RTCPeerConnection对象允许用户在两个浏览器之间直接通讯;
Peer-to-peer Data API 一个在两个节点之间的双向的数据通道
浏览器对 WebRTC 的支持
最新支持成都可在
pc上浏览器的支持情况
pc浏览器对WebRTC的支持情况
Andriod chrome浏览器从29版开始支持webRTC,但是默认关闭,如果不能正常使用webRTC,请在chrome://flags,开启webRTC
移动端的浏览器支持情况
iOS 还不支持,不过苹果很快会支持
WebRTC API
MediaStream
getUserMedia()与WebRTC相关,因为它是通向这组API的门户。它提供了访问用户本地相机/麦克风媒体流的手段。在移动设备上,目前只有andriod中webview内核为36或者大于36才支持(即只有andriod L或者更高版本),ios设备暂时还不支持。
各家浏览器对getUserMedia支持不同,因此在使用该API之前需要检测用户浏览器是否支持getUserMedia
function hasGetUserMedia() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
浏览器出于安全考虑,在请求网络摄像头或麦克风时,会弹出信息栏,让用户选择授予还是拒绝对其相机/麦克风的访问权限。
getUserMedia()需要传递三个参数,第一个参数用于指定你要访问的媒体类型, 第二个参数是成功获取媒体数据流后的回调函数,第三个参数为获取媒体数据流失败的处理函数,相关API文档可以参考: getUserMedia
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.moZGetUserMedia || navigator.msGetUserM
var video = document.querySelector('video');
navigator.getUserMedia({
audio : true,
video : true
}, function (stream) {
video.src = window.URL.creatObjectURL(stream);
}, function (error) {
console.log(error);
这样就可以通过video标签成功将视频流输出到页面上。
截取视频截图
可以通过canvas的API: ctx.drawImage(video, 0, 0)将video的某一帧绘制到canvas上,再通过canvas的canvas.toDataURL('image/png')将canvas绘制的东西转为图片。
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
navigator.getUserMedia({
audio: true,
video: true
}, function(stream) {
video.src = window.URL.creatObjectURL(stream);
}, function(error) {
console.log(error);
video.addEventListener('click', function() {
ctx.drawImage(video, 0, 0);
var img = new Image();
img.src = canvas.toDataURL('image/png');
document.appendChild(img);
给图片添加滤镜
canvas 可以获取每一个像素点得颜色值(包括red, green, blue, alpha四个值),通过 canvas 的 API: ctx.getImageData() 获取到的所有像素点的颜色值,修改对应的像素值之后,可以通过 ctx.putImageData() 将像素点重新绘制到 canvas 中
var imgData = ctx.getImageData();
var filter = {
// 灰度效果
grayscale: function(pixels) {
var d = pixels.
for (var i = 0, len = d. i & i += 4) {
var r = d[i],
g = d[i + 1],
b = d[i + 2];
d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3;
// 复古效果
sepia: function(pixels) {
var d = pixels.
for (var i = 0, len = d. i & i += 4) {
var r = d[i],
g = d[i + 1],
b = d[i + 2];
d[i] = (r * 0.393) + (g * 0.769) + (b * 0.189);
d[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168);
d[i + 2] = (r * 0.272) + (g * 0.534) + (b * 0.131);
// 红色蒙版效果
red: function(pixels) {
var d = pixels.
for (var i = 0, len = d. i & i += 4) {
var r = d[i],
g = d[i + 1],
b = d[i + 2];
d[i] = (r + g + b) / 3;
d[i + 1] = d[i + 2] = 0;
// 反转效果
invert: function(pixels) {
var d = pixels.
for (var i = 0, len = d. i & i += 4) {
var r = d[i],
g = d[i + 1],
b = d[i + 2];
d[i] = 255 -
d[i + 1] = 255 -
d[i + 2] = 255 -
ctx.putImageData(filter[type](imgData));
navigator.getUserMedia()可以和web Audio API相结合,用来处理音频效果
var range = document.querySelector('input');
window.AudioContext = window.AudioContext || window.webkitAudioC
var audioCtx = new AudioContext();
navigator.getUserMedia({
audio: true
}, function(stream) {
// 创建音频流
var source = audioCtx.createMediaStreamSource(stream);
// 双二阶滤波器
var biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = 'lowshelf';
biquadFilter.frequenc.value = 1000;
biquadFilter.gain.value = range.
source.connect(biquadFilter);
biquadFilter.connect(audioCtx.destination);
}, function(error) {
console.log(error);
RTCPeerConnection
RTCPeerConnection,用于peer跟peer之间呼叫和建立连接以便传输音视频数据流;
WebRTC是实现peer to peer的实时通信(可以两个或多个peer之间),在能够通信前peer跟peer之间必须建立连接,这是RTCPeerConnection的任务,为此需要借助一个信令服务器(signaling server)来进行,信令包括3种类型的信息:
Session control messages: 初始化和关闭通信,及报告错误;
Network configuration: 双方的IP地址和端口号(局域网内部IP地址需转换为外部的IP地址);
Media capabilities: 双方的浏览器支持使用何种codecs以及多高的视频分辨率。
var PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerC
navigator.getUserMedia = navigator.getUserMedia ? "getUserMedia" :
navigator.mozGetUserMedia ? "mozGetUserMedia" :
navigator.webkitGetUserMedia ? "webkitGetUserMedia" : "getUserMedia";
var v = document.createElement("video");
// 创建信令
var pc = new PeerConnection();
pc.addStream(video);
pc.createOffer(function(desc) {
pc.setLocalDescription(desc, function() {
// send the offer to a server that can negotiate with a remote client
// 创建回复
var pc = new PeerConnection();
pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer, function() {
// send the answer to the remote connection
peer跟peer之间一旦建立连接就可以直接传输音视频数据流,并不需要借助第三方服务器中转。
具体文档可以查看: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection。
RTCDataChannel
RTCDataChannel可以建立浏览器之间的点对点通讯。常用的通讯方式有webSocket, ajax和 Server Sent Events等方式,websocket虽然是双向通讯,但是无论是websocket还是ajax都是客户端和服务器之间的通讯,这就意味着你必须配置服务器才可以进行通讯。而RTCDATAChannel采用另外一种实现方式
它使用webRTC的另外一个API:RTCPeerConnection,RTCPeerConnection无需经过服务器就可以提供点对点之间的通讯,避免服务器这个中间件
RTCDataChannel支持SCTP机制,SCTP实际上是一个面向连接的协议,但SCTP偶联的概念要比TCP的连接具有更广的概念,SCTP对TCP的缺陷进行了一些完善,使得信令传输具有更高的可靠性,SCTP的设计包括适当的拥塞控制、防止泛滥和伪装攻击、更优的实时性能和多归属性支持。
WebRTC并未规定使用何种信令机制和消息协议,象SIP、XMPP、XHR、WebSocket这些技术都可以用作WebRTC的信令通信。
除了信令服务器,peer跟peer建立连接还需要借助另一种服务器(称为STUN server)实现NAT/Firewall穿越,因为很多peer是处于私有局域网中,使用私有IP地址,必须转换为公有IP地址才能相互之间传输数据。这其中涉及到一些专业术语包括STUN、TURN、ICE等,其实我对这些概念也不是很理解。网上找到的WebRTC demo好象都用的是Google提供的STUN server。
参考文章: /en/tutorials/webrtc/datachannels/?redirect_from_locale=zh
https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel
WebRTC的目的是为了简化基于浏览器的实时数据通信的开发工作量,但实际应用编程还是有点复杂,尤其调用RTCPeerConnection必须对如何建立连接、交换信令的流程和细节有较深入的理解。因此我们可以使用已经封装好的WebRTC库,这些WebRTC库对原生的webRTC的API进行进一步的封装,包装成更简单的API接口。同时屏蔽了不同浏览器之间的差异。
目前网上主要有两种WebRTC的封装库:
WebRTC.io github地址为: /webRTC/webRTC.io
simpleWebRTC github地址为: /HenrikJoreteg/SimpleWebRTC
最后是用WebRTC写的一个小demo: http://ccforward.github.io/demos/webrtc/index.html
关于 WebRTC 的相关文章推荐: /en/tutorials/webrtc/basics/
转载请注明本文标题:本站链接:
分享请点击:
1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
阅读(1321)
CodeSecTeam微信公众号
既然降生到这世上,我就要好好看看它,找到属于自己的世界第一。
手机客户端WebRTC -- JavaScript 标准参考教程(alpha)
来自,by 阮一峰
WebRTC是“网络实时通信”(Web Real Time Communication)的缩写。它最初是为了解决浏览器上视频通话而提出的,即两个浏览器之间直接进行视频和音频的通信,不经过服务器。后来发展到除了音频和视频,还可以传输文字和其他数据。
Google是WebRTC的主要支持者和开发者,它最初在Gmail上推出了视频聊天,后来在2011年推出了Hangouts,语序在浏览器中打电话。它推动了WebRTC标准的确立。
WebRTC主要让浏览器具备三个作用。
获取音频和视频
进行音频和视频通信
进行任意数据的通信
WebRTC共分成三个API,分别对应上面三个作用。
MediaStream (又称getUserMedia)
RTCPeerConnection
RTCDataChannel
getUserMedia
navigator.getUserMedia方法目前主要用于,在浏览器中获取音频(通过麦克风)和视频(通过摄像头),将来可以用于获取任意数据流,比如光盘和传感器。
下面的代码用于检查浏览器是否支持getUserMedia方法。
navigator.getUserMedia
= navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (navigator.getUserMedia) {
Chrome 21, Opera 18和Firefox 17,支持该方法。目前,IE还不支持,上面代码中的msGetUserMedia,只是为了确保将来的兼容。
getUserMedia方法接受三个参数。
navigator.getUserMedia({
video: true,
audio: true
}, onSuccess, onError);
getUserMedia的第一个参数是一个对象,表示要获取哪些多媒体设备,上面的代码表示获取摄像头和麦克风;onSuccess是一个回调函数,在获取多媒体设备成功时调用;onError也是一个回调函数,在取多媒体设备失败时调用。
下面是一个例子。
var constraints = {video: true};
function onSuccess(stream) {
var video = document.querySelector("video");
video.src = window.URL.createObjectURL(stream);
function onError(error) {
console.log("navigator.getUserMedia error: ", error);
navigator.getUserMedia(constraints, onSuccess, onError);
如果网页使用了getUserMedia方法,浏览器就会询问用户,是否同意浏览器调用麦克风或摄像头。如果用户同意,就调用回调函数onSuccess;如果用户拒绝,就调用回调函数onError。
onSuccess回调函数的参数是一个数据流对象stream。stream.getAudioTracks方法和stream.getVideoTracks方法,分别返回一个数组,其成员是数据流包含的音轨和视轨(track)。使用的声音源和摄影头的数量,决定音轨和视轨的数量。比如,如果只使用一个摄像头获取视频,且不获取音频,那么视轨的数量为1,音轨的数量为0。每个音轨和视轨,有一个kind属性,表示种类(video或者audio),和一个label属性(比如FaceTime HD Camera (Built-in))。
onError回调函数接受一个Error对象作为参数。Error对象的code属性有如下取值,说明错误的类型。
PERMISSION_DENIED:用户拒绝提供信息。
NOT_SUPPORTED_ERROR:浏览器不支持硬件设备。
MANDATORY_UNSATISFIED_ERROR:无法发现指定的硬件设备。
范例:获取摄像头
下面通过getUserMedia方法,将摄像头拍摄的图像展示在网页上。
首先,需要先在网页上放置一个video元素。图像就展示在这个元素中。
&video id="webcam"&&/video&
然后,用代码获取这个元素。
function onSuccess(stream) {
var video = document.getElementById('webcam');
接着,将这个元素的src属性绑定数据流,摄影头拍摄的图像就可以显示了。
function onSuccess(stream) {
var video = document.getElementById('webcam');
if (window.URL) {
video.src = window.URL.createObjectURL(stream);
video.src = stream;
video.autoplay = true;
// 或者 video.play();
if (navigator.getUserMedia) {
navigator.getUserMedia({video:true}, onSuccess);
document.getElementById('webcam').src = 'somevideo.mp4';
在Chrome和Opera中,URL.createObjectURL方法将媒体数据流(MediaStream)转为一个二进制对象的URL(Blob URL),该URL可以作为video元素的src属性的值。 在Firefox中,媒体数据流可以直接作为src属性的值。Chrome和Opera还允许getUserMedia获取的音频数据,直接作为audio或者video元素的值,也就是说如果还获取了音频,上面代码播放出来的视频是有声音的。
获取摄像头的主要用途之一,是让用户使用摄影头为自己拍照。Canvas API有一个ctx.drawImage(video, 0, 0)方法,可以将视频的一个帧转为canvas元素。这使得截屏变得非常容易。
&video autoplay&&/video&
&img src=""&
&canvas style="display:"&&/canvas&
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var localMediaStream = null;
function snapshot() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
// “image/webp”对Chrome有效,
// 其他浏览器自动降为image/png
document.querySelector('img').src = canvas.toDataURL('image/webp');
video.addEventListener('click', snapshot, false);
navigator.getUserMedia({video: true}, function(stream) {
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream;
}, errorCallback);
范例:捕获麦克风声音
通过浏览器捕获声音,需要借助Web Audio API。
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
var context = new AudioContext();
function onSuccess(stream) {
var audioInput = context.createMediaStreamSource(stream);
audioInput.connect(context.destination);
navigator.getUserMedia({audio:true}, onSuccess);
捕获的限定条件
getUserMedia方法的第一个参数,除了指定捕获对象之外,还可以指定一些限制条件,比如限定只能录制高清(或者VGA标准)的视频。
var hdConstraints = {
mandatory: {
minWidth: 1280,
minHeight: 720
navigator.getUserMedia(hdConstraints, onSuccess, onError);
var vgaConstraints = {
mandatory: {
maxWidth: 640,
maxHeight: 360
navigator.getUserMedia(vgaConstraints, onSuccess, onError);
MediaStreamTrack.getSources()
如果本机有多个摄像头/麦克风,这时就需要使用MediaStreamTrack.getSources方法指定,到底使用哪一个摄像头/麦克风。
MediaStreamTrack.getSources(function(sourceInfos) {
var audioSource = null;
var videoSource = null;
for (var i = 0; i != sourceInfos.length; ++i) {
var sourceInfo = sourceInfos[i];
if (sourceInfo.kind === 'audio') {
console.log(sourceInfo.id, sourceInfo.label || 'microphone');
audioSource = sourceInfo.id;
} else if (sourceInfo.kind === 'video') {
console.log(sourceInfo.id, sourceInfo.label || 'camera');
videoSource = sourceInfo.id;
console.log('Some other kind of source: ', sourceInfo);
sourceSelected(audioSource, videoSource);
function sourceSelected(audioSource, videoSource) {
var constraints = {
optional: [{sourceId: audioSource}]
optional: [{sourceId: videoSource}]
navigator.getUserMedia(constraints, onSuccess, onError);
上面代码表示,MediaStreamTrack.getSources方法的回调函数,可以得到一个本机的摄像头和麦克风的列表,然后指定使用最后一个摄像头和麦克风。
RTCPeerConnectionl,RTCDataChannel
RTCPeerConnectionl
RTCPeerConnection的作用是在浏览器之间建立数据的“点对点”(peer to peer)通信,也就是将浏览器获取的麦克风或摄像头数据,传播给另一个浏览器。这里面包含了很多复杂的工作,比如信号处理、多媒体编码/解码、点对点通信、数据安全、带宽管理等等。
不同客户端之间的音频/视频传递,是不用通过服务器的。但是,两个客户端之间建立联系,需要通过服务器。服务器主要转递两种数据。
通信内容的元数据:打开/关闭对话(session)的命令、媒体文件的元数据(编码格式、媒体类型和带宽)等。
网络通信的元数据:IP地址、NAT网络地址翻译和防火墙等。
WebRTC协议没有规定与服务器的通信方式,因此可以采用各种方式,比如WebSocket。通过服务器,两个客户端按照Session Description Protocol(SDP协议)交换双方的元数据。
下面是一个示例。
var signalingChannel = createSignalingChannel();
var configuration = ...;
// run start(true) to initiate a call
function start(isCaller) {
pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
// once remote stream arrives, show it in the remote video element
pc.onaddstream = function (evt) {
remoteView.src = URL.createObjectURL(evt.stream);
// get the local stream, show it in the local video element and send it
navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
selfView.src = URL.createObjectURL(stream);
pc.addStream(stream);
if (isCaller)
pc.createOffer(gotDescription);
pc.createAnswer(pc.remoteDescription, gotDescription);
function gotDescription(desc) {
pc.setLocalDescription(desc);
signalingChannel.send(JSON.stringify({ "sdp": desc }));
signalingChannel.onmessage = function (evt) {
start(false);
var signal = JSON.parse(evt.data);
if (signal.sdp)
pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
RTCPeerConnection带有浏览器前缀,Chrome浏览器中为webkitRTCPeerConnection,Firefox浏览器中为mozRTCPeerConnection。Google维护一个函数库,用来抽象掉浏览器之间的差异。
RTCDataChannel
RTCDataChannel的作用是在点对点之间,传播任意数据。它的API与WebSockets的API相同。
下面是一个示例。
var pc = new webkitRTCPeerConnection(servers,
{optional: [{RtpDataChannels: true}]});
pc.ondatachannel = function(event) {
receiveChannel = event.channel;
receiveChannel.onmessage = function(event){
document.querySelector("div#receive").innerHTML = event.data;
sendChannel = pc.createDataChannel("sendDataChannel", {reliable: false});
document.querySelector("button#send").onclick = function (){
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
Chrome 25、Opera 18和Firefox 22支持RTCDataChannel。
外部函数库
由于这两个API比较复杂,一般采用外部函数库进行操作。目前,视频聊天的函数库有、、,点对点通信的函数库有、。
下面是SimpleWebRTC的示例。
var webrtc = new WebRTC({
localVideoEl: 'localVideo',
remoteVideosEl: 'remoteVideos',
autoRequestMedia: true
webrtc.on('readyToCall', function () {
webrtc.joinRoom('My room name');
下面是PeerJS的示例。
var peer = new Peer('someid', {key: 'apikey'});
peer.on('connection', function(conn) {
conn.on('data', function(data){
// Will print 'hi!'
console.log(data);
// Connecting peer
var peer = new Peer('anotherid', {key: 'apikey'});
var conn = peer.connect('someid');
conn.on('open', function(){
conn.send('hi!');
Andi Smith,
Thibault Imbert,
Ian Devlin,
Eric Bidelman,
Sam Dutton,
Dan Ristic,
Justin Uberti, Sam Dutton,
Mozilla Developer Network,
Sam Dutton,
Please enable JavaScript to view the
| last modified onWebRTC三个主要接口
MediaStream
RTCDataChannel
关键词:WebRTC三个主要接口,MediaStream,RTCDataChannel
一、WebRTC一对一
1.1 WebRTC三个主要接口
1)MediaStream:通过MediaStream的API能够通过设备的摄像头及话筒获得视频、音频的同步流
2)RTCPeerConnection:RTCPeerConnection是WebRTC用于构建点对点之间稳定、高效的流传输的组件
3)RTCDataChannel:RTCDataChannel使得浏览器之间(点对点)建立一个高吞吐量、低延时的信道,用于传输任意数据
1.2 分别对上述三个接口进行简单介绍
1)MediaStream(getUserMedia)
MediaStream API为WebRTC提供了从设备的摄像头、话筒获取视频、音频流数据的功能。
2)RTCPeerConnection
WebRTC使用RTCPeerConnection来在浏览器之间传递流数据,这个流数据通道是点对点的,不需要经过服务器进行中转。但是这并不意味着我们能抛弃服务器,我们仍然需要它来为我们传递信令(signaling)来建立这个信道。WebRTC没有定义用于建立信道的信令的协议:信令并不是RTCPeerConnection API的一部分。
这些session信息的交换应该在点对点的流传输之前就全部完成,一个大致的架构图如下:
注:通过服务器建立信道
这里再次重申,就算WebRTC提供浏览器之间的点对点信道进行数据传输,但是建立这个信道,必须有服务器的参与。WebRTC需要服务器对其进行四方面的功能支持:
a)用户发现以及通信
b)信令传输
c)NAT/防火墙穿越
d)如果点对点通信建立失败,可以作为中转服务器
注:在RTCPeeConnection中,使用ICE框架来保证RTCPeerConnection能实现NAT穿越
两个兼容:
//兼容浏览器的getUserMedia写法
var getUserMedia = (navigator.getUserMedia ||
&&&&&&&&&&&&&&&&&&&navigator.webkitGetUserMedia ||
&&&&&&&&&&&&&&&&&&&navigator.mozGetUserMedia ||
&&&&&&&&&&&&&&&&&&&navigator.msGetUserMedia);
//兼容浏览器的PeerConnection写法
var PeerConnection = (window.PeerConnection ||
&&&&&&&&&&&&&&&&&&& window.webkitPeerConnection00||
&&&&&&&&&&&&&&&&&&& window.webkitRTCPeerConnection||
&&&&&&&&&&&&&&&&&&& window.mozRTCPeerConnection);
3)RTCDataChannel
既然能建立点对点的信道来传递实时的视频、音频数据流,为什么不能用这个信道传一点其他数据呢?RTCDataChannel API就是用来干这个的,基于它我们可以在浏览器之间传输任意数据。DataChannel是建立在PeerConnection上的,不能单独使用。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:18843次
积分:2171
积分:2171
排名:第14765名
原创:190篇
(10)(41)(20)(31)(31)(29)(30)(1)(1)

我要回帖

更多关于 webrtc mac 打包 下载 的文章

 

随机推荐