《FFmpeg从入门到精通》读书笔记(二)[通俗易懂]

《FFmpeg从入门到精通》读书笔记(二)[通俗易懂]写在前面2019.06.18第三章知识点(未进行排版)第三章FFmpeg转封装一、MP4格式标准MP4文件由许多个Box与FullBox组成;每个Box由Header和Data两部分组成;FullBox是Box的扩展,其在Box结构的基础上,在Header中增加8位version标志和24为flags标志;Header包含了整个Box的长度的大小(size)和类型(ty…

大家好,又见面了,我是你们的朋友全栈君。

写在前面

2019.06.18

第三章 FFmpeg转封装


第三章 FFmpeg转封装

一、MP4格式标准

MP4文件由许多个Box与FullBox组成;每个Box由Header和Data两部分组成。
FullBox是Box的扩展,其在Box结构的基础上,在Header中增加8位version标志和24为flags标志;
Header包含了整个Box的长度的大小(size)和类型(type):size=0,代表这个Box是文件的最后一个Box; size=1,说明Box的长度需要更多的位来描述,在后面会定义一个64位的largesize用来描述Box的长度; type=uuid,说明这个Box中的数据是用户自定义扩展类型
Data为Box的实际数据,可以是纯数据,也可以是更多的子Box;
当一个Box中Data是一系列的子Box时。这个Box又可以成为 Container Box

MP4中Box的组成 (书 P61-63)

主要信息:
在这里插入图片描述
Note:尺寸、类型、版本、标志 这四个字段都有

(1)moov:一级 音视频数据的metadata信息

mdat :一级 media数据容器
moov与mdat的存放位置没有强制要求; 互联网视频点播中,moov在前时,文件可以被快速打开; moov在后时,需要将MP4文件下载完成后才可以进行播放

(2)moov容器

moov容器定义了一个MP4文件中的数据信息,类型是moov,是一个容器Atom,其至少必须包含以下三种Atom中的一种:

mvhd标签,Movie Header Atom,存放未压缩过的影片信息的头容器
cmov标签,Compressed Movie Atom,压缩过的电影信息容器(不常用)
rmra标签,Reference Movie Atom, 参考电影信息容器(不常用)

还可以包含其他的标签 (书 P64)
mvhd中定义了多媒体文件的time scale、duration以及display characteristics; trak 二级 流的track,定义了多媒体文件中的一个track的信息,track是多媒体文件中可以独立操作的媒体单位,例如一个音频流或一个视频流就是一个track

(3)解析mvhd子容器

参数列表 (书 P66) 解析出视频的基本信息,包括尺寸、类型、时长、速度、音量等

(4)解析trak子容器

trak容器中定义了媒体文件中的一个track的信息,每个trak容器都有与它关联的media容器描述信息。
trak容器的主要使用目的:

包含媒体数据的引用和描述(media track)
包含modifier track 信息
流媒体协议的打包信息(hint track),hint track可以引用或者复制对应的媒体采样数据

hint track和modifier track必须保证完整性,同时要与至少一个media track一起存在。
一个trak容器中要求必须要有一个Track Header Atom(tkhd)、一个Media Atom(mdia),其他Atom可选

(5)解析tkhd容器

解析出track的尺寸、类型、ID、市场、音量等。音频与视频的trak的tkhd的大小相同,里面的内容随着音视频trak类型的不同而有所不同。

(6)解析mdia容器

Media Atom的类型是mdia,其必须包含如下容器:

一个媒体头:Media Header Atom(mdhd)
一个句柄参考:Handler Reference(hdlr)
一个媒体信息:Media Information(minf)和用户数据User Data Atom(udta)

(7)解析mdhd容器

mdhd容器被包含在各个track中,描述Media的Header,包含信息表格 P71:描述尺寸、类型、版本、生成和修订事件等。

Note:音频时长可通过Duration / TimeScale的方式来计算。

(8)解析hdlr容器

hdlr容器中描述了媒体流的播放过程,包含内容有:尺寸、类型、版本、标志、Handle的类型、Handle的子类行、保留、Component name

(9)解析minf容器

minf容器中包含了很多重要的子容器,例如音视频采样等信息相关的容器
minf容器中的信息将作为音视频数据的映射存在,内容具体如下:

视频信息头:Video Media Information Header(vmhd子容器)
音频信息头:Sound Media Information Header(smhd子容器)
数据信息:Data Information(dinf子容器)
采样表: Sample Table(stbl子容器)

(10)解析vmhd容器

图形模式:传输模式,传输模式指定的布尔值
Opcolor:颜色值,RGB颜色值

(11)解析smhd容器

均衡:音频的均衡是用来控制计算机的两个扬声器的声音混合效果,一般是0

(12)解析dinf容器

dinf容器是一个用于描述数据信息的容器,其定义的是音视频数据的信息

(13)解析stbl容器

stbl容器又称为采样参数列表的容器(Sample Table Atom),该容器包含转化媒体时间到实际的sample的信息,也说明了解释sample的信息,例如,视频数据是否需要解压缩、解压缩算法是什么 等信息。

其包含的子容器具体如下:

采样的描述、时间、同步、大小,Chunk采样、偏移等

stbl包含track中media sample的所有时间和数据索引,利用sample信息,就可以定位sample的媒体时间,决定其类型、大小,以及如何在其他容器中找到紧邻的sample

(14)解析edts容器

edts容器定义了创建Movie媒体文件中一个track的一部分媒体,所有的edts数据都在一个表里,包括每一部分的时间偏移量和长度。

一个空的edts数据用来定位到track的起始时间偏移位置。

MP4分析工具:分析MP4封装格式的工具

FFmpeg、Elecard StreamEye、mp4box、mp4info等

Elecard StreamEye

视频信息查看工具,能查看帧的排列信息,将I P B帧以不同颜色的柱状展示出来,柱的长度根据帧的大小显示;还可以分析MP4的封装内容,包括流的信息、宏块的信息、文件头信息、图像信息以及文件的信息等;还可以逐帧查看每一帧的详细信息和状态

mp4box

GPAC项目中的一个组件;针对媒体文件进行合成、拆解等操作

mp4info

可视化分析工具,将MP4文件的各Box解析出来并展示数据

MP4在FFmpeg中的Demuxer
ffmpeg -h demuxer=mp4

默认开启:

seek_streams_individually 根据单独的流进行seek

默认不开启:

user_absolute_path 可以通过绝对路径加载外部的track,可能有安全因素影响
ignore_editlist 忽略EditList Atom信息
ignore_chapters 忽略Chapters信息
enable_drefs 外部track支持

MP4在FFmpeg中的Muxer (参数 书P80)
1.faststart参数

正常情况下ffmpeg生成moov是在mdat写完成之后再写入,可以通过faststart将moov容器移动值mdat的前面(如前文所说,moov在前面,视频可以边下边播)

ffmpeg -i input.flv -c copy -f mp4 -movflags faststart output.mp4
2.dash参数
知识点:DASH介绍
DASH是一种服务端、客户端的流媒体解决方案
服务端: 
将视频内容分割为一个个分片,每个分片可以存在不同的编码形式(不同的codec、profile、分辨率、码率等); 
播放器端: 
就可以根据自由选择需要播放的媒体分片;可以实现adaptive bitrate streaming技术。不同画质内容无缝切换,提供更好的播放体验。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DASH简介及使用方法(FFmpeg, MP4Box)

ffmpeg -i input.flv -c copy -f mp4 -moveflags dash output.mp4
3.isml参数

ISMV为微软发布的一个流媒体格式,通过参数isml可以发布ISML直播流,将ISMV推流至IIS服务器

ffmpeg -i input.mp4 -c copy -moveflags isml+frag_keyframe -f ismv Stream

二、FLV格式标准

FLV文件分两部分,一部分为FLV头文件,另一部分为FLV文件内容

1.FLV文件头格式解析(字段 书P84)

签名字段用了三个字节,组成“FLV”;然后是版本、音频标记类型、视频标记类型、数据偏移

2.FLV文件内容格式解析

内容格式为上一个Tag大小+FLAGTAG,FLAGTAG分为两部分:TAGHeader部分和TAGBody部分

3.FLVTAG格式解析

头部:保留字段、滤镜位、TAG类型、数据大小占用、时间戳及扩展时间戳、流ID; 之后是Tag的data。

存储的数据分为视频数据、音频数据及脚本数据

4.VideoTag数据解析

header中读取到的Tag类型为0x09

帧类型、编码标识(CodecID)、H264的包类型(AVCPackerType)、CTS、视频数据

知识点:
PTS:Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来
DTS:Decode Time Stamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。
在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。

I,P,B帧和PTS,DTS的关系

5.AudioTag数据格式解析

header中读取到的Tag类型为0x08

声音格式(AAC、MP3、Speex等)、音频采样率(Hz)、采样大小(8或16位)、音频类型(Mono/Stereo sound)、音频包类型、音频数据

6.ScriptData格式解析

header中读取到的Tag类型为0x12
ScriptData常见的展现方式是FLV的Metadata,里面存储的数据格式一般为AMF数据
类型、数据

知识点:
AMF是Action Message Format协议的简称,AMF协议是Adobe公司自己的协议,主要用于数据交互和远程过程调用,
在功能上相当于WebService,但是AMF与 WebService中的XML不同的是AMF是二进制数据,而XML是文本数据,
AMF的传输效率比XML高。
AMF使用HTTP方式传输,目前主要是 用于ActionScript中,即实现Flex和Server之间的通信。
FFmpeg转FLV (书 P89)

封装FLV时,内部的音频或者视频不符合标准时,无法封装进FLV,如音频格式为AC3,需要先将其转换为AAC,再封装进FLV

ffmpeg -i input_ac3.mp4 -vcodec copy -acodec aac -f flv output.flv

生成带索引的FLV:将FLV文件中的关键帧建议一个索引,并将索引写入Metadata头中

ffmpeg -i input.mp4 -c copy -f flv -flvflags add_keyframe_index output.flv
FLV文件格式分析工具

flvparse、FlvAnalyzer、ffprobe

ffprobe -v trace -i output.flv

在这里插入图片描述

三、M3U8格式标准介绍

M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,既支持直播也支持点播
标签:

  • EXTM3U:M3U8文件必须包含的标签,且必须在文件的第一行

  • EXT-X-VERSION:M3U8文件的版本

  • EXT-X-TARGETDURATION:每一个分片都会有一个分片自己的duration,这个标签是最大的那个分片的浮点数四舍五入后的整数值

  • EXT-X-MEDIA-SEQUENCE:M3U8直播时的直播切片序列,当播放打开M3U8时,以这个标签的值为参考,播放对应序列号的切片

客户端播放M3U8的标准还有更多规则:

分片必须是动态改变的,序列不能相同,且序列必须是增序的
当M3U8列表中没有出现EXT-X-ENDLIST标签时,无论M3U8列表中有多少片分片,都从倒数第三片开始播放;不满三片不应该播放
前一片与后一片有不连续时播放可能会出错,需要使用EXT-X-DISCONTINUITY标签来解决
以播放当前分片的duration时间刷新M3U8列表,然后做对应的加载动作
如果播放列表在刷新之后与之前的列表相同,那么在播放当前分片duration一半的时间再刷新一次

  • EXTINF:M3U8列表中每一个分片的duration,还包含其他信息,主要为标注切片信息

  • EXT-X-STREAM-INF:主要出现在多级M3U8文件中,例如不同清晰度

FFmpeg转HLS参数

FFmpeg自带HLS的封装参数,使用HLS格式即可进行HLS的封装,参数表格 P96
常规的文件转HLS直播:ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8
” -bsf:v h264_mp4toannexb”将MP4中的H.264转换为H.264 AnnexB标准的编码,AnnexB标准的编码常见与实时传输流中。如果源文件为FLV、TS等可作为直播传输流的视频,则不需要这个参数

参数解析
1.start_number参数

设置M3U8列表中第一片的序列号,例如:

ffmpeg -re -i input.flv -c copy -f hls -start_number 300 output.m3u8
2.hls_time参数

设置M3U8列表中切片的duration;该切片规则是从关键帧开始切片,时间不均匀;如果先转码再切片,则会比较规律

ffmpeg -re -i input.flv -f hls -hls_time 10 output.m3u8
3.hls_list_size参数

设置M3U8列表中TS切片的个数

ffmpeg -re -i input.flv -f hls -hls_list_size 3 output.m3u8
4.hls_wrap参数

为M3U8列表中TS设置刷新回滚参数

ffmpeg -re -i input.flv -f hls -hls_wrap 3 output.m3u8
5.hls_base_url参数

为M3U8列表中的文件路径设置前置基本路径参数

ffmpeg -re -i input.flv -f hls -hls_base_url http://xxx.xxx.x.x/live/ output.m3u8
6.hls_segment_filename参数

设置切片文件名的规则

ffmpeg -re -i input.flv -f hls -hls_segment_filename test_output-%d.ts output.m3u8
7.hls_flags参数

该参数包含了一些子参数

  • 7.1 delete_segments

删除已经不在M3U8列表中的旧文件。
注意:FFmpeg删除切片时会将hls_list_size大小的2倍作为删除的依据

ffmpeg -re -i input.flv -f hls -hls_flags delete_segments -hls_list_size 4 output.m3u8

在这里插入图片描述

  • 7.2 round_duration

实现切片信息duration为整型

ffmpeg -re -i input.flv -f hls -hls_flags round_durations output.m3u8
  • 7.3 discont_start

在生成M3U8时,在切片信息的前边插入discontinuity标签

ffmpeg -re -i input.flv -f hls -hls_flags discont_start output.m3u8

在这里插入图片描述

  • 7.4 omit_endlist

在生成M3U8结束的时候,若不在文件末尾,则不追加endlist标签:因为在常规的生成M3U8的操作中,FFmpeg会默认写入endlist标签

ffmpeg -re -i input.flv -f hls -hls_flags omit_endlist output.m3u8
  • 7.5 split_by_time

生成M3U8时根据hls_time参数设定的数值作为秒数参考对TS进行切片,并不一定要遇到关键帧

ffmpeg -re -i input.flv -f hls -hls_time 2 -hls_flags split_by_time output.m3u8 
8.use_localtime

以本地系统时间为切片文件名

ffmpeg -re -i input.mp4 -c copy -f hls -use_localtime 1 -bsf:v h264_mp4toannexb output.m3u8
9.method

设置HLS将M3U8及TS文件上传至Http服务器; Http服务器要支持上传相关方法,如POST、PUT等

ffmpeg -i input.mp4 -c copy -f hls -hls_time 3 -hls_list_size 0 -method POST -t 6 http://www.baidu.com

在这里插入图片描述

上述命令中两个FFmpeg参数的含义

-bsf
比特流过滤器设置
首先使用ffmpeg -bsfs来查看所有的比特流过滤器,使用下面的命令
ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
来匹配要复制的视频流,也是就是说,是有条件复制视频流,必须匹配上才复制

-c
-codec的缩写
ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
意思是encodes all video streams with libx264 and copies all audio streams.


视频文件切片

视频文件切片与HLS基本类似,但HLS切片在标准中只支持TS格式的切片,且是直播与点播切片。视频切片可以使用segment方式,也可以使用ss加上t参数

FFmpeg切片segment参数 (参数表格 P105)参数中一些与HLS用法相同,下面分析一些用法不同的
在这里插入图片描述

FFmpeg使用segment方式进行切片
1.segment_format

指定切片文件的格式。HLS切片的格式主要为MPEGTS文件格式; 在segment中,可以根据segment_format来指定切片文件的格式,既可以为MPEGTS格式,也可以为MP4切片、FLV切片等

ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 test_output%d.mp4

在这里插入图片描述

2.segment_list与segment_list_type指定切片索引列表

使用segment切割文件时,不仅可以切割MP4,同样可以切割TS或FLV等文件,生成的文件索引列表名称也可以指定名称

1)生成ffconcat格式索引文件

ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type ffconcat -segment_list output.lst test_output-%d.mp4

在这里插入图片描述
在这里插入图片描述

该命令生成ffconcat格式的索引文件output.lst,内包含MP4切片的文件列表

2)生成FLAT格式索引文件

ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type flat -segment_list flielist.txt test_output-%d.mp4

在这里插入图片描述

3)生成CSV格式索引文件

ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type csv -segment_list flielist.csv test_output-%d.mp4

在这里插入图片描述
在这里插入图片描述

4)生成M3U8格式索引文件

ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type m3u8 -segment_list flielist.m3u8 test_output-%d.mp4

在这里插入图片描述

3.reset_timestamps 使切片时间戳归零
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -reset_timestamps 1 test_output-%d.mp4
4.segment_times 按照事件点剪切
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_times 3,9,12 test_output-%d.mp4

根据命令参数,切片的时间点分别为3,9,12秒,在这三个时间点进行切片

FFmpeg使用ss与t参数进行切片

使用ss可以进行视频文件的seek定位,ss所传递的参数为时间值,t所传递的参数也为时间值

1.使用ss指定剪切开头部分

例如:从视频的第10秒开始截取
ffmpeg -ss 10 -i input.mp4 -c copy output.ts

2.使用t指定视频总长度

例如:截取前10秒的数据
ffmpeg -i input.mp4 -c copy -t 10 -copyts output.mp4

3.使用output_ts_offset指定输出start_time
使用ss与t可以达到切割视频的某一段的效果,但不能指定输出文件的start_time

ffmpeg -i input.mp4 -c copy -t 10 -output_ts_offset 120 output.mp4

在这里插入图片描述
在这里插入图片描述

FFmpeg抽取音视频文件中的AAC音频流
ffmpeg -i input.mp4 -vn -acodec copy output.aac

在这里插入图片描述
(由于我的input.mp4是录屏文件,没有音轨,所以没有获取到)

FFmpeg抽取音视频文件中的H.264视频流
ffmpeg -i input.mp4 -an -vcodec copy output.h264

在这里插入图片描述

FFmpeg抽取音视频文件中的H.265视频流
ffmpeg -i input.mp4 -an -vcodec copy -bsf hevc_mp4toannexb -f hevc output.hevc
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/153376.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • AutoSAR系列讲解 – 总目录

    AutoSAR系列讲解 – 总目录博主想在开始前先讲一下我们的具体安排,这里就以目录加说明的形式展示出来,同时这也可以作为大家学习AutoSAR的参考。由于实践篇需要在很久以后才会更新,所以这里我们先罗列一下理论篇的内容,实践篇等开始更新的时候我再补充上

  • 网络规划与设计「建议收藏」

    网络规划与设计「建议收藏」一、网络生命周期网络生命周期就是网络系统从思考、调查、分析、建设到最后淘汰的总过程。常见的网络生命周期是四阶段周期模型、五阶段周期模型、六阶段周期模型。1.四阶段周期模型特点:能够快速适应新的

  • 表单编号和文件编号_php制作一个表单

    表单编号和文件编号_php制作一个表单在实际的编程中,表单的HTML代码和获取表单的PHP程序可以分别写到两个文件中,也可以写到同一个PHP文件中。初学Web交互编程时,为了简便,可以使用后者,因为这样做可以减少网站内网页文件的数量。

  • ubuntu14.04使用reaver跑pin码

    ubuntu14.04使用reaver跑pin码今天刚说过没找到支持ubuntu14.04用reaver跑pin的旧版库文件这就有摸索到方法了…另外安装系统ubuntu14.04以及一系列破解工具比如aircrack,minidwep等都不在本贴中赘述了,百度有很多,也可以直接在终端使用命令”apt-getinstall软件包”来安装,不过不要安装reaver,本贴主要讲安装reaver和库文件等上面说的你都安装完了之后,去h

  • java通过SMS短信平台实现发短信的功能

    java通过SMS短信平台实现发短信的功能

  • python实现将数据写入Excel文件中「建议收藏」

    python实现将数据写入Excel文件中「建议收藏」将数据写入Excel文件中,用python实现起来非常的简单,下面一步步地教大家。一、导入excel表格文件处理函数importxlwt注意,这里的xlwt是python的第三方模块,需要下载安装才能使用,不然导入不了(python第三方库的安装也非常简单,打开命令行,输入pipinstallxlwt就可以了)二、创建excel表格类型文件book=xlwt.Workbook(encoding=’utf-8′,style_compression=0)调用xlwt模块中的Workbo

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号