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

您所在的位置:网站首页 前端rtsp转flv 使用FFmpeg + nginx + flv.js 实现RTSP格式视频流在web网页进行播放

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

2024-07-17 22:14| 来源: 网络整理| 查看: 265

近期,出于项目需要,要求支持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/local tar -zxvf nginx-1.8.1.tar.gz cd 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、重启nginx nginx -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= 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/[email protected]/1.1.1i 出现以下类似文案,表明命令执行成功: Configuration summary + using system PCRE library + using OpenSSL library: /usr/local/Cellar/[email protected]/1.1.1i + using system zlib library nginx 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 ]; then eval `/usr/libexec/path_helper -s` fi if [ "${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 重启该配置文件 输入以下结果表明全局可使用nginx app@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:[email protected]: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:[email protected]:554/Streaming/Channels/101': Metadata: title : Media Presentation Duration: N/A, start: 0.240000, bitrate: N/A Stream #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:[email protected]:554/Streaming/Channels/101': Metadata: title : Media Presentation Duration: N/A, start: 0.240000, bitrate: N/A Stream #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:[email protected]: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进行配置的

原生video Your browser is too old which doesn't support HTML5 video. 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, //


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3