Nodejs+MongoDB+WebRTC搭建视频通话协同应用

由于Node.js是基于事件驱动的单线程异步IO,能够提高服务器的并发性能,且一直很火的视频直播软件也层出不穷,于是跟风来填个坑,学习学习。
最开始是看了一个教程,跟着学,实现一个既有视频通话功能,又有协同编码功能的web应用,但是无奈跟着教程用peerjs框架怎么都没调出来视频通话,最终没实现成功,于是网上一番百度,最终采用了网上的SkyRTC和PeerJS结合完成的视频通话,源码已上传git(不想看我下面啰里巴嗦乱七八糟博文的请直接去看代码,虽然代码也很乱?),因为涉及的内容很多,所以写的很省略,都是简单介绍。

github连接 https://github.com/ZeoSophia/VideoCall

项目整体目录图

整体目录图

Socket.io框架

WebRTC信令最流行的实现之一是使用Socket.io。Socket.io是一个JavaScript库,用于支持双向基于事件通信的实时web应用程序。Socket.io虽然使用了WebSocket协议,但它不仅仅是一个简单的WebSocket包装器,它还提供了许多其他功能,比如向多个socket广播,支持对大多数WebRTC来说至关重要的“房间”的概念。
在Node.js环境下可以直接安装Socket.io资源包,安装成功之后,首先需调用HTTP模块的createServer()方法将Socket.io与服务端的http.srver绑定。

var app = express();
var server = require('http').createServer(app);
var socketIO = require('socket.io');
var io = socketIO(server);

建立Socket连接,用户通过相同URL(Uniform Resource Locator)进入同一聊天室之后,通过调用io.emit()方法将消息发送给所有进入同一“房间”的用户,即可连接成功,进而实现即时通讯,实现监听连接双方的消息方式如下:

socket.on('chatMessage', function(data) {
        io.to(socket.room).emit('chatMessage', data);
    });
socket.on('disconnect', function() {
        socket.leave(socket.room);
});

视频通话实现

首先通过调用createStream()方法创建本地视频流,方便后期实时的视频流传递播放,同时设置video和audio的属性值,建立方法如下:

 rtc.on("connected", function(socket) {
        rtc.createStream({
            "video": true,
            "audio": true
        });
    });

通过接口MediaStream的调用,调用URL.createObjectURL()方法,将生成的媒体流绑定为前端页面”<video>”属性的src的值(实现代码如下),再通过网页对HTML代码解析,将媒体流以本地流的形式播放出来。

rtc.on("stream_created", function(stream) {//成功
        document.getElementById('me').srcObject=stream;
        document.getElementById('me').play();
    });
   
 rtc.on("stream_create_error", function() {//失败
        alert("failed!");
    });

调用RTCPeerConnection接口后,通过调用RTCPeerConnection(iceServer)方法创建一个新对象,并且通过参数创建一个对象,同时会将此对象和一个ICE(Internet Communications Engine)代理对象以及其状态相关联,并且在创建对象时同时被初始化。

var iceServer = {
        "iceServers": [{
            "url": "stun:stun.l.google.com:19302"
        }]
};
var pc = new PeerConnection(iceServer)

WebRTC浏览器兼容问题

WebRTC API的核心是MediaStream处理API,通常称为媒体流API或流API。MediaStream接口可实现从设备摄像头或话筒获取视频、音频数据流的功能,通过调用getUserMedia()方法获取,采用此接口的方法解决由于浏览器版本不同,导致内核版本不同的问题。

var getUserMedia = (navigator.getUserMedia || 
                    navigator.webkitGetUserMedia || 
                    navigator.mozGetUserMedia || 
                    navigator.msGetUserMedia);

协同编程

由于Socket.io作为一个应用层不仅能够传递视频、音频等多媒体流,同时也可以传输其他类似文档型的二进制流。前端部分通过’<textarea>’标签存放,服务段部分发现是该页面之后,先检测是否有前端页面数据传入,通过调用res.render()的方法将数据动态渲染出来。

<textarea id="code-screen">{{content}}</textarea>
<script>
var code = $('#code-screen').val();
 var cmClient;
 function init(str, revision, clients, serverAdapter) {
 if (!code) {
      editor.setValue(str);
  }
cmClient = window.cmClient = new EditorClient(revision, clients, serverAdapter, new CodeMirrorAdapter(editor))};

    socket.on('doc', function(obj) {
init(obj.str,obj.revision,obj.clients,new SocketIOAdapter(socket));
    });
</script>

当两用户成功建立连接时,从数据库通过查找获取代码编辑区实时的内容,前端页面并进行回显,实现用户体验感上的“协同编程”。

if (data) {
  	res.render('task', {
		content: data.content, 
		roomId: data.id
	});
} else {
   res.render('error');
}

 Task.findByIdAndUpdate(data.room,
 	{content: self.document}, function(err) {
            if (err) return cb(false);
            cb(true);
 });
  • 运行代码前一定要先给peer分配端口
    启动项目前应向peer开放端口
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值