HTML5 播放 RTSP 视频的实例代码


Posted in HTML / CSS onJuly 29, 2019

目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。除了 Firefox 浏览器可以直接播放 RTSP 流之外,几乎没有其他浏览器可以直接播放 RTSP 流。Electron 应用是基于 Chromium 内核的,因此也不能直接播放 RTSP 流。

在借助一定工具的情况下,可以实现在 Web 页面上播放 RTSP 流。本文介绍的方法可以应用于传统 Web 应用和 Electron 应用中,唯一的区别是将 Electron 应用的主进程当作传统 Web 应用的服务器。

目前已有 RTSP 播放方案的对比

既然是做直播,就需要延迟较低。当摄像头掉线时,也应当有一定的事件提示。处于这两点,对目前已有的已经实现、无需购买许可证的 RTSP 播放方案进行对比(处于原理阶段的暂时不分析)。

HTML5 播放 RTSP 视频的实例代码

我对这四种方式都进行了实现,整体效果最好的还是第4种方案,占用端口少,延迟低,渲染速度快,而且离线事件易于处理。

基于 flv.js 的 RTSP 播放方案

flv.js 是 Bilibili 开源的一款 HTML5 浏览器。依赖于 Media Source Extension 进行视频播放,视频通过 HTTP-FLV 或 WebSocket-FLV 协议传输,视频格式需要为 FLV 格式。

服务器端(主进程)

服务器端采用 express + express-ws 框架进行编写,当有 HTTP 请求发送到指定的地址时,启动 ffmpeg 串流程序,直接将 RTSP 流封装成 FLV 格式的视频流,推送到指定的 WebSocket 响应流中。

import * as express from "express";
import * as expressWebSocket from "express-ws";
import ffmpeg from "fluent-ffmpeg";
import webSocketStream from "websocket-stream/stream";
import WebSocket from "websocket-stream";
import * as http from "http";
function localServer() {
    let app = express();
    app.use(express.static(__dirname));
    expressWebSocket(app, null, {
        perMessageDeflate: true
    });
    app.ws("/rtsp/:id/", rtspRequestHandle)
    app.listen(8888);
    console.log("express listened")
}
function rtspRequestHandle(ws, req) {
    console.log("rtsp request handle");
    const stream = webSocketStream(ws, {
        binary: true,
        browserBufferTimeout: 1000000
    }, {
        browserBufferTimeout: 1000000
    });
    let url = req.query.url;
    console.log("rtsp url:", url);
    console.log("rtsp params:", req.params);
    try {
        ffmpeg(url)
            .addInputOption("-rtsp_transport", "tcp", "-buffer_size", "102400")  // 这里可以添加一些 RTSP 优化的参数
            .on("start", function () {
                console.log(url, "Stream started.");
            })
            .on("codecData", function () {
                console.log(url, "Stream codecData.")
             // 摄像机在线处理
            })
            .on("error", function (err) {
                console.log(url, "An error occured: ", err.message);
            })
            .on("end", function () {
                console.log(url, "Stream end!");
             // 摄像机断线的处理
            })
            .outputFormat("flv").videoCodec("copy").noAudio().pipe(stream);
    } catch (error) {
        console.log(error);
    }
}

为了实现较低的加载时间,可以为 ffmpeg 添加如下参数:

  • analyzeduration 可以降低解析码流所需要的时间
  • max_delay 资料上写的具体作用不太记得了,效果没有 analyzeduration 明显

当然这个实现还比较粗糙。当有多个相同地址的请求时,应当增加 ffmpeg 的输出,而不是启动一个新的 ffmpeg 进程串流。

浏览器端(渲染进程)

示例使用 Vue 框架进行页面设计。

<template>
    <div>
        <video class="demo-video" ref="player"></video>
    </div>
</template>
<script>
import flvjs from "flv.js";
export default {
    props: {
        rtsp: String,
        id: String
    },
    /**
     * @returns {{player: flvjs.Player}}
     */
    data () {
        return {
            player: null
        }
    },
    mounted () {
        if (flvjs.isSupported()) {
            let video = this.$refs.player;
            if (video) {
                this.player = flvjs.createPlayer({
                    type: "flv",
                    isLive: true,
                    url: `ws://localhost:8888/rtsp/${this.id}/?url=${this.rtsp}`
                });
                this.player.attachMediaElement(video);
                try {
                    this.player.load();
                    this.player.play();
                } catch (error) {
                    console.log(error);
                };
            }
        }
    },
    beforeDestroy () {
        this.player.destory();
    }
}
</script>
<style>
    .demo-video {
        max-width: 480px; 
        max-height: 360px;
    }
</style>

效果展示

用 Electron 页面展示了 7 个 Hikvison NVR 的摄像头,可以实现低延迟,低 CPU 占用,无花屏现象。由于涉及保密,这里就不放截图了。

同样的方法我播放了 9 个本地 1080p 的视频《白鹿原》,可以看一下这个效果。

HTML5 播放 RTSP 视频的实例代码

播放效果非常好,完全没有卡顿和花屏,CPU 占用率也不高。

示例代码仓库: WhuRS-FGis/html5-rtsp 示例代码仓库:

总结

以上所述是小编给大家介绍的HTML5 播放 RTSP 视频的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

HTML / CSS 相关文章推荐
CSS3 滤镜 webkit-filter详细介绍及使用方法
Dec 27 HTML / CSS
CSS实现定位元素居中的方法
Jun 23 HTML / CSS
CSS3中currentColor关键字的妙用
Feb 27 HTML / CSS
css3实现冲击波效果的示例代码
Jan 11 HTML / CSS
HTML5 Canvas绘制文本及图片的基础教程
Mar 14 HTML / CSS
HTML5混合开发二维码扫描以及调用本地摄像头
Dec 27 HTML / CSS
HTML5实现QQ聊天气泡效果
Jun 26 HTML / CSS
html5贪吃蛇游戏使用63行代码完美实现
Jun 25 HTML / CSS
html5 乒乓球(碰撞检测)实例二
Jul 25 HTML / CSS
2014年圣诞节倒计时网页的制作过程
Dec 05 HTML / CSS
html5需遵循的6个设计原则
Apr 27 HTML / CSS
html5实现移动端适配完美写法
Nov 16 HTML / CSS
利用 Canvas实现绘画一个未闭合的带进度条的圆环
Jul 26 #HTML / CSS
使用Html5多媒体实现微信语音功能
Jul 26 #HTML / CSS
使用canvas来完成线性渐变和径向渐变的功能的方法示例
Jul 25 #HTML / CSS
浅析canvas元素的html尺寸和css尺寸对元素视觉的影响
Jul 22 #HTML / CSS
详解通过focusout事件解决IOS键盘收起时界面不归位的问题
Jul 18 #HTML / CSS
详解window.open被浏览器拦截的解决方案
Jul 18 #HTML / CSS
data:image data url 文件转为Blob上传后端的方法
Jul 16 #HTML / CSS
You might like
全国FM电台频率大全 - 25 云南省
2020/03/11 无线电
用session做客户验证时的注意事项
2006/10/09 PHP
Discuz!5的PHP代码高亮显示插件(黑暗中的舞者更新)
2007/01/29 PHP
php中switch与ifelse的效率区别及适用情况分析
2015/02/12 PHP
php如何获取文件的扩展名
2015/10/28 PHP
PHP计算近1年的所有月份
2017/03/13 PHP
jquery 简短右键菜单 多浏览器兼容
2010/01/01 Javascript
JS模拟面向对象全解(二、类型与赋值)
2011/07/13 Javascript
原生的html元素选择器类似jquery选择器
2014/10/15 Javascript
获取阴历(农历)和当前日期的js代码
2016/02/15 Javascript
如何用JavaScript实现动态修改CSS样式表
2016/05/20 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
JS实现静态页面搜索并高亮显示功能完整示例
2017/09/19 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
2018/09/02 Javascript
python使用pdfminer解析pdf文件的方法示例
2018/12/20 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
html5.2 dialog简介详解
2018/02/27 HTML / CSS
StubHub新加坡:购买和出售全球活动门票
2017/03/10 全球购物
澳大利亚连衣裙和女装在线:Esther
2017/11/11 全球购物
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
英国领先的电子、技术和办公用品购物网站:Ebuyer
2018/04/04 全球购物
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
高三自我鉴定范文
2013/10/19 职场文书
商务会议邀请函
2014/01/09 职场文书
文明学生标兵事迹
2014/01/21 职场文书
初中三年毕业生的自我评价分享
2014/02/14 职场文书
理工大学毕业生自荐信范文
2014/02/22 职场文书
租房协议书
2014/09/12 职场文书
终止或解除劳动合同及劳动关系的证明书
2014/10/06 职场文书
首都博物馆观后感
2015/06/05 职场文书
pytorch通过训练结果的复现设置随机种子
2021/06/01 Python
分享一些Java的常用工具
2021/06/11 Java/Android
Vue3.0 手写放大镜效果
2021/07/25 Vue.js
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫