软件研究之Ffmpeg
1.前言
最近遇到的项目就是利用网站播放视频,于是我研究了 流媒体 技术,其中较多的就是利用 ffempeg 将mp4转换为m3u8格式。
【1】.FFmpeg常用推流命令
【2】.网站播放视频较慢,利用mp4转m3u8解决
【3】.视频直播支持的分辨率和对应合适的码率 1920×1080:500 kbps~4000 kbps。
【4】.FFMPEG之视频编码那些事儿 视频压缩:帧内压缩(Intraframe compression)、帧间压缩(Interframe compression)、GOP(Group Of Picture)
2.安装
2.1.windows
(1) 下载
(2) 解压之后,配置环境变量
1 | ffmpeg -version |
(3) 使用
1 | ffmpeg -i E:\demo\demo.MP4 -profile:v baseline -level 3.0 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls E:\demo\demo.m3u8 |
2.2.linux
最新版的 ffmpeg-master-latest-linux64-gpl.tar.xz 版本,可以不用编译,直接下载解压配置环境变量就可以使用了。
(1) 下载
(2) 解压
1 | # 第一步 |
(3)配置环境变量
1 | vi /etc/profile |
(4)查看是否安装成功
1 | ffmpeg -version |
(5)执行命令生成
和windows上一样,也是可以直接使用命令执行的。
3.Java
其实不安装ffmpeg的二进制,直接使用java也是可以的。
(1)引入依赖
1 | <!-- Optional GPL builds with (almost) everything enabled --> |
【1】.Maven相关依赖
(2)核心代码
1 | /** |
【1】.Java使用FFmpeg实现mp4转m3u8 这里从安装到 java 调用,讲到都非常的详细。
【2】.在 java 中使用 ffmpeg 的四个阶段 阶段一:字符串阶段;阶段二:封装阶段;阶段三:工具类阶段;阶段四:最终阶段
【3】.javacv ffmpeg 本地还需要装ffmpeg吗
【4】. Java整合ffmpeg视频处理的正确使用方式 最后还是使用了命令行的形式进行的。
【5】.springboot 通过javaCV 实现mp4转m3u8 上传oss 这是主要的代码。
【6】.java中File转为MultipartFile的四种方式
【7】.如果通过javacv来调用ffmpeg解析mp4视频为m3u8,内存式hls切片.通过流的方式来保存? 这里还提供了利用 chrome 进行测试的方法,安装Play HLS M3u8 插件,如果没有,那么自己找个离线可以播m3u8的软件即可
【8】.Java实现视频加密及播放 这里使用了 nginx 进行了转发。
5.前端播放
可以使用 hls.js 进行播放,还可以使用 xgplay-hls 进行播放。
【1】.xgplayer-hls hls 播放插件,H264 和 H265 编码格式(H265支持解析,能否播放取决于浏览器是否支持H265编码格式)
6.编码加密
因为我在设置的时候,总是无法编码成 h264 格式,所以就想着去尝试下其他的方式,不知道行不行的。
【1】.chrome 如何开启HEVC硬件解码 前期chrome官方版本一直未支持H265,因此前期只能通过自己编译chrome源码来生成H265定制浏览器,但是不支持硬解码的缺陷一直是一个大坑,我们一度准备放弃chrome浏览器,前几天忽然听说chrome 105以上的稳定版本已经集成了HEVC解码并且支持硬解
【2】.ffmpeg 用显卡转码切片hls m3u8文件的方法 key加密 ffmpeg 无损HLS切片参数例如,注意压制时关键帧设置1秒
7.视频压缩
我有几个文件,1080p的文件,没有压缩之前达到了3.7G的大小,就算是用1s钟进行分片,结果还是无法打开播放。
1 | private static final int FRAME_RATE = 30; // 帧率 |
【1】.JAVA,实现视频压缩(最全) Java压缩视频大小,10M视频压缩完成后大约是1M,用时大约2S
【2】.Java 压缩视频(无需安装插件) 这里用了 jave-nativebin-osx64 这个东西。
【3】.为什么我的带有Hls.js视频播放器的应用程序在3-4个小时后就会结冰呢?
【4】.ffmpeg实例,比特率码率(-b)、帧率(-r)和文件大小(-fs)相关操作 帧率(Frame rate)也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。码率也叫比特率(Bit rate)(也叫数据率)是一个确定整体视频/音频质量的参数,秒为单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用bps来表达。控制输出文件大小。
【5】.JavaCV开发详解之4:本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地) 这个的代码里面的注释倒是挺多的,比如比特率、质量、音频等的设置。还包括了一些视频抓取之类的东西。
【6】.javacv FFmpeg 视频压缩 这里的代码还是挺好用的,进行了视频压缩重采样,好用。
【7】.使用ffmpeg缩小视频体积的几种方式 调整视频的分辨率;调整视频的码率;使用更高效的视频编码格式;
【8】.java实现,无损视频大小压缩 这里用了这个插件 it.sauronsoftware
问题
(1)av_interleaved_write_frame() error -2 while writing interleaved audio packet
这个问题就是启用了 加密,如果把加密的地方注销掉,就会出现这个问题,下面的代码就是,可以不加密,但是不能没有加密文件。
1 | //生成加密key |
(2)hls.js 播放黑屏,只有声音
大部分的文章都是因为 h265 编码的问题,但是我设置的编码格式是 h264的编码格式啊。
1 | // 设置编码格式 |
【尝试方案】
(1) 修改编码方式,多次重新编译。
【解决方案】
最后的解决方案是将 hls_segment_type 设置为 fmp4 而不是 mpegts。
1 | /*hls的切片类型: |
【1】.从s3存储桶播放.m3u8文件时出现视频黑屏和仅有声音的问题 这里加了一个 X-Amz-Meta-File-Range-Start=0 请求参数
【2】.hls.js播放m3u8为什么黑屏,控制台的log正常,ts文件也一直在解析? 大概率是因为H.265导致的。
【3】.主流视频编码器特点、优缺点归纳和比较(H.264、HEVC、VP9、AV1) High Efficiency Video Coding,又称H.265/HEVC,是一种新的视频压缩标准,用来扩充H.264/AVC编码标准,2013年1月26号,HEVC正式成为国际标准,收取版税。为了应对互联网流媒体、通信、视频会议、数字存储媒体和电视广播等各种应用对运动图像更高压缩率的日益增长的需求而开发的。
【4】.m3u8流文件在html视频播放器中播放有声音无画面问题 故视频解码时无法正常解码,所以只需要在海康的摄像头中更改流媒体格式为H264,那么视频就可以正常播放了
【5】.JAVA ~ FFmpegFrameRecorder用H264编码封装mp4 有声音无图像 这里设置了 avcodec.AV_CODEC_ID_H264,并设置了 setFormat(“mp4”),但是对我没有效果。
【6】.java网络摄像头播放、截图、rtsp转m3u8 这里提供了 rtsp转m3u8,具体的方法和前面的差不多。
(3)无法加密
当设置了 recorder.setOption(“hls_segment_type”, “fmp4”),但是就无法进行加密了,recorder.setOption(“hls_key_info_file”, keyInfoPath),否则就会报错。
1 | /*hls的切片类型: |
【解决方案】
最后我也没有解决,尝试了很多次,结果也都是这个样子的,没有什么意外,只能先放弃了。
(4)设置 hls_time 不能按时间进行分片,有的多有的少
【1】.关于 javacv hls 切片结果很模糊的为 recorder.setGopSize(2 * frameRate);//设置 gop
【2】. 流媒体直播实时视频延迟时间排查和剖析:gop关键帧间隔导致延迟,流媒体和播放器缓存,B帧等导致的延迟 原创
【3】.使用FFmpeg命令进行hls切片,得到的ts文件时长不准确,如何精确控制m3u8切片时长
【4】.基本概念 为便于您更好的理解视频点播产品,您可以在使用前了解视频格式、视频编码、视频转码等基本概念。
(5)moov atom not found
有些视频文件可以被压缩,有些视频不能压缩,不知道什么原因,压缩的时候报错:[libx264 @ 0x7fc7497d9d00] non-strictly-monotonic PTS。“Application provided invalid, non monotonically increasing dts to muxer in stream 0”
【解决方法】
经过我多方的测试和查找,后来我发现这个原始视频的帧率有些不正确,原视频的帧率是29.53fps,后来我统一改成了 30.0 fps。
1 | recorder.setFrameRate(FRAME_RATE); |
【1】.How to Fix Video ‘Moov Atom Not Found’ Error?
【2】.3个方案解决视频“Moov Atom Not Found”错误问题 方法 1. 使用万兴易修的视频修复功能修复视频错误。方法 2. 使用 qtfaststart 修复 FFMPEG “Moov Atom Not Found”。方法 3. 使用 MP4box 解决“Moov Atom Not Found”视频错误。
【3】.ffmpeg使用libx264编码时,为何一直出现x264 [warning]: non-strictly-monotonic PTS?
【4】.FFmpeg h.264 mp4编码告警:non-strictly-monotonic PTS 选用ABR需要注意两个设置,fps和输出帧pts计算。切换到h.265编码倒没这个警告,
【5】.Web端H.265播放器研发解密 音视频编解码对于前端工程师是一个比较少涉足的领域,涉及到流媒体技术中的文本、图形、图像、音频和视频多种理论知识的学习,才能够应用到具体实践中,我们自研web播放器并支持h.265解码,在码率优化的大背景下(保持画质不变情况下,应用图像增强、roi区域检测、智能场景分类和h265编解码等多种技术能力,将码流降低50%。
(6) invalid DTS: PTS is less than DTS
有些视频进行压缩的时候,就出现了问题。出现这种错误是由于视频pts大于dts。解释是:pts是视频播放时间,dts是送入解码器解码时间。所以一帧视频播放时间必须在解码时间点之后。
【尝试方案】
(1).使用packet进行压缩,结果没有效果。
1 | for (; (avPacket = frameGrabber.grabPacket()) != null;) { |
(2).在while循环中的合适位置添加if(pkt.pts < pkt.dts) continue; 这个方法没有搞定。
(3).取消了时间戳设置
1 | recorder.setTimestamp(frameGrabber.getTimestamp()); // 注释掉了 |
(4) 使用只存储关键帧的方法
1 | if(captured_frame.keyFrame){ |
【解决方法】
最后的解决方法让我非常的崩溃,只是注释了 recorder.setTimestamp(frameGrabber.getTimestamp()); 这句话,让解码器自动计算时间戳。
1 | recorder.start(); |
【1】.【FFmpeg】关于对错误pts () < dts () in stream的解决方法 在while循环中的合适位置添加 if(pkt.pts < pkt.dts) continue;
【2】.PTS 和 DTS 理解
【3】.深入理解FFmpeg的Packet和Frame数据结构 Packet是FFmpeg中用于封装音视频数据的基本单元。Frame是FFmpeg中用于存储解码后的音视频数据的数据结构。在解码阶段,解码器会将解码后的音视频数据填充到Frame中。一个Frame中包含了一帧完整的音视频数据,通过Frame的成员变量可以获取到这些数据的相关信息,如宽度、高度、采样率等。
【4】.如何跨平台调用ffmpeg?史上最简单基于JavaCV跨平台执行ffmpeg命令 这里有一个地方就是使用
【5】.java 视频转码 视频压缩 这里有视频大小分辨率建议码率,还有码率公式。
【6】.JavaCV 之音视频基础概念 I帧、B帧、P帧、DTS、PTS了解 AVFrame是已解码的帧数据,需重新编码才能正常保存为视频文件;AVPacket是解码前的原始数据,无需重新编码也能正常保存
【7】.javacv 获取 I帧间隔 通过 Frame 类的 keyFrame 属性,我们可以判断是否为I帧
【8】.java cv流媒体处理高频抓帧 FFmpegFrameGrabber 提供了一系列方法来设置视频源、读取视频帧、获取视频信息等操作。通过FFmpegFrameGrabber 类,我们可以获取视频流、抓取视频帧并进行处理。
【9】.javacv I帧转图片 总共有六个步骤:1.导入所需的javacv库;2.初始化视频文件;3.读取视频帧;4.获取帧;5.将帧转为图片;6.保存图片。获取P帧,
1 | if(frame.image!=null){ |
【10】.javacv之视频和音频的合并 当视频长度大于音频长度时,进行和成。