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实现任意图片lowpoly动画效果实例
May 11 HTML / CSS
CSS3实现精美横向滚动菜单按钮
Apr 14 HTML / CSS
利用css3画个同心圆示例代码
Jul 03 HTML / CSS
利用CSS3的3D效果制作正方体
Mar 10 HTML / CSS
HTML5实时语音通话聊天MP3压缩传输3KB每秒
Aug 28 HTML / CSS
5分钟弄清楚html5的drag and drop(小结)
Apr 10 HTML / CSS
HTML5 video标签(播放器)学习笔记(一):使用入门
Apr 24 HTML / CSS
HTML5实现预览本地图片
Feb 17 HTML / CSS
HTML5拖拽API经典实例详解
Apr 20 HTML / CSS
HTML5自定义属性的问题分析
Aug 16 HTML / CSS
CSS 新特性 contain控制页面的重绘与重排问题
Apr 30 HTML / CSS
CSS3实现列表无限滚动/轮播效果
Jun 23 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
PHP中实现中文字符进制转换原理分析
2011/12/06 PHP
PHP加密技术的简单实现
2016/09/04 PHP
简单谈谈 php 文件锁
2017/02/19 PHP
比较详细的关于javascript 解析json的代码
2009/12/16 Javascript
js调用css属性写法
2013/09/21 Javascript
javascript中验证大写字母、数字和中文
2014/01/15 Javascript
jquery中常用的函数和属性详细解析
2014/03/07 Javascript
js中不同的height, top的区别对比
2015/09/24 Javascript
文本框只能输入数字的实现方法(兼容IE火狐)
2016/06/25 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
JavaScript运行机制实例分析
2020/04/11 Javascript
Node.js API详解之 Error模块用法实例分析
2020/05/14 Javascript
写一个Vue loading 插件
2020/11/09 Javascript
[03:01]2014DOTA2国际邀请赛 DC:我是核弹粉,为Burning和国土祝福
2014/07/13 DOTA
[47:10]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第二场 12.16
2020/12/18 DOTA
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
Python脚本实现自动将数据库备份到 Dropbox
2017/02/06 Python
Python简单网络编程示例【客户端与服务端】
2017/05/26 Python
Python基于辗转相除法求解最大公约数的方法示例
2018/04/04 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
Python Django框架单元测试之文件上传测试示例
2019/05/17 Python
Python+pyplot绘制带文本标注的柱状图方法
2019/07/08 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
使用matlab 判断两个矩阵是否相等的实例
2020/05/11 Python
django自带的权限管理Permission用法说明
2020/05/13 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
2020/08/17 Python
一些常用的HTML5模式(pattern) 总结
2015/07/14 HTML / CSS
Dr.Jart+美国官网:韩国药妆品牌
2019/01/18 全球购物
进程的查看和调度分别使用什么命令
2013/12/14 面试题
班组长岗位职责范本
2014/01/05 职场文书
制药工程专业个人求职自荐信
2014/01/25 职场文书
婚前保证书
2014/04/29 职场文书
经济管理专业求职信
2014/06/09 职场文书
人力资源管理专业自荐书
2014/07/07 职场文书
行政人事主管岗位职责
2015/04/11 职场文书
uwsgi+nginx代理Django无法访问静态资源的解决
2021/05/10 Servers