在这个自媒体盛行的时代,音视频(电影、音乐)对于我们来说是再熟悉不过了吧。那么对于一个音视频文件,都有哪些属性呢?以视频为例,我们可以通过如下命令查看其信息。
> ffmpeg -i .\demo.mp4
ffmpeg version 5.0.1-essentials_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 11.2.0 (Rev7, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
libavutil 57. 17.100 / 57. 17.100
libavcodec 59. 18.100 / 59. 18.100
libavformat 59. 16.100 / 59. 16.100
libavdevice 59. 4.100 / 59. 4.100
libavfilter 8. 24.100 / 8. 24.100
libswscale 6. 4.100 / 6. 4.100
libswresample 4. 3.100 / 4. 3.100
libpostproc 56. 3.100 / 56. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\demo.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:17.62, start: 0.000000, bitrate: 4898 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 4895 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
其中,
-
Input #0:表示通过ffmpeg -i参数输入的第一个文件,下标从0开始,当然也可以输入多个文件。
-
Metadata:表示视频元信息。
-
Duration:视频播放时长为17.62s,开始播放时间为0,整个文件的比特率为4898kb/s。
-
Stream #0:0(und): Video:h264,表示该文件的第一个流是视频流,编码格式为H.264(封装格式为AVC1),每一帧的数据表示为YUV420P,分辨率为1920*1080,视频流的比特率为1732kbit/s,帧率为29.83fps。
那么,什么是FFmpeg?
FFmpeg简介
FFmpeg(Fast Forward Moving Picture Experts Group,Fast Forward(快速前进),MPEG即为大名鼎鼎的ISO动态图像专家组),是一款免费、开源、支持跨平台的音视频编解码工具及开发套件,可以用于音频和视频的转码、转封装、录制、流化处理等场景,号称是音视频界的瑞士军刀。
FFmpeg组件
FFmpeg组件由命令行应用程序和函数库两部分组成。
命令行应用程序
-
ffmpeg:用于对视频文档或音频档案转换格式。
-
ffplay:一个简单的播放器,基于SDL与FFmpeg库。
-
ffprobe:用于显示媒体文件的信息。
函数库
-
libavutil:一个包含简化编程功能的库,包括随机数生成器、数学例程、核心多媒体使用程序等。
-
libavcodec:一个包含解码和编码器的音/视频编解码器的库。
-
libavformat:一个包含用于多媒体容器格式的解封装和封装的库。
-
libavdevice:一个包含输入和输出设备的库,用于抓取和呈现许多常见的多媒体输入/输出软件框架,包括Video4Linux、Video4Linux2、VFW和ALSA。
-
libavfilter:一个包含媒体过滤器的库。
-
libswscale:一个用于图像尺寸缩放和像素格式转换的库。
-
libswresample:一个用于音频重采样、格式转换、音频混合的库。
-
libpostproc:一个用于后期效果处理的库。
FFmepg基本概念
容器Container
一种文件封装格式,比如flv、mkv、mp4等,其中包含下面5种流以及文件头信息。
媒体流Stream
一种视频数据信息的传输方式,包括5种流:音频、视频、字幕、附件和数据。
帧Frame
一幅静止的图像,包括I帧、B帧、P帧。
GOP(Group Of Picture)
图像组,两个I帧之间的距离。Reference(参考周期)指两个P帧之间的距离。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧。
编解码器Codec
对视频进行压缩或者解压缩,CODEC = Encode(编码)+ Decode(解码)。
帧内压缩
压缩GOP图像组中的I帧。记录关键帧,剩余的依靠运动轨迹来预测生成视频。
帧间压缩
压缩GOP图像组中的B帧与P帧。基于连续视频的相邻帧之间具有冗余信息的特点对时间轴上不同帧之间的数据实施压缩,进一步提高压缩比。
软/硬编解码
软编解码
使用CPU对视频进行编解码的方式。
-
优点:兼容性好。
-
缺点:CPU占用率高,使得其它进程无法使用更多的CPU资源,导致电脑整体性能下降,产生降频、卡顿,无法流畅录制、播放视频等问题。
硬编解码
使用非CPU进行编码,如显卡GPU、专用的DSP芯片、厂商芯片等。一般编解码算法固定所以采用芯片处理。
-
优点:编码速度非常快且效率极高,CPU的占用率低,就算长时间高清录制视频手机也不会发烫。
-
缺点:兼容性欠佳。
相关视频推荐
ffmpeg实战教程:ffmpeg命令,ffmpeg过滤器,ffplay播放器,ffmpeg进阶学习https://www.bilibili.com/video/BV1zC4y127uj/
【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发免费学习地址
【纯干货免费分享】C++音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击671977938加群免费领取哦~
复用/封装Mux
把不同的媒体流按照某种容器的规则存放在容器中。
封装/解封装Demux
把不同的媒体流从某种容器中解析出来。
帧率Fps
视频文件中每秒的帧数,肉眼想看到连续移动图像至少需要15帧。
码率/比特率Bitrate
视频每一秒包含的数据量、信息量。码率直接决定了视频的最终大小及视频的质量。
控制码率的方法:
-
CBR(Constant BitRate):固定码率模式,则文件大小可预算,编码压力小,通常用于直播场景;简单场景画质好,复杂场景画质差;属于空间利用率最低的一种方法。
-
VBR(Variable BitRate):动态码率模式,码率按需分配,简单场景码率低,复杂场景码率高。
-
CRF(Constant Rate Factor):固定质量模式,CRF值越低,视频质量越高,反之亦然。以观感画质为目标码率,文件大小不可预算。
FFmpeg视频处理流程
FFmpeg命令行使用
FFmpeg语法形式:
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
usage: ffmpeg [全局参数] {[输入文件参数] -i 输入文件地址} ... {[输出文件参数] 输出文件地址} ...
其中,
-
全局参数
-i 设定输入格式
-y 设定输出格式,输出时直接覆盖同名文件
-ss 开始时间
-c:指定编码器
-c copy:直接复制,无需经过重新编码
-c:v:指定视频编码器
-c:a:指定音频编码器
-an:去除音频流
-vn:去除视频流
-
输出视频文件参数
-b 设定视频流量(码率),默认为200Kbit/s
-r 设定帧速率,默认为25
-s 设定画面的宽与高
-aspect 设定画面的比例
-vn 不处理视频
-vcodec 设定视频编解码器,未设定时则使用与输入流相同的编解码器
-qscale 0 保留原始的视频质量
-
输出音频文件参数
-ar 设定采样率
-ac 设定声音的Channel数
-acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器
-an 不处理音频
例如,将一个mp4文件转为webm文件,输入mp4文件视频编码格式为H.264,音频编码格式为aac;输出webm文件的视频编码格式为VP9,音频编码格式为Vorbis,命令如下:
ffmpeg \
-y \ # 全局参数
-c:a libfdk_aac -c:v libx264 \ # 输入文件参数
-i input.mp4 \ # 输入文件
-c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数
output.webm # 输出文件
常见使用示例
查看媒体文件信息
ffmpeg -i demo.mp4
如果想隐藏FFmpeg本身的信息,则添加-hide_banner参数。
ffmpeg -i demo.mp4 -hide_banner
视频编辑
调整码率
通常调整码率是为了将视频文件的体积变小。例如:
ffmpeg -i demo.mp4 -minrate 964K -maxrate 3856K -bufsize 2000K output.mp4
其中,-minrate指定最小码率,-maxrate指定最大码率,-bufsize设置缓冲区大小。
更改视频分辨率或长宽比
FFmpeg中采用-s参数来缩放视频,例如:
ffmpeg -i demo.mp4 -s 1024x576 output.mp4
视频拼接
用于将指定的数个视频片段拼接成一段视频。
ffmpeg -f concat -i file_concat.txt -codec copy output_concat.mp4
-
file_concat.txt
file 'demo.mp4'
file 'output.mp4'
视频转码
转换容器格式
将视频文件从一种容器转到另一种容器,即转换媒体文件格式,例如avi 、flv 、mp4等。
ffmpeg -i demo.mp4 -hide_banner video_output.avi
这里只是转一下容器格式,而不改变视频的编码方式。如想要加快转换速度,则可以再加上-c copy指定直接拷贝。
转换编码格式Transcoding
将视频文件从一种编码转成另一种编码,只需指定输出文件的视频编码器即可。例如:
-
转成H.264编码,一般使用编码器libx264。
ffmpeg -i demo.mp4 -hide_banner -c:v libx264 output.mp4
-
同理,转成H.265编码,一般使用编码器libx265。
ffmpeg -i demo.mp4 -hide_banner -c:v libx265 output.mp4