最近各大直播网站都比较火,想探究一下是怎么玩的。但是看了几个大牛的回答,感觉有太多陌生的东西,尝试起来成本略高。发现了有个东西叫webrtc,有人分析过他不适合做流量大,人数多的直播。但是我也只是玩一下,感受一下视频连通的感觉。
一开始在github上面看到了一个,比较全大部分的API都做了demo,还有canva 3d融合webrtc的例子。因为大部分例子都是没有经过网络的通讯,所以想用socket写一个交换信令的demo。其中也找到过demo但是没试通过...然后看一些博客和API自己写一个小demo,帮助理解webrtc
目录结构就是这样 只拉取了express socket.io

前端代码:
html部分
<script src="/socket.io/socket.io.js"></script> Local: <br> <video id="localVideo" autoplay style="width:80px"></video><br> Remote: <br> <video id="remoteVideo" autoplay style="width:80px"></video>
js部分
// 判断发起端
var isCaller = window.location.href.split(‘#‘)[1];
// 信令服务器的Socket连接
var socket = io.connect(‘http://localhost:3000‘);
// stun和turn服务器
var iceServer = null;
// iceServer在局域网下可以通讯
var pc = new webkitRTCPeerConnection(iceServer);
// 发送给的其他端通知
pc.onicecandidate = function(event){
if (event.candidate !== null) {
debugger
console.log(‘onicecandidate -----‘);
socket.emit(‘message‘,JSON.stringify({
"event": "_ice_candidate",
"data": {
"candidate": event.candidate
}
}));
}
};
// 建立好p2p通道以后 会通过OnAddStream返回一个音视频流的对象
pc.onaddstream = function(event){
document.getElementById(‘remoteVideo‘).src = URL.createObjectURL(event.stream);
};
// offer和answer
var sendOfferFn = function(desc){
pc.setLocalDescription(desc);
console.log(‘Offer -----‘);
socket.emit(‘message‘,JSON.stringify(desc));
},
sendAnswerFn = function(desc){
pc.setLocalDescription(desc);
console.log(‘Answer -----‘);
socket.emit(‘message‘,JSON.stringify(desc));
};
// 获取本地音频和视频流
navigator.webkitGetUserMedia({
"audio": true,
"video": true
}, function(stream){
//在localVideo输出音视频
document.getElementById(‘localVideo‘).src = URL.createObjectURL(stream);
//把本地的媒体流绑定到PeerConnection
pc.addStream(stream);
//发起端 发送offer
if(isCaller){
pc.createOffer(sendOfferFn, function (error) {
console.log(‘Failure callback: ‘ + error);
});
}
}, function(error){
console.log(‘getUserMedia error: ‘ + error);
});
socket.on(‘message‘,function(event){//处理socket请求
if(event.type){
console.log(‘请求以返回--------‘+event.type);
}else{
console.log(‘--------‘)
console.log(event);
}
if(event.type==‘offer‘ && !isCaller){
pc.setRemoteDescription(event)
pc.createAnswer(sendAnswerFn, function (error) {
console.log(‘Failure callback: ‘ + error);
});
}
if(event.type==‘answer‘ && isCaller){
pc.setRemoteDescription(event)
}
if(event.event==‘_ice_candidate‘){
pc.addIceCandidate(new RTCIceCandidate(event.data.candidate));
}
})
node部分
var express = require(‘express‘); var app = express() var server = require(‘http‘).Server(app); var io = require(‘socket.io‘)(server); server.listen(3000); app.use(express.static(__dirname + ‘/js‘)); app.get(‘/‘, function (req, res) { res.sendfile(__dirname + ‘/index.html‘); }); io.on(‘connection‘, function (socket) { socket.on(‘message‘,function(data){ var message=JSON.parse(data); if(message.type){ console.log(message.type); }else{ console.log(message.event); } console.log(‘请求已经广播出去--------‘); socket.broadcast.emit(‘message‘,message); }) });
访问localhost:3000开启一个端
然后访问localhost:3000#true (开始进行对localhos:3000进行连接)
下面具体流程转载 烟雨任平生的
具体流程可以参考:http://www.cnblogs.com/fangkm/p/4364553.html 他写的比较细节,清新脱俗
原文:http://www.cnblogs.com/meihuanyu/p/6061692.html