近期,出于项目需要,要求支持web网页播放RTSP格式的监控视频。因之前并没有相关的项目经验及技术积累。并且H5中的video默认并不支持RTSP格式的视频播放,接下来花了一周时间,都在进行调研和实践网上搜到的方案。

1、vlc插件 + video标签

起初,找到的实现方式,是利用第三方插件,vlc播放器或者在谷歌浏览器上安装vlc视频插件的方案。在实践过程中发现,该方案,依赖于谷歌浏览器支持NPAPI插件。谷歌浏览器目前已经不知道该插件,即使后来费了很多时间在网上找谷歌浏览器40-44版本,尝试进行播放,页面也提示“该插件不支持”。同时,低版本谷歌浏览器基本是2015年之前的,对于ES6语法还有样式上的兼容,也多少存在一些问题,还有就是下载的版本居然连打开开发者工具都闪退,果断放弃了在低版本谷歌浏览器的开发计划。

之后有尝试谷歌浏览器能不能播放RTMP格式的视频流,结果依旧没有成功;究其原因,是由于2021年之后的谷歌浏览器版本已不再支持flash插件,且之前的任何浏览器版本都不再支持flash插件,即使在设置中打开的flash的控制,页面依然显示“adobe flash player 不再支持”的字样。。。

2、nginx + ffmpeg + flv.js

翻找了很多相关的技术文章,esayPlayer也安装过,加开发群咨询技术问题,反馈都说前端H5无法直接播放RTSP视频流,只能转格式,但是推荐的服务又是付费的,目前项目并不打算使用第三方服务,将视频放在公网环境进行存储播放,所以也就作罢了。

最终,选择了这个看上去技术实践并不是很困难的方式。该方式的实现原理,通过服务端将其 RTSP / RTMP 流实时转为 http-flv 流,从而浏览器可直接使用该流进行直播(使用bilibili提供的 flv.js )。

该实现方式的前提条件:
(1)nginx

(2)nginx-http-flv-module

(3)ffmpeg

(4)  flv.js

2.1 配置流程

2.1.1 nginx 补充 nginx-http-flv-module模块

// 步骤:// 1、下载 nginx-http-flv-module下载 https://github.com/winshining/nginx-http-flv-module 项目// 2、下载 nginx 安装包,解压后进入对应包文件夹中cd /usr/localtar -zxvf nginx-1.8.1.tar.gzcd nginx-1.21.1 // 3、在nginx安装文件夹中,执行以下命令,安装nginx-http-flv-module,--add-module后拼接的是nginx-http-flv-module 项目的存放路径./configure --prefix=/usr/local/nginx  --add-module=/usr/local/nginx/nginx-http-flv-module// 4、手动编译并重新安装nginx,此时nginx将被安装到 make && make install// 5、重启nginxnginx -s reload 

遇到的问题:

(1)已有nginx,安装路径下,并没有 configure文件

我是在mac上直接进行配置操作的,但是进入nginx的安装路径 /usr/local/Cellar/nginx下(之前通过brew install nginx 进行安装的),并没有找到 congfigure文件。在网上找了nginx的安装压缩包,拷贝其中的 congfigure 进行了补充。但由于是第一次搞这个配置,怕又出什么幺蛾子,就先用 brew uninstall nginx 把之前的卸载了。重新按照上边的方式,一步步进行了操作;

(2)nginx补充模块时报openssl库缺失

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.依照该报文提示,先检查是否已经安装openssl库如果没有, 执行安装命令  brew  install openssl然后,修改 nginx 安装第三方模块的命令, --with-openssl=拼接openssl的安装路径:./configure --prefix=/usr/local/nginx  --add-module=/usr/local/nginx/nginx-http-flv-module --with-openssl=/usr/local/Cellar/openssl@1.1/1.1.1i出现以下类似文案,表明命令执行成功:Configuration summary+ using system PCRE library+ using OpenSSL library: /usr/local/Cellar/openssl@1.1/1.1.1i+ using system zlib librarynginx path prefix: "/usr/local/nginx"nginx binary file: "/usr/local/nginx/sbin/nginx"nginx modules path: "/usr/local/nginx/modules"nginx configuration prefix: "/usr/local/nginx/conf"nginx configuration file: "/usr/local/nginx/conf/nginx.conf"nginx pid file: "/usr/local/nginx/logs/nginx.pid"nginx error log file: "/usr/local/nginx/logs/error.log"nginx http access log file: "/usr/local/nginx/logs/access.log"nginx http client request body temporary files: "client_body_temp"nginx http proxy temporary files: "proxy_temp"nginx http fastcgi temporary files: "fastcgi_temp"nginx http uwsgi temporary files: "uwsgi_temp"nginx http scgi temporary files: "scgi_temp"

(3)执行make install 提示没有权限

// 错误报文/Library/Developer/CommandLineTools/usr/bin/make -f objs/Makefile install
test -d '/usr/local/nginx' || mkdir -p '/usr/local/nginx'
mkdir: /usr/local/nginx: Permission denied
make[1]: *** [install] Error 1
make: *** [install] Error 2处理方案:sudo make install  // 需要输入密码

(4)nginx 不存在

// 错误报文
app@xxx local% nginx -v
zsh: command not found: nginx处理方案:修改/etc/profile文件进入文件编辑 vim /etc/profile 输入 i 进入编辑状态# System-wide .profile for sh(1)if [ -x /usr/libexec/path_helper ]; theneval `/usr/libexec/path_helper -s`
fiif [ "${BASH-no}" != "no" ]; then[ -r /etc/bashrc ] && . /etc/bashrc
fi// 在该文件末尾补充以下文字,注意nginx安装后的路径PATH=$PATH:/usr/local/nginx/sbin
export PATH按 esc 退出编辑状态
按 :wq 强制更新文件
cat  /etc/profile 查看编辑后的文件内容最后,记得执行   source /etc/profile  重启该配置文件输入以下结果表明全局可使用nginxapp@xxx local% nginx -v
nginx version: nginx/1.21.1

2.1.2 修改 nginx 配置文件

该配置,按照nginx-http-flv-module 项目中提供的配置进行修改即可,以下是我的nginx.conf中相关的配置——标记“重要”的配置。

配置修改完成之后,记得重启nginx服务: nginx -s reload

#user  nobody;
worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';#access_log  logs/access.log  main;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       80;server_name  localhost;#charset koi8-r;#access_log  logs/host.access.log  main;location / {root   html;index  index.html index.htm;}# 重要 http-flv  转流配置location /live {flv_live on; #打开 HTTP 播放 FLV 直播流功能chunked_transfer_encoding on; #支持 'Transfer-Encoding: chunked' 方式回复add_header 'Access-Control-Allow-Origin' '*'; #添加额外的 HTTP 头add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的 HTTP 头add_header 'Cache-Control' 'no-cache';}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}}# 重要  rtmp推流相关配置rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;rtmp {out_queue           4096;out_cork            8;max_streams         128;timeout             15s;drop_idle_publisher 15s;log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用log_size     1m; #log模块用来记录日志的缓冲区大小server {listen 1935;# server_name www.test.*;  #当模块中,只有一个server时,可以不配置server_name,nginx对于请求,当找不到匹配的server_name时,会默认发给第一个server进行处理。application myapp {live on;gop_cache on; #打开GOP缓存,减少首屏等待时间}}
}

2.2 执行拉流、推流操作

// ffmpeg的拉流、推流命令,可自行搜索,以下命令,是将一个本地RTSP的视频流,转为http-flv的过程,
其中视频、音频格式直接复制,没有进行转码操作ffmpeg -rtsp_transport tcp -i  rtsp://admin:xxx@127.0.0.1:554/Streaming/Channels/101 -c copy -f flv rtmp://127.0.0.1:1935/live/101

遇到的问题

(1)无法执行以上命令,报错: RTMP_ReadPacket, failed to read RTMP packet header

// 错误报文
[rtsp @ 0x7f8429008200] Missing PPS in sprop-parameter-sets, ignoring
Input #0, rtsp, from 'rtsp://admin:xxx@127.0.0.1:554/Streaming/Channels/101':Metadata:title           : Media PresentationDuration: N/A, start: 0.240000, bitrate: N/AStream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 1280x720, 25 fps, 25 tbr, 90k tbn, 50 tbc
RTMP_ReadPacket, failed to read RTMP packet header
rtmp://127.0.0.1:1935/live/101: Unknown error occurred处理方案:以上报文,表明拉流操作正常,推流出现了问题,
排查了很久,最后,对比了之前的nginx配置发现rtmp://127.0.0.1:1935/live/101  中的 live 没有对应配置,将其修改为 myapp 后成功执行注意: 推流的地址格式———— rtmp://ip:port/appname/streamname  其中,port  指nginx配置中rtmp相关配置下的监听端口 1935(可自行修改nginx中对应端口,注意不要与其他使用端口冲突)
appname  指 application 后的名称,可配置多个application,注意名称不可重复nginx配置示例如下:rtmp {out_queue           4096;out_cork            8;max_streams         128;timeout             15s;drop_idle_publisher 15s;log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用log_size     1m; #log模块用来记录日志的缓冲区大小server {listen 1935;# server_name www.test.*;  #当模块中,只有一个server时,可以不配置server_name,nginx对于请求,当找不到匹配的server_name时,会默认发给第一个server进行处理。application myapp {live on;gop_cache on; #打开GOP缓存,减少首屏等待时间}}
}

(2)无法执行以上命令,报错:RTMP_Connect0, failed to connect socket. 61 (Connection refused)

// 错误报文[rtsp @ 0x7fd41d011000] Missing PPS in sprop-parameter-sets, ignoring
Input #0, rtsp, from 'rtsp://admin:xxx@127.0.0.1:554/Streaming/Channels/101':Metadata:title           : Media PresentationDuration: N/A, start: 0.240000, bitrate: N/AStream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 1280x720, 25 fps, 25 tbr, 90k tbn, 50 tbc
RTMP_Connect0, failed to connect socket. 61 (Connection refused)
rtmp://127.0.0.1:1935/myapp/test: Unknown error occurred处理方案:网上搜索,提示是nginx服务未开启导致的,重启nginx即可

(3)延迟较大,超过10s以上

通过以下操作,延迟明显缩小,但是在使用浏览器播放视频源地址,与页面上进行播放的视频进行对比,发现页面上的时间与播放器上的时间,依旧存在3-5s的差距,这个问题待后续跟进处理;

// 修改ffmpeg的命名,
// 补充 -tune zerolatency 控制延迟
// 补充 -preset ultrafast 转码速度ffmpeg -rtsp_transport tcp -i "rtsp://admin:xxx@127.0.0.1:554/Streaming/Channels/102" -vcodec copy -acodec copy -f flv -tune zerolatency  -preset ultrafast "rtmp://127.0.0.1:1935/myapp/test"

2.3 前端页面的输出

2.3.1 flv.js 安装

npm i flv.js

2.3.1 vue 页面导入flv.js

播放器组件封装,基本上都是按照flv.js 提供的demo进行配置的

<template><div class="app-container"><div>原生video</div><video id="videoElement" class="centeredVideo" controls autoplay width="480" height="320" muted>Your browser is too old which doesn't support HTML5 video.</video></div>
</template><script>
import flvjs from 'flv.js'
export default {data() {return {}},mounted() {this.$nextTick(() => {if (flvjs.isSupported()) {const videoElement = document.getElementById('videoElement')var flvPlayer = flvjs.createPlayer({type: 'flv',url: 'http://127.0.0.1/live?port=1935&app=myapp&stream=test',isLive: true, // <====加个这个hasAudio: false,hasVideo: true// withCredentials: false,// cors: true},{enableWorker: true, // 开启多线程enableStashBuffer: false,lazyLoad: false,lazyLoadMaxDuration: 0,lazyLoadRecoverDuration: 0,deferLoadAfterSourceOpen: false,fixAudioTimestampGap: true,autoCleanupSourceBuffer: true})flvPlayer.attachMediaElement(videoElement)flvPlayer.load() // 加载videoElement.play()}})},methods: {}
}
</script>

遗留问题

(1)前端页面支持多个视频同时播放的处理,目前chrome等现代浏览器的同源策略限制,最多播放6个直播视频流;

(2)延迟5s以上的问题,同一个视频源,页面播放与使用vlc播放器直接播放RTSP视频流之间存在3-5s的延迟问题,有待后续跟进处理;

参考文档:

1、web实现RTSP无插件低延迟播放方案整理

2、基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module(一)

3、直播流转码 RTMP 转 HTTP-FLV 用于 WEB 播放解决流程

4、【入门】无插件web直播解决方案,ffmpeg+nginx-http-flv-module+flv.js

使用FFmpeg + nginx + flv.js 实现RTSP格式视频流在web网页进行播放相关推荐

  1. vlc搭建rtsp直播Demo ffmpeg + nginx + flv.js实现rtsp网页播放Demo

    文章目录 学习链接 本地视频文件作为数据源 推流步骤 拉流步骤 本地摄像头作为数据源 拉流步骤 vlc + ffmpeg + nginx + flv.js 实现网页视频直播 概括 vlc打开摄像头,提 ...

  2. [转]web实时视频流从0到1(ffmpeg+nginx-http-flv-module+flv.js)

    海康威视视频流rtsp,需要在web(Vue)页面显示,探索了很多方法,考虑到兼容,最终确定 ffmpeg+nginx-http-flv-module+flv.js 这一套方案,也推荐大家使用这一套方 ...

  3. web实时视频流从0到1(ffmpeg+nginx-http-flv-module+flv.js)

    海康威视视频流rtsp,需要在web(Vue)页面显示,探索了很多方法,考虑到兼容,最终确定 ffmpeg+nginx-http-flv-module+flv.js 这一套方案,也推荐大家使用这一套方 ...

  4. 采用ffmpeg转换flv视频到mp4格式时报错的解决方案

    1. ffmpeg支持如下格式转换视频 $ffmpeg -i 源文件  目标文件 如: $ffmpeg -i hello.flv hello.mpeg $ffmpeg -i hello.flv hel ...

  5. 使用flv.js + websokect播放rtsp格式视频流

    1.问题背景 在最近的项目中,涉及到海康接入的视频播放的问题,海康这边获取到的视频流是rtsp格式,web端目前没有直接可以播放的组件,于是最开始是后端处理了视频流,返回hls格式的m3u8地址,这样 ...

  6. 【入门】无插件web直播解决方案,ffmpeg+nginx-http-flv-module+flv.js

    概述 这几天一直在搭建一个web端的直播平台,需求是无插件,低延迟,开源免费. 但是网上的教程,大多比较零散,没有整合成一套解决方案. 所以搜索了很多资料,也问了不少群里的大佬.本篇博客是一个资源整合 ...

  7. 基于nginx和ffmpeg前端flv.js简单的直播环境搭建(rtmp+http-flv+hls)

    https://blog.csdn.net/xjb2006/article/details/106681078 https://segmentfault.com/a/1190000016043297? ...

  8. 用ffmpeg+nginx+海康威视网络摄像头rtsp在手机端和电脑端实现直播

    原料:海康威视摄像头,nginx服务器,ffmpeg. 首先海康威视摄像头, 它的rtsp数据流的地址为:rtsp://[username]:[password]@[ip]:[port]/[codec ...

  9. ffmpeg录制屏幕并推流ffmpeg+nginx-http-flv-module+flv.js

    https://blog.csdn.net/u012848709/article/details/106064127 https://blog.csdn.net/qq_33456552/article ...

最新文章

  1. java在继承中父类的成员变量是否会被子类所覆盖
  2. 【项目管理】ITTO-成本管理
  3. C#趣味程序---百鸡百钱
  4. http 二进制_浅谈HTTP协议
  5. webpack进阶之插件篇
  6. linux 运行选择哪个cpu核,判断Linux进程在哪个CPU核运行的方法
  7. 安卓actionBar上无法显示搜索按钮如何解决
  8. 优化理论08-----约束优化的最优性条件、拉格朗日条件、凸性、约束规范、二阶最优性条件(上)
  9. 32获取外部中断状态_STM8单片机中断的主要功能解析
  10. MyBatis入门到精通,最全最详细的MyBatis学习教程来了
  11. Vue中实现页面截图并上传
  12. 专科计算机专业软件工程,软件工程专业专科学校都有哪些?
  13. 为什么微软邮箱(outlook.live.com)一个邮件也收不到
  14. IP地址后面/24/26/27/28/29/30网关数量分别是多少?如何计算?
  15. C/C++, STM32,KEIL warning: #175-D: subscript out of range
  16. iOS用AVAudioPlayer播放m4a音频
  17. 提高个人效率的方法和工具
  18. 公司技术分享-全文技术分享Lucene VS ElasticSearch VS Solr
  19. 【MySQL】根据数据表中日期字段查询某个月每一天的数据量?查询数据表中所有日期每天的数据量?近三天每天数据量?
  20. interview--- 帽子戏法

热门文章

  1. 【OD矩阵】《城市公交IC卡·数据分析方法及应用》基于换乘点的上车点识别
  2. jmeter接口顺序执行_Jmeter接口测试顺序
  3. Sql性能优化之sql语句的写法
  4. css文字后面跟加的割竖杠 |
  5. 秦九韶算法 Horner算法
  6. web-harvest 采集腾讯读书“ 小说
  7. 空气净化器的过滤网能够清洗吗?怎样清洗?
  8. ble - GATT 协议详解
  9. OCAD应用:多重转换式断续变焦系统设计
  10. 综合FuSa和SOTIF的无人驾驶扩展HARA分析方法