搜索
 找回密码
 立即注册

音视频基本概念和FFmpeg的简单入门(新手友好)

音视频开发进阶 2022-11-11 22:19:31 183

音视频基本概念和FFmpeg的简单入门

编辑切换为居中

添加图片注释,不超过 140 字(可选)

基本概念#

容器/文件(Conainer/File):

即特定格式的多媒体文件,一般来说一个视频文件是由视频,音频,字幕等按特定的格式/规则组合到一起的,常见如:

<pre class="public-DraftStyleDefault-pre" data-offset-key="1iupv-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="1iupv-0-0"><div data-offset-key="1iupv-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="1iupv-0-0"><span data-text="true">mp4 flv mkv avi</span></span></div></pre></pre>

媒体流(Stream):

表示时间轴上的一段连续数据,如一段声音数据、一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器。

数据帧/数据包(Frame/Packet):

通常,一个媒体流是由大量的数据帧组成的,对于压缩数据,帧对应着编解码器的最小处理单元,分属于不同媒体流的数据帧交错存储于容器之中。

一般: Frame对应压缩前的数据,Packet对应压缩后的数据。

编解码器(Codec):

视频和音频都需要经过编码,才能保存成文件。编解码器是指以帧为单位实现压缩数据和原始数据之间的相互转换的;

编码:原始数据->压缩数据;

解码:压缩数据->原始数据;

不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。

常用的视频编码格式如下:

<pre class="public-DraftStyleDefault-pre" data-offset-key="ctvbm-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="ctvbm-0-0"><div data-offset-key="ctvbm-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="ctvbm-0-0"><span data-text="true">H.262 H.264 H.265</span></span></div></pre></pre>

示例:原始图形YUV数据用H.264编码成H264帧

编辑

添加图片注释,不超过 140 字(可选)

常用的音频编码格式如下:

<pre class="public-DraftStyleDefault-pre" data-offset-key="6bj18-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="6bj18-0-0"><div data-offset-key="6bj18-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="6bj18-0-0"><span data-text="true">MP3 AAC

</span></span></div></pre></pre>

示例:原始声音PCM数据用AAC编码器编码成AAC帧(是的音频也有帧)

编辑

添加图片注释,不超过 140 字(可选)

复用(mux):

把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)

编辑

添加图片注释,不超过 140 字(可选)

解复用(demux):

把不同的流从某种容器中解析出来,这种行为叫做解复用(demux)

编辑

添加图片注释,不超过 140 字(可选)

帧率(Frame rate):

n帧率也叫帧频率,用FPS表示。帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。

一般电影的帧率为24;

码率(Bit Rate):

比特率(也叫码率,数据率)是一个确定整体视频/音频质量的参数,秒为单位处理的位数,码率和视频质量成正比,在视频文件中中比特率用bps(bit per second)来表达。

码率越低,表示压缩程度越高,画质越差。

码率越高,视频质量相对越高,视频文件也就越大。

FFmpeg

FFmpeg是一个很多的项目,包括很多组件:

  • ffmpeg——一个命令行工具,用来对视频文件转换格式,也支持对电视卡即时编码
  • ffserver——一个HTTP多媒体即时广播流服务器,支持时光平移
  • ffplay——一个简单的播放器,基于SDL与FFmpeg库
  • libavcodec——包含全部FFmpeg音频/视频编解码库
  • libavformat——包含demuxers和muxer库
  • libavutil——包含一些工具库
  • libpostproc——对于视频做前处理的库
  • libswscale——对于视频作缩放的库

我们一般说的的FFmpeg 是指FFmpeg 的命令行工具;

第一条FFmpeg命令

<pre class="public-DraftStyleDefault-pre" data-offset-key="8gl3e-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="8gl3e-0-0"><div data-offset-key="8gl3e-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="8gl3e-0-0"><span data-text="true">ffmpeg -y -i input.mp4 -acodec copy -vcodec libx264 -s 720x1280 output.avi</span></span></div></pre></pre>

参数解析

<pre class="public-DraftStyleDefault-pre" data-offset-key="bbpd4-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="bbpd4-0-0"><div data-offset-key="bbpd4-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="bbpd4-0-0"><span data-text="true">-y </span></span><span data-offset-key="bbpd4-0-1"><span data-text="true"># 全局参数,等于npm -y </span></span><span data-offset-key="bbpd4-0-2"><span data-text="true"> -i input.mp4 </span></span><span data-offset-key="bbpd4-0-3"><span data-text="true">#输入文件,FFmpeg命令有位置之分, -i 之前是输入参数,之后是输出参数</span></span><span data-offset-key="bbpd4-0-4"><span data-text="true"> -acodec copy </span></span><span data-offset-key="bbpd4-0-5"><span data-text="true">#输出文件参数,复制音频编码而不用重新编码</span></span><span data-offset-key="bbpd4-0-6"><span data-text="true"> -vcodec libx26 </span></span><span data-offset-key="bbpd4-0-7"><span data-text="true">#输出文件参数,重新用libx26编码(比较慢耗性能)</span></span><span data-offset-key="bbpd4-0-8"><span data-text="true"> -s 720x1280 </span></span><span data-offset-key="bbpd4-0-9"><span data-text="true">#输出参数,</span></span><span data-offset-key="bbpd4-0-10"><span data-text="true"> output.avi </span></span><span data-offset-key="bbpd4-0-11"><span data-text="true">#输出文件</span></span><span data-offset-key="bbpd4-0-12"><span data-text="true">

</span></span></div></pre><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="1qlv2-0-0"><div data-offset-key="1qlv2-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="1qlv2-0-0"><span data-text="true">可以看到,FFmpeg一般分为这五个部分,大家参考上面命令对号入座

全局参数 输入文件参数 输入文件 输出文件参数 输出文件 </span></span></div></pre></pre>

所以这条命令的含义是:把视频input.mp4不修改音频的情况下用libx26编码音频,同时分辨率改成720*1280,格式改成avi;

视频信息

左:input.mp4 ,右:output.avi

可以看到视频文件已经完成了命令操作转换;

编辑切换为居中

添加图片注释,不超过 140 字(可选)

FFmpeg常用参数

<pre class="public-DraftStyleDefault-pre" data-offset-key="cm89e-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="cm89e-0-0"><div data-offset-key="cm89e-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="cm89e-0-0"><span data-text="true">-c:指定编码器

-c copy:直接复制,不经过重新编码

-c:v:指定视频编码器

-c:a:指定音频编码器

-i:指定输入文件

-an:去除音频流

-vn: 去除视频流,不处理视频

-preset:指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。

-y:不经过确认,输出时直接覆盖同名文件。

-s: size 设置帧大小 格式为WXH 缺省160X128.下面的简写也可以直接使用:Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576

-b: bitrate 设置比特率,缺省200kb/s

-vcodec: codec 强制使用codec编解码方式。 如果用copy表示原始编解码数据直接被拷贝。

-filter: 视频过滤器,如 -filter:v "crop=w:h:x:y"用过滤器v裁剪视频 w - 源视频中裁剪的矩形的宽度 h – 矩形的高度。 x – 我们想自源视频中裁剪的矩形的 x 坐标 。 y – 矩形的 y 坐标。

-aspect:设置横纵比 4:3 16:9 或 1.3333 1.7777

-ss:position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持,比如用来指定剪切开始时间</span></span></div></pre></pre>

FFmpeg命令处理流程

我们还是以这条命令为例,分析FFmpeg命令对视频的处理经过哪些流程

<pre class="public-DraftStyleDefault-pre" data-offset-key="9q2k0-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="9q2k0-0-0"><div data-offset-key="9q2k0-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="9q2k0-0-0"><span data-text="true">ffmpeg -y -i input.mp4 -acodec copy -vcodec libx264 -s 720x1280 output.avi

</span></span></div></pre></pre>

我们看图:我们看到命令处理一般分成5个步骤

  1. 解复用:把容器文件解析成编码的数据包;
  2. 解码:解码器把数据包解码成数据帧;
  3. filter进行帧处理:把1080 1920的数据帧处理成720 1280
  4. 重新编码:编码器libx264重新把数据帧编码成编码的数据包;
  5. 复用:把数据包按格式avi封装;

这个简单流程比较重要,要了然于心;

FFmpeg常用命令

打印视频基本信息

编辑切换为居中

添加图片注释,不超过 140 字(可选)

<pre class="public-DraftStyleDefault-pre" data-offset-key="cfkdg-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="cfkdg-0-0"><div data-offset-key="cfkdg-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="cfkdg-0-0"><span data-text="true">$ ffmpeg -i input.mp4 -hide_banner

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41isomavc1 creation_time : 2021-05-29T16:51:47.000000Z Duration: 00:00:30.61, start: 0.000000, bitrate: 5932 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1080x1920, 5672 kb/s, 60 fps, 60 tbr, 60 tbn (default) Metadata: creation_time : 2021-05-29T16:51:47.000000Z handler_name : L-SMASH Video Handler vendor_id : [0][0][0][0] encoder : AVC Coding Stream #0:10x2: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 253 kb/s (default) Metadata: creation_time : 2021-05-29T16:51:47.000000Z handler_name : L-SMASH Audio Handler vendor_id : [0][0][0][0] At least one output file must be specified</span></span></div></pre></pre>

转换格式修改分辨率

<pre class="public-DraftStyleDefault-pre" data-offset-key="d45h1-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="d45h1-0-0"><div data-offset-key="d45h1-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="d45h1-0-0"><span data-text="true">ffmpeg -y -i input.mp4 -s 720x1280 output.avi

</span></span></div></pre></pre>

视频静音处理(移除音频)

<pre class="public-DraftStyleDefault-pre" data-offset-key="2a51a-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="2a51a-0-0"><div data-offset-key="2a51a-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="2a51a-0-0"><span data-text="true">ffmpeg -i input.mp4 -an quiet.mp4

</span></span></div></pre></pre>

从视频中提取图片

<pre class="public-DraftStyleDefault-pre" data-offset-key="1s0f7-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="1s0f7-0-0"><div data-offset-key="1s0f7-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="1s0f7-0-0"><span data-text="true">ffmpeg -i input.mp4 -r 1 -f image2 -ss 00:00:10 -t 2 image-%2d.png

</span></span></div></pre></pre>

  • -r – 设置帧速度。即,每秒提取帧到图像的数字。默认值是 25。
  • -f – 表示输出格式,即,在我们的实例中是图像。
  • image-%2d.png – 表明我们如何想命名提取的图像。在这个实例中,命名应该像这样image-01.png、image-02.png、image-03.png 等等开始。如果你使用 %3d,那么图像的命名像 image-001.png、image-002.png 等等开始。

添加/修改封面

<pre class="public-DraftStyleDefault-pre" data-offset-key="9k1p6-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="9k1p6-0-0"><div data-offset-key="9k1p6-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="9k1p6-0-0"><span data-text="true">ffmpeg -y -i input.mp4 -i cover.png -map 0 -map 1 -c copy -disposition:v:1 attached_pic cover_output.mp4

</span></span></div></pre></pre>

如果需要把视频第一帧截出来坐封面,那就先提取

<pre class="public-DraftStyleDefault-pre" data-offset-key="4joj1-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="4joj1-0-0"><div data-offset-key="4joj1-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="4joj1-0-0"><span data-text="true">ffmpeg -ss 00:00:01 -i input.mp4 -f image2 cover.png

</span></span></div></pre></pre>

提取视频里的音频文件

<pre class="public-DraftStyleDefault-pre" data-offset-key="9dh7k-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="9dh7k-0-0"><div data-offset-key="9dh7k-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="9dh7k-0-0"><span data-text="true">ffmpeg -i input.mp4 -vn -c:a copy output.aac

</span></span></div></pre></pre>

裁剪视频

<pre class="public-DraftStyleDefault-pre" data-offset-key="7crtt-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="7crtt-0-0"><div data-offset-key="7crtt-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="7crtt-0-0"><span data-text="true">ffmpeg -i input.mp4 -filter:v "crop=640:480:120:240" cut.mp4

</span></span></div></pre></pre>

  • -filter:v – 表示视频过滤器。
  • crop – 表示裁剪过滤器。
  • w – 我们想自源视频中裁剪的矩形的宽度。
  • h – 矩形的高度。
  • x – 我们想自源视频中裁剪的矩形的 x 坐标 。
  • y – 矩形的 y 坐标。

视频截取

<pre class="public-DraftStyleDefault-pre" data-offset-key="253v-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="253v-0-0"><div data-offset-key="253v-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="253v-0-0"><span data-text="true">ffmpeg -i input.mp4 -ss 00:00:05 -codec copy -t 10 cutout.mp4</span></span></div></pre></pre>

  • -ss 开始时间
  • -t 10,截取十秒

视频切割拆分成多个

<pre class="public-DraftStyleDefault-pre" data-offset-key="l1qb-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="l1qb-0-0"><div data-offset-key="l1qb-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="l1qb-0-0"><span data-text="true">ffmpeg -i input.mp4 -t 00:00:13 -c copy part1.mp4 -ss 00:00:13 -codec copy part2.mp4

</span></span></div></pre></pre>

  • -t 00:00:13 表示从视频的开始到视频的第 30 秒创建一部分视频。
  • -ss 00:00:13 为视频的下一部分显示开始时间戳。它意味着第 2 部分将从第 30 秒开始,并将持续到原始视频文件的结尾。

视频合并拼接

<pre class="public-DraftStyleDefault-pre" data-offset-key="1gmp2-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="1gmp2-0-0"><div data-offset-key="1gmp2-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="1gmp2-0-0"><span data-text="true">ffmpeg -i "concat:part1.mp4|part2.mp4" -c:a copy -c:v copy combine.mp4

</span></span></div></pre></pre>

设置视屏屏蔽宽高

<pre class="public-DraftStyleDefault-pre" data-offset-key="5fd3e-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="5fd3e-0-0"><div data-offset-key="5fd3e-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="5fd3e-0-0"><span data-text="true">ffmpeg -i input.mp4 -aspect 4:3 4_3.mp4

</span></span></div></pre></pre>

通常使用的高宽比是:

  • 16:9
  • 4:3
  • 16:10
  • 5:4
  • 2:21:1
  • 2:35:1
  • 2:39:1

添加字幕

<pre class="public-DraftStyleDefault-pre" data-offset-key="6mjj7-0-0"><pre class="Editable-styled" data-block="true" data-editor="aat1o" data-offset-key="6mjj7-0-0"><div data-offset-key="6mjj7-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"><span data-offset-key="6mjj7-0-0"><span data-text="true">ffmpeg -i input.mp4 -i subtitle.srt -c copy output.mkv

</span></span></div></pre></pre>

是字幕文件,然后这里选用的是软字幕方式比较快

总结

简单记录音视频的非常基本的概念和FFmpeg的基本使用

https://www.cnblogs.com/xiaxiaolu/p/16176848.html

使用道具 举报

随机推荐

0 回复

游客
返回顶部