JavaScript实现网页端播放摄像头实时画面

目录
  • 初衷
  • 应对的场景
  • 涉及到的范围
  • 解决问题的思路
  • 摄像头的Rtsp地址
  • ffmpeg下载,安装,配置环境变量
  • nodejs和Express
  • JSMpeg播放和请求打开关闭

初衷

写这篇博客已经是项目过去很久了,之所以写是因为当时被这个问题为难了很久。我原本是做后端的,涉及到前端的东西,当时是两眼一黑。好在最后还是解决了。当相信这个内容还是有价值的,所以今天整理出来,帮助未来可能需求的人。

应对的场景

希望在自己的Web应用中播放局域网(不能上云),或是广域网的摄像头实时画面。

涉及到的范围

  • Nodejs 以及 Express
  • WebSocket html页面拉流
  • ffmpeg 推流用
  • node-rtsp-stream 主要依赖这个东西,将 rtsp 流推送到 Ws
  • JSMpeg 主要用来播放 ws 流画面

这个解决方案是全前端方案,所以后端的流处理都是用Node处理的。

解决问题的思路

  • 首先要拿到摄像头的播放Rtsp通道。(有些是带密码的,有些不带密码)。
  • 使用ffmpeg将rtsp流转成ws流。
  • 当客户端请求播放摄像头画面的时候,Node接受请求,并将流地址返回给前端。
  • 前端使用 JSMpeg 去播放ws流,画面呈现。
  • 闭关的时候,仍然请求后端,用Node处理。闭关推流进程。

摄像头的Rtsp地址

因为这里没有摄像头,所以我在网上搜索了一个流地址:

  rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov'

如果电脑中装了 VCL,则可以使用VCL的流地址播放功能去播放,这里我就不做演示了。

ffmpeg 下载,安装,配置环境变量

这里我在gitHub上找到了一个ffmepg下载地址 ,这个版本是windows版本的。

安装就不用说了,下一步,下一步即可,最后就说配置环境变量。其作用就是在命令行状态下可以直接通过 ffmpeg 访问到文件。

nodejs 和 Express

nodejs 我就不详细介绍了,express也一样,这两个东西要是不会,这篇文章也就不用看了。

然后就是写代码接受前端到http请求了。可以参考博客园里面的express介绍。稍后我会贴出代码,建议看看文档。

Express参考

接受请求的代码

var express = require('express');
const requestmanager = require('../lib/RequestManager')
var router = express.Router();

router.get('/', function (req, res) {
    res.send('Carmeras Server is Runing...');
});

/* GET users listing. */
router.post('/', function (req, res) {
    var cfg = req.body
    let result = new requestmanager().Open(cfg)
    res.json(result)
});

router.post('/close', function (req, res) {
    var cfg = req.body
    new requestmanager().Close(cfg)
    res.json({ state: 'close the rtsp stream success.' })
})

这里用到了 node-rtsp-stream 、express 、express.Router 还引用了一个 RequestManager,这是我自己写的一个管理请求的包,代码如下:

const Stream = require('node-rtsp-stream')
const os = require('os');
///获取本机ip///
function getIPAdress() {
    var interfaces = os.networkInterfaces();
    for (var devName in interfaces) {
        var iface = interfaces[devName];
        for (var i = 0; i < iface.length; i++) {
            var alias = iface[i];
            if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
                return alias.address;
            }
        }
    }
}
const args = []
const requestManager = function () { }
//这里是在原型上加上打开和关闭两个方法
requestManager.prototype = {
    Open: function (arg) {
        let result = {}
        if (args.length == 0) {
            result = this._create(arg)
            result = this._openVideo(result)
        } else {
            args.forEach(a => {
                if (a.rtspUrl == arg.rtspUrl) {
                    result = a
                }
            })
            if (result.port === undefined || result.rtspUrl === undefined) {
                result = this._create(arg)
                result = this._openVideo(result)
            }
        }
        result = Object.assign(result,{url:`ws:\\${getIPAdress()}:${result.port}`})
        return result;
    },
    Close: function (arg) {
        let result = {}
        let idx = -1
        idx = args.findIndex(a => a.rtspUrl == arg.rtspUrl)
        if (idx !== -1) {
            args[idx].stream.stop()
            result = args.splice(idx, 1)
        } else {

        }
        console.log(args)
        return result
    },
    //这里是产生一个随机端口号,用来推流使用。
    _randomPort: function () {
        let port = Math.floor(Math.random() * (4001 - 3001) + 3001)
        return port
    },
    //这里是核心推流代码,其实很简单。
    _openVideo: function (arg) {
        arg.stream = new Stream({
            name: 'name',
            //streamUrl: 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov',
            streamUrl: arg.rtspUrl,
            wsPort: arg.port,
            ffmpegOptions: { // options ffmpeg flags
                '-stats': '', // an option with no neccessary value uses a blank string
                '-r': 30, // options with required values specify the value after the key
                '-s': arg.size,
                '-codec:a': 'mp2',
                '-ar': 44100,
                '-ac': 1,
                '-b:a': '128k'
            }
        })
        return arg
    },
    //这里创建参数。
    _create: function (arg) {
        let target = {
            rtspUrl: 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov',
            port: this._randomPort(),
            size: '1024*768',
            stream: null
        }
        let source = {
            rtspUrl: arg.rtspUrl,
            port: this._randomPort(),
            size: arg.size,
            stream: null
        }
        Object.assign(target, source)
        args.push(target)
        return target
    }

}

module.exports = requestManager

当 Open方法被调用的时候,node-rtsp-stream会调用 ffmepg 程序开始推流。其参数如下:

 ffmpegOptions: { // options ffmpeg flags
                '-stats': '', // an option with no neccessary value uses a blank string
                '-r': 30, // options with required values specify the value after the key
                '-s': arg.size,
                '-codec:a': 'mp2',
                '-ar': 44100,
                '-ac': 1,
                '-b:a': '128k'
            }

这里关注 -s 它是设置画幅大小的。所以我这里用到了参数 arg.size。带_(下划线)的方法内部使用。 关键位置都给了注视了,一般应该是看的懂了。

JSMpeg 播放 和请求打开关闭

这是个第三方库,在gitee和gitHub上都有,这里列出Gitee上的地址JSMpeg我用到的关键代码就几句

 /*初始化并播放*/
 let player = new JSMpeg.Player(url, opt);
 /*销毁关闭*/
 player.destroy()

至于请求,可以用axios 或是 jquery库,我这里用的是 jquery

       var player
        //关闭
        function closeStream() {
            $.post("http://127.0.0.1:3000/cameras/close/", { rtspUrl: $('#rtsp').val() }, function (result) {
                player.destroy()
            })
        }

        //打开
        function start() {
            var rstp = $('#rtsp').val()
            var size = $('#size').val()
            $.post("http://127.0.0.1:3000/cameras/", { rtspUrl:rstp, size:  size }, function (result) {
                var url = "ws://127.0.0.1:" + result.port;
                var canvas = document.getElementById('video-canvas');
                let opt = {
                    canvas: canvas,
                    poster: "0.jpg",
                }
                player = new JSMpeg.Player(url, opt);
            })

        }

完整的Html如下:

<!DOCTYPE html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>DEMO node-rtsp-stream-jsmpeg</title>
    <script src="https://jsmpeg.com/jsmpeg.min.js"></script>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

    <style type="text/css">
        html,
        body {

            text-align: center;
        }

        input[type='text'] {
            width: 450px;
        }
    </style>
</head>

<body>
    <div>
        <!-- <span>rtsp : <input type="text" name="rtsp" id="rtsp"  value="rtsp://admin:xcs123456@192.168.3.11:554/h264/ch1/main/av_stream"></span><br /> -->
        <span>rtsp : <input type="text" name="rtsp" id="rtsp"  value="rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"></span><br />

        <span>rtsp : <input type="text" name="size" id="size" value="1024*768"></span><br />
        <canvas id="video-canvas">
        </canvas><br />

        <input type="button" value="Start Stream" onclick="start()">
        <input type="button" value="Close Stream" onclick="closeStream()">
    </div>

    <script type="text/javascript">
        var player

        function closeStream() {
            $.post("http://127.0.0.1:3000/cameras/close/", { rtspUrl: $('#rtsp').val() }, function (result) {
                player.destroy()
            })
        }

        function start() {
            var rstp = $('#rtsp').val()
            var size = $('#size').val()
            $.post("http://127.0.0.1:3000/cameras/", { rtspUrl:rstp, size:  size }, function (result) {
                var url = "ws://127.0.0.1:" + result.port;
                var canvas = document.getElementById('video-canvas');
                let opt = {
                    canvas: canvas,
                    poster: "0.jpg",
                }
                player = new JSMpeg.Player(url, opt);
            })

        }
    </script>
</body>

以上就是全部的内容,完整代码可以到gitee上下载

以上就是JavaScript实现网页端播放摄像头实时画面的详细内容,更多关于JavaScript摄像头实时画面的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS实现调用本地摄像头功能示例

    本文实例讲述了JS实现调用本地摄像头功能.分享给大家供大家参考,具体如下: 今天学习了一下js调用本地摄像头,其实是实现不是很麻烦,下面是代码部分,连接上Tomcat服务器,然后再到网页上打开即可以看到效果了..快来玩一下吧! <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title></title> <

  • JS打开摄像头并截图上传示例

    直入正题,JS打开摄像头并截图上传至后端的一个完整步骤 1. 打开摄像头主要用到getUserMedia方法,然后将获取到的媒体流置入video标签 2. 截取图片主要用到canvas绘图,使用drawImage方法将video的内容绘至canvas中 3. 将截取的内容上传至服务器,将canvas中的内容转为base64格式上传,后端(PHP)通过file_put_contents将其转为图片 要注意的是,在chrome以外的浏览器中,使用摄像头或多或少会出现一些问题,可能也是老问题了,所以以

  • js调用网络摄像头的方法

    不支持IE浏览器(需要使用flash插件), 支持移动端, 未经过完全测试 PC端使用的时候, HTML页面需要预留video标签, canvas标签 移动端使用的时候, HTML页面需要预留file标签, canvas标签, img标签 (function (window, document) { window.camera = { init: function (options) { /** * options 属性示例 * videoID: video控件ID * canvasID: ca

  • Vue实现调用PC端摄像头实时拍照

    Vue之调用PC端摄像头实时拍照,供大家参考,具体内容如下 由于我使用的是点击按钮打开模态框拍照所以在这里吧按钮和模态框代码都粘贴如下. <!-- 打开模态框按钮--> <el-form-item label="*照片:" prop="headImage"> <el-input type="text" v-model="imgSrc" /> <el-col :span="1.

  • javascript实现摄像头拍照预览

    使用javascript实现电脑摄像头的打开和截图的功能,供大家参考,具体内容如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>摄像头调用实例</title> <script type="text/javascript" src="jquery-3.2.1.min.js"></scr

  • js调用设备摄像头的方法

    本文实例为大家分享了js调用设备摄像头的具体代码,供大家参考,具体内容如下 使用getUserMedia这个API来获取摄像头的权限 兼容chrome和火狐,IOS不兼容 下面是源码: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="widt

  • JavaScript实现网页端播放摄像头实时画面

    目录 初衷 应对的场景 涉及到的范围 解决问题的思路 摄像头的Rtsp地址 ffmpeg下载,安装,配置环境变量 nodejs和Express JSMpeg播放和请求打开关闭 初衷 写这篇博客已经是项目过去很久了,之所以写是因为当时被这个问题为难了很久.我原本是做后端的,涉及到前端的东西,当时是两眼一黑.好在最后还是解决了.当相信这个内容还是有价值的,所以今天整理出来,帮助未来可能需求的人. 应对的场景 希望在自己的Web应用中播放局域网(不能上云),或是广域网的摄像头实时画面. 涉及到的范围

  • javascript实现网页端解压并查看zip文件

    WEB前端解压ZIP压缩包 web前端解压zip文件有什么用: 只考虑标准浏览器的话, 服务器只要传输压缩包到客户端, 节约了带宽, 而且节约了传输时间, 听起来好像很厉害的说:      如果前端的代码很多, 而且包含大副的图片,那么就可以把js和css和jpg和png等各种数据通过服务端打包成zip传送到浏览器, 浏览器负责解压, css实用动态生成插入到dom中,js也用globalEval直接执行, jpg或者png各种图片文件由blob流转化为image, 直接插入到浏览器中: htm

  • JavaScript实现网页播放器

    今天我和大家分享用JavaScript在网页编写一个播放器. 对于播放器,大家都不陌生,那么要怎么样才能实现它呢? 下面是我做的一个播放器的图 首先我们从上向下看看这个播放器,它的最上面是标题(head):我的音乐:中间是内容(body):歌曲:最下面(foot):控制音乐播放的控件.标题部分就只有标题:我的音乐,而中间内容部分是歌单,每个歌曲都有一个播放图标(音乐播放时才有)和歌曲的信息,底部部分有一些控制播放的图标.当前播放歌曲名.歌曲播放进度还有歌曲播放时长. 布局这块我们要保存结构与样式

  • js控制网页背景音乐播放与停止的方法

    本文实例讲述了js控制网页背景音乐播放与停止的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml

  • 基于jQuery的网页影音播放器jPlayer的基本使用教程

    jPlayer简介: 想在网页上播放背景音乐,不想用html标签的方式,因为那样只有音乐全部下载完以后才能播放,还容易出现跨浏览器兼容性的问题,于是选了一款基于jQuery的播放器jPlayer来做. 设置jPlayer的尺寸大小 使用构造函数配置jPlayer({size:Object})设置jPlayer的高宽. 使用构造函数配置jPlayer({sizeFull:Object})设置全屏尺寸. 注意可通过构造函数配置jPlayer({backgroundColor:"#RRGGBB&quo

  • php实现网页端验证码功能

    我们在实际开发中,会用到短信验证码以及网页验证码,相对来说网页验证码的成本比较低,安全系数也还可以,接下来我们就来做一个网页端的验证码,直接上代码: 首先来说一下文件目录结构: |----------phpyanzheng  项目文件夹 |----fonttype 文件夹放字体文件,字体文件一般以 .ttf和.otf结尾 |----1.php  里面放php语言代码 |----index.html  里面放网页布局 1.php <?php header('content-type:image/j

  • JS实现网页端猜数字小游戏

    本文实例为大家分享了JS实现网页端猜数字游戏的具体代码,供大家参考,具体内容如下 题目描述 电脑产生一个0到100之间的随机数字,并且要求用户来猜,如果用户猜的数字比这个数字大,电脑会提示"太大",否则会提示"太小",当用户正好猜中,电脑会提示"恭喜你猜对了,这个数是-".在用户每次猜测之后,程序会输出用户第几次猜测.如果用户输入的根本不是一个数字,程序会告诉用户输入无效 代码实现 <!DOCTYPE html> <html&g

  • JavaScript实现移动端带transition动画的轮播效果

    JavaScript实现轮播的方式多种多样,桌面的移动端的实现方式都是大同小异的,具体的核心实现原理不外乎下面几个要点.即: 1. 确定播放方向.一般都是横向轮播,当然不排除纵向的需求可能.当然还有反向播放情况,这个自定义. 2. 对第一张图片的处理.如果当前是第一张了,那么如果继续往前面(就是你播放方向的反向)滑动,那么就会出现留白(如果你允许继续滑动的话,不过不允许滑动也没有啥意思了,除非你想来回轮播,这个我在另一篇用jQuery也说明过),此时应该让你的左边显示应该轮播图片的最后一张,实现

  • javascript实现移动端 HTML5 图片上传预览和压缩功能示例

    本文实例讲述了javascript实现移动端 HTML5 图片上传预览和压缩功能.分享给大家供大家参考,具体如下: 在开发移动端web网页中,我们不可避免的会遇到文件上传的功能,但由于手机图片尺寸太大,上传时间过长导致用户体验太差,就需要在上传前对图片进行一定的压缩. 在代码之前,有必要先了解我们即将使用到的几个API file 和 FileList 对象 file对象可以用来获取某个文件的信息,还可以用来读取这个文件的内容.通常情况下,File对象是来自用户在一个 input 元素上选择文件后

随机推荐