一个使用webRTC进行一对一或一对多视频通话的demo并可以对播放视频流截图拍照上传
点击查看具体webRTC API
最终效果如图
一、这个demo满足了:
1、PC端获取远程APP操作人员的后置摄像并能实时通话,并且PC端还可以通过远程视频流截取APP后置摄像的图片。(app端 ——>PC端)
2、app端卸货人员与场地负责人之间视频通话。(app端 ——> app端)
二、 需要注意(坑)
1、socket.io-client版本问题,直接安装的依赖是4.**以上的版本,但是没有触发node监听的事件;后来改成2.*以上的版本才解决。
2、在业务需求完成后不仅要关闭peerConnection,还需要关闭本地及远程视频流;但是通过navigator.mediaDevices.getUserMedia获取的视频流,需要按以下方式来停止媒体流:
const tracks = localStream.getTracks().concat(remoteStream.getTracks())
tracks.forEach((track) => {
track.stop()
})
3、socket 的disconnect事件,一直无法监听;后来发现是房间号不一样造成的
三、nodeJs 的配置如下
'use strict'
let http = require('http');
let express = require('express');
let serveIndex = require('serve-index');
let app = express();
app.use(serveIndex('./dist'));
app.use(express.static('./dist'));
let http_server = http.createServer(app);
http_server.listen(3003);
let io = require('socket.io')(http_server, {
path: '/rtcket'
});
http_server.on('listening', onListening);
function onListening () {
let addr = http_server.address();
let bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
console.log('Listening on ' + bind);
}
let clients = []
io.on('connection', function (socket) {
let query = socket.handshake.query
let username = query.username
let room = query.room
console.log(username + '连接了')
if (clients.some(v => v.userId === socket.id)) {
return
}
socket.join(room)
clients.push({ userId: socket.id, username })
// 过滤相同用户名
if (clients.length > 1) {
let hash = {}
clients = clients.reduce((item, next) => {
hash[next.username] ? ''
: hash[next.username] = true && item.push(next)
return item
}, [])
console.log('最终', clients)
}
if (clients.length >= 2) {
io.sockets.in(room).emit('ready')
}
socket.emit('joined')
socket.broadcast.to(room).emit('join', { username })
io.sockets.in(room).emit('clients', clients)
// 收到对等连接创建的消息
socket.on('pc message', function (data) {
socket.to(data.to.userId).emit('pc message', data)
console.log('pc message收到对等连接创建的消息')
})
// 发私信,发起视频互动的请求
socket.on('interact', function (data) {
socket.to(data.to.userId).emit('interact', data)
console.log('interact发起视频互动的请求')
})
// 对方同意视频互动
socket.on('agree interact', function (data) {
socket.to(data.from.userId).emit('agree interact', data)
console.log('agree interact对方同意视频互动')
})
// 对方拒绝视频互动
socket.on('refuse interact', function (data) {
socket.to(data.from.userId).emit('refuse interact', data)
console.log('拒绝视频互动的请求')
})
// 结束视频
socket.on('stop interact', function (data) {
socket.to(data.to.userId).emit('stop interact', data)
console.log('停止视频互动')
})
socket.on('leave', function () {
socket.emit('left')
socket.broadcast.to(room).emit('leave', { userId: socket.id, username })
clients = clients.filter(v => v.userId !== socket.id)
io.sockets.in(room).emit('clients', clients)
})
socket.on('disconnect', function () {
console.log(username + '断开连接了')
const obj = clients.filter(v => v.userId === socket.id)
socket.broadcast.to(room).emit('close_disconnect', obj)
console.log(room + 'close_disconnect', obj)
clients = clients.filter(v => v.userId !== socket.id)
io.sockets.in(room).emit('clients', clients)
console.log(username + '最终断开连接了')
})
})
五、源码地址
六、按下面方式启动项目
安装依赖
npm install
启动项目
npm run serve
启动 node 服务
npm run node
怎么互动视频聊天
启动后的地址是:http://localhost:8888/
同时打开多个就可以实现一对一聊天或者一对多聊天
七、页面怎么互动聊天如下图
在另一个页面则会显示这样(选择接受即可)