ffmpeg推流 nginx-http-flv-module作为流媒体服务器转流m3u8 前端vue集成videojs-player播放 实现、调优、问题解决

news2024/9/22 13:45:47

背景:

       最近公司要基于双目视觉做鹤管自动充装项目,需要对相机的流媒体进行推流,推流到流媒体服务器后,再将流转换成页面能播放的flv或m3u8格式的直播流,然后在页面进行视频直播。本项目共有四个鹤位,所以需要同时对4个相机的视频进行直播,且要保证直播的实时性。

实现:

1、安装流媒体服务器 基于nginx 安装nginx-http-flv-module模块
  1. 下载nginx依赖

apt-get install build-essential libpcre3 libpcre3-dev libssl-de
  1. 新建一个文件夹nginx_rtmp并切换到该目录下

    mkdir nginx_rtmp
    cd nginx_rtmp/
  2. 上传nginx和nginx-http-flv-module压缩包到nginx_rtmp,压缩包下载地址:链接:https://pan.baidu.com/s/1n_40umpZgZY8hEdtoJrg0Q 提取码:weda

  3. 解压nginx.zip、nginx-http-flv-module.zip

  4. 解压缩

    tar -xf nginx-1.21.6.tar.gz
    unzip nginx-http-flv-module.zip
    将解压后的nginx-http-flv-module 移动到 /usr/local/nginx-http-flv-module 目录下
  5. 编译nginx, 同时设置第三方模块

    cd nginx-1.21.6/
    ./configure --with-http_ssl_module --add-module=/usr/local/nginx-http-flv-module
    make && make install

    如果此步报错,可能是没装zlib,可执行以下命令

    sudo apt update
    sudo apt install zlib1g-dev
    
  6. 检查nginx是否安装完成

    /usr/local/nginx/sbin/nginx -v
  7. 将nginx添加到环境变量中, 不一定用vim

    vim /etc/profile.d/export_path.sh

    添加内容

    #!/bin/bash
    ​
    export PATH=$PATH:/usr/local/nginx/sbin/

    生效:

    . /etc/profile
    nginx -v
  8. 修改nginx的配置文件 路径>>/usr/local/nginx/conf/nginx.conf*

    vim /usr/local/nginx/conf/nginx.conf

    将准备好的nginx.conf内容覆盖进去,配置文件有两个,一个是转流为flv格式的,一个是转流为m3u8格式的,后续说一下区别

  9. 启动

   /usr/local/nginx/sbin/nginx
2、使用ffmpeg进行推流
安装ffmpeg

```bash
apt install ffmpeg
```

推流命令
A、将rtsp视频推流生成flv格式:
ffmpeg -rtsp_transport tcp -i rtsp://admin:Admin12345@192.168.1.65:554/h264/ch0/main/av_stream -c:v libx264 -c:a aac -threads 5 -preset ultrafast -max_delay 100000 -f flv -an rtmp://192.168.1.171:1935/live/room

其中,运行日志中的fps为帧率,即一秒会产生多少张图片。

说明:

此种方式使用的是nginx-flv.conf中的配置内容

a、rtsp://admin:Admin12345@192.168.1.65:554/h264/ch0/main/av_stream 这个地址是我的摄像头播放地址,请查看并使用你使用的摄像头播放地址,可以是rtsp的也可以是MP4。

b、rtmp://192.168.1.171:1935/live/room 为nginx.conf配置的rtmp的地址,room是推流地址唯一标识,可以自定义。

推流成功后,使用VLC播放器进行播放,播放地址为:http://192.168.1.171:80/live?port=1935&app=live&stream=room,其中192.168.1.171换成你的服务器ip ,live是nginx.conf配置文件中配置的http标签下server下的location live的请求服务地址,port为nginx.conf配置文件中rtmp标签下server监听的端口号(注意开放服务器防火墙),app=live这个live与rtmp标签下 server下的location live所对应,stream=room这个room与你自定义推流地址所对应。

至此,rtsp转换成flv转换完成。

B、将相机最原始的视频转成m3u8,这种方式指的是将相机与服务器直接通过usb相连,然后获取相机中的视频并进行转换,不是将网络地址进行推流转换。
ffmpeg -y -an -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -s 768x512 -r 20 -i - -c:v libx264 -pix_fmt yuv420p -preset ultrafast -f flv -rtmp_live live -tune zerolatency -preset ultrafast -g 14 rtmp://192.168.1.171:1935/live/171

说明:

此种方式使用的是nginx-m3u8.conf中的配置内容。

rtmp://192.168.1.171:1935/live/171 为nginx.conf配置的rtmp的地址,171是推流地址唯一标识,可以自定义。

推流成功后,使用VLC播放器进行播放,播放地址为:http://192.168.1.171:80/live/171.m3u8,其中192.168.1.171换成你的服务器ip ,live是nginx.conf配置文件中配置的http标签下server下的location live的请求服务地址,room.m3u8这个room与你自定义推流地址所对应。

其中,nginx-m3u8.conf配置文件相关配置如下:

rtmp {
        server {
                listen 1935;
                chunk_size 4096;
 
                application live {
                 live on;
                 hls on; 
                 hls_path /usr/local/hls/files;
                 hls_fragment 200ms;           
                 hls_playlist_length 1400ms;
                 hls_cleanup on;
                 hls_max_fragment 200ms;
                 # exec_push ffmpeg -i rtmp://input -an -c:v libx264 -preset veryfast -f flv rtmp://output;
        }
    }
}

rtmp标签下hls部分参数解释如下:

live on;    # 开启直播模式

hls on;    # hls 格式

hls_path /usr/local/hls/files;   # 生成的视频流文件临时存储路径

hls_fragment 700ms;    # 一个ts切片文件的时长,eg:500ms

hls_max_fragment  1000ms;   #一个ts切片的最大时长,eg: 700ms; ts文件的时长会小于 hls_max_fragment ,大于等于 hs _fragment,建议hls_max_fragment大于等于2000ms,并且小于2 * hls_fragment 

hls_playlist_length 2100ms;    #与hls_fragment参数一起控制.m3u8文件中.ts列表数,eg:hls_playlist_length=1500ms,hls_fragment=500ms,则.m3u8文件中共有3个ts文件列表,建议此值为hls_fragment的三倍

hls_sync 2s; #音视频的同步时间,通俗一点就是强制的音/视频同步,可以防止音画不同步的现象,默认是2ms,

hls_continuous onloff #设置连续模式,打开HLS连续模式。 在这种模式下,HLS序列号从上次停止的地方开始。 老片段被保存。 默认为关闭。

hls_nested on|off   #默认是off。切换HLS嵌套模式。在此模式下,hls_path为每个流创建一个子目录。播放列表和片段在该子目录中创建。默认为关闭。

hls_base_url    #设置基准URL,对于m3u8中使用相对URL有效。设置HLS播放列表项目的基本URL。 当为空时,这些项目没有前缀,并假定与父播放列表位于相同的位置,或者在使用hls_nested时降低一个级别。 此功能适用于主(变式)和从HLS播放列表。 它可以让您下载播放列表并在本地播放,因为它包含对子播放列表或片段的完整引用。 默认为空。

hls_cleanup on|off    #切换HLS清理。 默认情况下,该功能处于打开状态。 在这种模式下,nginx缓存管理器进程从HLS目录中删除旧的HLS片段和播放列表。

hls_fragment_naming system|timestamp|sequential #使用系统时间、使用流时间戳、使用递增的整数顺序(默认),

exec_push ffmpeg -i rtmp://input -an -c:v libx264 -preset veryfast -f flv rtmp://output;   # 某些情况下,可以使用此参数对流进行二次处理

参考:【官方文档】Nginx模块Nginx-Rtmp-Module学习笔记(二)HLS 指令详解_51CTO博客_Nginx-rtmp-module

通过此种方式,会在hls_path配置的路径下生成.m3u8文件和.ts文件,.m3u8文件中的内容是要播放的.ts列表,然后再通过nginx http标签配置代理转发到.m3u8文件,就可以实现视频流的播放,如下图:

至此,m3u8转换完成。

ffmpeg相关参数说明:

-threads 5 -preset ultrafast -max_delay 100000 参数

-threads 5的意思是 设置编解码等工作的线程数,线程数多了速度自然比一个线程处理的快;

-preset ultrafast 用来指定视频的输出质量,它共有以下几个可以用的值:

ultrafast 超快的
superfast 超高速的
veryfast 非常快
faster 更快
fast 快
medium 中等
slow 缓慢的
slower 较慢的
veryslow 非常慢
我们这里使用的是 ultrafast 超快的;

-max_delay 100000 表示指定视频的最大延迟,这里设置100ms

以上参数为调优参数,可以降低视频的延迟,也可以使用降低分辨率、视频大小来增加推送速度,降低延时

下面是一些常用参数:

  1. -i (input): 指定输入文件或者 URL。

  2. -f (format): 指定输出文件格式。

  3. -vcodec (video codec): 指定视频编解码器。

  4. -acodec (audio codec): 指定音频编解码器。

  5. -ss (start time): 指定开始时间。

  6. -t (duration): 指定持续时间。

  7. -r (frame rate): 指定帧率。

  8. -s (size): 指定视频分辨率。

  9. -b (video bitrate): 指定视频比特率。

  10. -ab (audio bitrate): 指定音频比特率。

  11. -ar (audio sampling rate): 指定音频采样率。

  12. -vn: 禁止视频流。

  13. -an: 禁止音频流。

  14. -c:v copy: 将视频流拷贝到输出文件,避免重新编码。

  15. -c:a copy: 将音频流拷贝到输出文件,避免重新编码。

  16. -filter_complex: 指定复杂的过滤器图形。

  17. -map: 选择流进行处理和映射。

  18. -preset: 指定编码预设。

  19. -crf: 指定恒定质量的压缩级别。

  20. -pix_fmt: 指定像素格式。

  21. -af: 音频过滤器。

  22. -vf: 视频过滤器。

  23. -movflags: 指定 MOV 文件特定的标志。

  24. -y: 覆盖输出文件而不询问。

  25. -loglevel: 指定日志级别。

  26. -g: 关键帧数,推流生成hls时使用,值为:帧率(ffmpeg -r参数值) * hls_fragment(rtmp配置中的值,转换成秒,如700ms,则为0.7)

遇到的问题及调优

1、生成的flv视频延迟严重及卡顿问题?

通过修改ffmpeg推流参数解决:-threads 5 -preset ultrafast -max_delay 100000(具体参数解释,上文中有说明)

也可以修改相机的曝光度、推流分辨率等方法实现。

2、生成的.ts文件不连续,且有时不生成,配置的hls相关参数不生效?

此处原因是因为生成ts文件时,需要一个关键帧的概念,ts文件是根据关键帧生产的,如果ffmpeg推流时不设置关键帧或者关键帧设置的不对,生产.ts文件时就会有问题,且hls_fragment、 hls_playlist_length等参数设置不生效。关键帧的设置方式是在ffmpeg推流时添加 -R参数,例如:ffmpeg -R 10。其中关键帧的计算方式为:ffmpeg推送帧率(-r 参数对应的值) * nginx.conf中hls_max..的值(按秒进行折算),比如:ffmpeg推送帧率是20,nginx.conf中配置的hls_fragment的值为700ms,则关键帧=20*0.7 = 14,此时生成的每个ts文件中会有14帧,即14张图片。

3、vue3集成video.js组件播放m3u8视频流时,视频经常卡顿,不流畅?

这个问题主要原因是nginx.conf中关于hls的相关参数设置不当造成的,hls_fragment不易设置过低,如果过低,其生成速度会过快,导致前端页面请求速度跟不上(前端请求完.m3u8获取ts列表后,相应的ts就消失了),会导致丢帧,在不考虑延时问题的情况下,hls_fragment值大一些会比较好,比如2s。由于我们对时效性有要求,所以最开始的时候设置的太低(200ms),结果导致出现问题。后来,hls_fragment改为500ms,hls_playlist_length改为1500ms,视频开始流畅,随着数值加大会更好,但是延时会增加。总之,hls_fragment、hls_max_fragment、hls_playlist_length几个参数要不断尝试,以调整出最优参数

4、vue3集成video.js组件播放m3u8视频流时,播放一段时间后,发现视频也会有稍微的卡顿,且此时http请求获取的ts文件大小都是375B(正常是200KB左右),此时如果刷新浏览器会恢复正常。(使用vlc没有这个问题)?

这个问题是由于m3u8是基于HLS协议的格式,需要浏览器对视频进行「解码」播放,如果浏览器的解码能力有限(比如当视频的 m3u8 文件加载成功并且浏览器无法获取其中一个 ts 文件时),video.js会不断进行重试,导致视频画面卡顿。而VLC支持多种媒体格式和协议,最重要的是能自适应解码(能够在解码过程中自动调整解码参数),提供了流畅的播放效果。所以video.js插件播放m3u8会卡顿,VLC就不会。此时刷新浏览器也可以恢复正常。

当出现卡顿时,http请求.ts文件的响应数据结果都是375B(正常是200KB左右)刷新浏览器加载出首帧时,说明初始化已经成功,刚开始不会卡顿,直到继续在解码过程中解码性能受阻时,才会继续卡顿。  出现卡顿时,http的请求数据为375B,可以认为是异常了,因为无法继续获取下一个有效的ts文件(正常的180KB),仅获取到了一些无用的文件(大小375B)。

综上所述,基本认为是浏览器的解码能力有限导致的。

解决此问题,

1、可以继续加大hls_fragment参数的值,通过降低ts文件的请求次数从而降低对浏览器解码性能的消耗,但是此方法会增加视频延时。

2、也可以通过提升浏览器的解码能力来改善,提升浏览器解码能力的方法为:

a、​​chrome​​​浏览器–>​​右键​​​–>​​属性​​​–>​​目标​​​: 先加一个​​空格​​​,然后输入:​​--enable-features=PlatformHEVCDecoderSupport​​​; 点击​​应用​​.
--enable-gpu-rasterization   # 启用GPU
--force-local-ntp            # 强制本地NTP
--enable-features=PlatformHEVCDecoderSupport  # 使用HEVC硬件解码---Windows以外平台需要提供解码包

b、设置谷歌浏览器使用独立显卡
桌面-右键-显示设置-显示卡-浏览-选择谷歌浏览器安装目录下的Chrome.exe文件,添加后,点击选项-弹窗后选择高性能

5、使用video.js组件播放直播视频时,无法刷新、无法更换视频播放地址

前端是VUE3,之前使用video.js组件,但是使用此组件,无法更换视频地址,也无法刷新视频,用了网上的N种方法都不行,后来机缘巧合之后,发现了一个叫videojs-player的组件,引入方式为在package.json文件的dependencies下添加依赖:"@videojs-player/vue": "^1.0.0",注意此组件应该是对video.js组件进行了封装,所以也需要依赖video.js。

添加依赖之后,在代码中添加一下代码即可:

<div v-for="(arm, index) in loadArmData"
      class="view-option"
      :style="[{ height: optionHeight + 'px' }]">
    <video-player
       :ref="el => (videoRefs[index] = el)"
       :id="'video' + index"
       style="width: 100%; height: 100%"
       controls
       autoplay
       :muted="true"
       :preload="true"
       :src="arm.videoAddress"
       v-if="videoShow[index]"/>
</div>

如果想对视频进行刷新,有两种非常简单的方式:

一种是通过v-if进行控制,代码如下:

videoShow.value[index] = false
nextTick(() => {
  videoShow.value[index] = true
})

一种是通过修改src的值来实现,代码如下:

loadArmData.value[index].videoAddress =
          loadArmVideoUrlData.value[index] + '?t=' + new Date().getTime()

参考博客地址:https://blog.csdn.net/Aarstg/article/details/122937043

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1132151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1024 有奖征名|来给矩阵起源办公室的新猫取名字呀~

在一个风雨交加的夜晚&#xff0c;一只无名的小黑猫突然出现在矩阵起源办公室中。这只小黑猫的出现引起了员工们的惊讶和好奇。他的毛色乌黑亮丽&#xff0c;眼神炯炯有神&#xff0c;容貌精神焕发&#xff0c;脚步身轻如燕、叫声熠熠生辉。尽管大家都很喜欢这只可爱的小动物&a…

项目管理-2023西电网课课后习题答案-第二章

文章目录 第二章答案1-1011-2021-3031-4040-42 [✅] 第一章答案[✅] 第二章答案 第三章答案 第四章答案 第五章答案 第二章答案 1-10 11-20 21-30 31-40 40-42

【Redis系列】在Centos7上安装Redis5.0保姆级教程!

哈喽&#xff0c; 大家好&#xff0c;我是小浪。那么最近也是在忙秋招&#xff0c;很长一段时间没有更新文章啦&#xff0c;最近呢也是秋招闲下来&#xff0c;当然秋招结果也不是很理想&#xff0c;嗯……这里就不多说啦&#xff0c;回归正题&#xff0c;从今天开始我们就开始正…

横坐标日期等间隔绘图 python示例代码

有两列数据&#xff0c;一列是日期&#xff0c;另一列是数值。日期是递增的&#xff0c;但是间隔不是均匀的。比如1月1日至2月1日有10组数据&#xff0c;2月1日至3月1日有100组数据&#xff0c;3月1日至4月1日有1000组数据。我想绘折线图&#xff0c;横坐标是日期&#xff0c;纵…

内网电脑监控软件的功能

内网电脑监控软件是一种用于监控企业内部网络使用情况的软件&#xff0c;可以帮助企业管理者更好地了解员工的工作状态和网络使用情况&#xff0c;提高工作效率和信息安全。 其功能具体如下&#xff1a; 1、实时电脑屏幕 实时监控是内网电脑监控软件的核心功能之一&#xff0…

Redis数据类型——hash类型的概念及操作

1.hash类型介绍 可以理解为redis中的一个小型redis 2.v 3.hash数据类型的扩展操作 4.hash类型数据操作的注意事项

SylixOS BSP开发(七)

实现系统调试信息打印接口 当系统出错时或者使用内核日志时会输出一些打印信息&#xff0c;这最终都是调用到bspLib.c中的bspDebugMsg 这个接口来实现的&#xff0c;所以我们在开发BSP时&#xff0c;第一个要做的工作就是实现这个接口。 一般的调试信息都是通过串口来输出的&am…

Autojs 利用OpenCV识别棋子之天天象棋你马没了

本例子通过代码像你介绍利用OpenCV实现霍尔找圆的方法定位棋子位置 通过autojs脚本实现自动点击棋子 开源地址 https://github.com/Liberations/TtxqYourHorseIsGone/blob/master/main.js AutoXJs https://github.com/kkevsekk1/AutoX/releasesauto() //安卓版本高于Android 9…

受欢迎的免费在线数据库设计工具Itbuilder

工欲善其事必先利其器&#xff0c;众所周知&#xff0c;良好的数据库设计能够大幅减少后期的运维工作&#xff0c;同时也能最大程度地减少软件项目出错的可能。因此一个合适的在线数据库设计工具&#xff0c;来实现事半功倍的效果。 什么是在线数据库设计&#xff1f; 在线数据…

容联七陌助力鱼跃医疗升级智能联络中心,让客户服务更“鱼跃”

在当今高度竞争的市场环境中&#xff0c;企业的客户服务质量对于维护品牌形象和保持竞争优势至关重要。而随着人工智能、大数据等技术快速发展&#xff0c;智能化客户服务正在成为各行各业发展的重要部分。 鱼跃医疗是一家致力于“用科技律动生命"的国内知名医疗制造企业…

GaussDB技术解读系列:如何迁移到GaussDB?

迁移是数据库选型过程中客户最为关心的话题之一&#xff0c;经过大量的沟通调研&#xff0c;我们总结了三个客户在数据库迁移方面的主要期望&#xff1a;迁移不影响业务运行&#xff08;安心&#xff09;&#xff0c;迁移不能丢数据&#xff08;放心&#xff09;&#xff0c;迁…

损失函数总结(四):NLLLoss、CTCLoss

损失函数总结&#xff08;四&#xff09;&#xff1a;NLLLoss、CTCLoss 1 引言2 损失函数2.1 NLLLoss2.2 CTCLoss 3 总结 1 引言 在前面的文章中已经介绍了介绍了一系列损失函数 (L1Loss、MSELoss、BCELoss、CrossEntropyLoss)。在这篇文章中&#xff0c;会接着上文提到的众多…

【Note】一般二叉树的顺序存储

一般二叉树的存储示意图 位置i012345678910结点ABC^D^E^^F

离子阱领域新突破!滑铁卢团队在量子比特控制方面取得进展

&#xff08;图片来源&#xff1a;网络&#xff09; 要想打造未来量子计算机&#xff0c;就需要对量子比特进行精准可靠地控制。研究人员利用激光开发出了一种新方法&#xff0c;可以控制由化学元素钡制成的单个量子比特&#xff0c;这是迄今为止最好的离子阱量子比特控制方法…

使用Redis部署 PHP 留言板应用

使用Redis部署 PHP 留言板应用 启动 Redis 领导者&#xff08;Leader&#xff09;启动两个 Redis 跟随者&#xff08;Follower&#xff09;公开并查看前端服务清理 启动 Redis 数据库 创建 Redis Deployment apiVersion: apps/v1 kind: Deployment metadata:name: redis-le…

【IDEA查看一个jar包的依赖】

首先install,打jar包 重新创建一个项目 选中刚才的jar包 在这个包下就能看到jar包的依赖了

每日一练 | 华为认证真题练习Day122

1、路由器所有的接口属于同一个广播域。 A. 对 B. 错 2、下列配置默认路由的命令中&#xff0c;正确的是&#xff08;&#xff09;。 A. [Huawei]ip route-static 0.0.0.0 0.0.0.0 192.168.1.1 B. [Huawei-Serial0]ip route-static 0.0.0.0 0.0.0.0 0.0.0.0 C. [Huawei]ip…

做测试5年,熬到阿里P6,月薪25k,我总结了这些技能点

你是不是经常在工作中遇到过这些问题&#xff1a; Linux下查看端口占用命令你还记得吗&#xff1f; python容器数据操作你清楚吗&#xff1f; Devops要用了&#xff0c;各种必备技能你还不熟&#xff1f; 接口调不同&#xff0c;排查思路不清楚&#xff1f; …… 以上这些…

JMeter + Ant + Jenkins持续集成-接口自动化测试

需要安装的工具&#xff1a; jdk1.8jmeter3.2ant1.9jenkins2.1 1、Jdkwin7系统如何安装jdk及环境变量的配置-百度经验 安装包安装设置环境变量验证是否安装正确 Java -version检查&#xff0c;如下就代表安装成功了&#xff0c;环境变量设置就去搜索了&#xff0c;网上很多…

基于springboot实现就业信息管理系统项目【项目源码+论文说明】

基于springboot实现就业信息管理系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人…