Web视频监控娱乐版

329 阅读2分钟

视频监控流程图

录制端实现

视频录制端使用 H5 的 video 捕获电脑的摄像头流媒体,然后通过 canvas 将某个时间点的视频帧生成 base64编码的图片,通过 WebSocket 将base64编码的图片上传到服务器,经过服务器(信令服务器)中转到其它 WebSocket 播放端。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>视频录制</title>    <style type="text/css"> html,body{            padding: 0px; margin: 0px; box-sizing: border-box; }        .container{            width: 1280px; margin: auto; overflow: hidden; }        #video{        }        #canvas{        }    </style></head><body>    <div class="container">        <video id="video" ></video>        <canvas id="canvas" width="1280" height="960" hidden></canvas>    </div></body><script src="http://code.jquery.com/jquery-2.1.1.min.js"></script><script type="text/javascript">  var videoEL = document.getElementById('video'); var canvasEL = document.getElementById('canvas'); var context = canvasEL.getContext("2d");  /* 封装 WebSocket 实例化的方法  */ var CreateWebSocket = (function () {      return function (urlValue) {        if(window.WebSocket) return new WebSocket(urlValue); if(window.MozWebSocket) return new MozWebSocket(urlValue); return false; }    })(); /* 实例化 WebSocket 连接对象, 地址为 ws 协议 */ var webSocket = CreateWebSocket("ws://localhost:8080/broadcast"); /* 接收到服务端的消息时 */ webSocket.onmessage = function (msg) {    }; /* 关闭时 */ webSocket.onclose = function () {      console.log("关闭连接"); };  window.navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 960} }).then(function (mediaStream) {      console.log('摄像头连接成功。')      videoEL.srcObject = mediaStream; videoEL.onloadedmetadata = function(e) {        videoEL.play(); setInterval(function(){          context.drawImage(videoEL, 0, 0);//绘制视频 var dataURL = canvasEL.toDataURL(); webSocket.send(JSON.stringify({method: "saveRecord", message: dataURL}))        },30); }; }).catch(function (err) {      console.log(err)    })   </script></html>

服务端实现

服务端笔者采用 node 当下流行的 KOA 框架作为 Web 承载服务器,使用 koa-websocket 处理 websocket 连接,当做信令服务器。

const Koa = require('koa');const Router = require('@koa/router');const websockify = require('koa-websocket'); const koaApp = new Koa();const socketApp = websockify(koaApp); const router = new Router(); const views = require('koa-views'); const ctxArr = []; koaApp.use(views(__dirname + '/views', {})); router.get('/record', (ctx, next) => {  return ctx.render('record')}); router.get('/play', (ctx, next) => {  return ctx.render('play')}); router.all('/broadcast/', function (ctx) {  console.log('客户端已连接')  ctxArr.push(ctx)  ctx.websocket.on('message', function(message) {    var data = JSON.parse(message)    ctxArr.forEach(function (item) {      if (item != ctx) {        // 将监听到的画面广播到其他 websocket 连接。        item.websocket.send(data.message)      }    })  });}) koaApp  .use(router.routes())  .use(router.allowedMethods()); socketApp.ws.use(router.routes()); socketApp.listen(8080);

播放端实现

播放端相对简单,将 websocket 获取到的 base64图片渲染到 canvas 即可。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>监控播放</title>    <style type="text/css"> html,body{            padding: 0px; margin: 0px; box-sizing: border-box; }        .container{            width: 1280px; margin: auto; overflow: hidden; }    </style></head><body><div class="container">    <canvas id="canvas" width="1280" height="960"></canvas></div></body><script src="http://code.jquery.com/jquery-2.1.1.min.js"></script><script type="text/javascript">  var canvasEL = document.getElementById('canvas'); var context = canvasEL.getContext("2d");  /* 封装 WebSocket 实例化的方法  */ var CreateWebSocket = (function () {    return function (urlValue) {      if(window.WebSocket) return new WebSocket(urlValue); if(window.MozWebSocket) return new MozWebSocket(urlValue); return false; }  })(); /* 实例化 WebSocket 连接对象, 地址为 ws 协议 */ var webSocket = CreateWebSocket("ws://localhost:8080/broadcast"); /* 接收到服务端的消息时 */ webSocket.onmessage = function (msg) {    var img = new Image(); img.onload = function(){      context.drawImage(img, 0, 0);//绘制视频 }; img.src = msg.data; }; /* 关闭时 */ webSocket.onclose = function () {    console.log("关闭连接"); }; </script></html>

本文转载自:www.limitcode.com/detail/5e67…