初识webrtc 

WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。20115月开放了工程的源代码,在行业内得到了广泛的支持和应用,成为下一代视频通话的标准。

WebRTC 技术带来的便利是,不需要native(iosandroid)支持,直接通过浏览器就可以进行视频语音通信,这在直播或者视频直连、文字通信等方面意义重大。

WebRTC 目前已经是比较成熟的技术,网上也有很多开源项目,近期研究了下手机端与pc端的点对点视频直连,实现原理如图:

485067-20160523153500491-1948887887.png


实现视频直连需要以下几个要素:

1、模拟PC

2、模拟手机端

3、建立websocket服务

4、使用coturn服务做中转(我这里模拟是在同一网段,这部分可以暂时忽略)


实现过程中,为了方便起见,我用了一个比较好的webrtc PeerJshttp://peerjs.com/)。PeerJS 提供了前端处理WebSocket链接的相关接口,另外提供了配套的Peerjs server,来支持服务端,基于nodejs,非常方便(https://github.com/peers/peerjs-server


实现过程:

1、利用PeerJS server开启 websocket 服务。

var fs = require('fs');var PeerServer = require('peer').PeerServer;var server = PeerServer({
  port: 9000,
  ssl: {
    key: fs.readFileSync('/path/to/your/ssl/key/here.key'),
    cert: fs.readFileSync('/path/to/your/ssl/certificate/here.crt')
  }
});

2、集成express

var express = require('express');
var app = express();
var ExpressPeerServer = require('peer').ExpressPeerServer;

app.get('/', function(req, res, next) { res.send('Hello world!'); });

var server = app.listen(9000);

var options = {
    debug: true
}

app.use('/api', ExpressPeerServer(server, options));

// OR

var server = require('http').createServer(app);

app.use('/peerjs', ExpressPeerServer(server, options));

server.listen(9000);

需要注意的是,https的证书本地可以自己通过OpenSSL创建一下,比较简单。


3、模拟PC端(index.html)

<!doctype html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="js/peer.js"></script>
</head>

<body>
<input type="text" id="message">
<input type="button" value="发送" id="submit">
<div id="message-list"></div>
<video id="B1" autoplay></video>

<script>
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;

var video = document.querySelector("video");
var localStream,
peer = new Peer('B1', { host: '192.168.43.212', port: 4433, secure: true, path: '/api', debug: 3 });

// emitted when connected server.
peer.on('open', function (id) {
console.log('My peer ID is: ', id);
});

peer.on('connection', function (conn) {
console.info('连接来了:', conn.peer);
document.getElementById('submit').onclick = function () {
conn.send(document.getElementById('message').value || '空白信息');
};
console.info('开始创建视频流...');
navigator.getUserMedia({
video: true,
audio: false
}, function (stream) {
localStream = stream;
peer.call('B2', stream);
}, function (err) {
console.info('创建视频流失败。。。');
});

conn.on('data', function (data) {
console.info('来自%s: %s', conn.peer, data);
document.getElementById('message-list').appendChild(document.createElement('p').appendChild(document.createTextNode(data)));
conn.send(conn.peer + ', 我已经收到你的信息:' + data);
});
});

peer.on('call', function (call) {
console.info('B2发视频来了', call);

call.answer(localStream);
call.on('stream', function (stream) {
console.info('来自B2的视频流。。。');
video.src = window.URL.createObjectURL(stream);
});
});

peer.on('error', function (err) {
console.info('发生错误:', err);
});

</script>
</body>

</html>

4、模拟手机端:(video.html)

<!doctype html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="js/peer.js"></script>
</head>

<body>
<input type="text" id="message">
<input type="button" value="发送" id="submit">
<div id="message-list"></div>
<video id="remote" autoplay></video>

<script>
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;

var video = document.getElementById("remote"),
local = document.getElementById('local');
var localStream,
peer,
remoteId = 'B1';

navigator.getUserMedia({
video: true,
audio: false
}, function (stream) {
console.info('创建视频流成功。', stream);
localStream = stream;
//        local.src = window.URL.createObjectURL(stream);
peer = new Peer('B2', { host: '192.168.43.212', port: 4433, secure: true, path: '/api', debug: 3 });

peer.on('open', function (id) {
var connection = peer.connect(remoteId);
console.log('My peer ID is: ', id, connection);

connection.on('open', function () {
document.getElementById('submit').onclick = function () {
connection.send(document.getElementById('message').value || '空白信息');
};
connection.send('hello world...');
});

connection.on('data', function (message) {
console.info('来自%s的%s', remoteId, message);
document.getElementById('message-list').appendChild(document.createElement('p').appendChild(document.createTextNode(message)));
});

connection.on('err', function (err) {
console.info('来自%s的错误信息:', remoteId, err);
});

connection.on('close', function () {
console.info('与%断开连接');
});
});

peer.on('call', function (call) {
console.info('我的视频流:', localStream);
call.answer(localStream);

peer.call('B1', localStream);
call.on('stream', function (stream) {
console.info('来自B1的视频流。。。', call);
video.src = window.URL.createObjectURL(stream);
});


});

peer.on('connection', function (conn) {
console.info('连接来了:', conn);
});
peer.on('error', function (err) {
console.info(err);
});

}, function (err) {
console.info('创建视频流失败。。。', err);
});

</script>
</body>

</html>

注意:代码中的

host: '192.168.43.212', port: 4433

为刚才步骤1中建立的webSocket服务的ip和端口号,https服务在localhost下是可以访问的,部署到服务器上证书一定要正确,否则连接不上。


测试步骤:

1、浏览器访问index.html.

2、新建选项卡访问video.html

3、视频连接成功!

源码:

rtc.zip


发表评论

登录 后参与评论

评论列表 (9条)

  • sarkerdo
    2 个月前
    @doramart  ванркврнвк
  • sarkerdo
    2 个月前
    fgjfgjhfgjf
  • wudedi2000
    3 个月前
    这是一个评论
  • doramart [  管理员]
    3 个月前
    @slvador  加扣扣:305511094
  • slvador
    3 个月前
    @doramart  我能加下你联系方式吗?这里太难沟通了
  • doramart [  管理员]
    3 个月前
    @slvador  你的peer server 起来了么?IP配置正确吗?
  • slvador
    3 个月前
    你好,为什么我本地服务报错了,而且启动后只有个发送按钮。 :4433/api/peerjs/B1/diuawpdo44t/id?i=0 Failed to load resource: net::ERR_CONNECTION_REFUSED peer.js:1 PeerJS: ERROR Error: Lost connection to server.
  • doramart [  管理员]
    3 个月前
    @testtest1  是系统帮,还是身体棒
  • testtest1
    3 个月前
    棒棒棒!!