音视频基本概念和FFmpeg的简单入门
写在前面
最近正好有音视频编辑的需求,虽然之前粗略的了解过FFmpeg不过肯定是不够用的,借此重新学习下;
基本概念
容器/文件(Conainer/File):
即特定格式的多媒体文件,一般来说一个视频文件是由视频,音频,字幕等按特地的格式/规则组合到一起的,常见如:
mp4
flv
mkv
avi
媒体流(Stream):
表示时间轴上的一段连续数据,如一段声音数据、一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器。
数据帧/数据包(Frame/Packet):
通常,一个媒体流是由大量的数据帧组成的,对于压缩数据,帧对应着编解码器的最小处理单元,分属于不同媒体流的数据帧交错存储于容器之中。
一般: Frame对应压缩前的数据,Packet对应压缩后的数据。
编解码器(Codec):
视频和音频都需要经过编码,才能保存成文件。编解码器是指以帧为单位实现压缩数据和原始数据之间的相互转换的;
编码:原始数据->压缩数据;
解码:压缩数据->原始数据;
不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。
常用的视频编码格式如下:
H.262
H.264
H.265
示例:原始图形YUV数据用H.264编码成H264帧

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

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

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

帧率(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命令
ffmpeg -y -i input.mp4 -acodec copy -vcodec libx264 -s 720x1280 output.avi
参数解析
-y # 全局参数,等于npm -y
-i input.mp4 #输入文件,FFmpeg命令有位置之分, -i 之前是输入参数,之后是输出参数
-acodec copy #输出文件参数,复制音频编码而不用重新编码
-vcodec libx26 #输出文件参数,重新用libx26编码(比较慢耗性能)
-s 720x1280 #输出参数,
output.avi #输出文件
可以看到,FFmpeg一般分为这五个部分,大家参考上面命令对号入座
全局参数
输入文件参数
输入文件
输出文件参数
输出文件
所以这条命令的含义是:把视频input.mp4不修改音频的情况下用libx26编码音频,同时分辨率改成720*1280,格式改成avi;
视频信息
左:input.mp4 ,右:output.avi
可以看到视频文件已经完成了命令操作转换;

FFmpeg常用参数
-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]的格式也支持,比如用来指定剪切开始时间
FFmpeg命令处理流程
我们还是以这条命令为例,分析FFmpeg命令对视频的处理经过哪些流程
ffmpeg -y -i input.mp4 -acodec copy -vcodec libx264 -s 720x1280 output.avi
我们看图:

我们看到命令处理一般分成5个步骤
- 解复用:把容器文件解析成编码的数据包;
- 解码:解码器把数据包解码成数据帧;
- filter进行帧处理:把1080 * 1920的数据帧处理成720 * 1280
- 重新编码:编码器libx264重新把数据帧编码成编码的数据包;
- 复用:把数据包按格式avi封装;
这个简单流程比较重要,要了然于心;
FFmpeg常用命令
打印视频基本信息
$ 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:0[0x1](und): 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:1[0x2](und): 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
转换格式修改分辨率
ffmpeg -y -i input.mp4 -s 720x1280 output.avi
视频静音处理(移除音频)
ffmpeg -i input.mp4 -an quiet.mp4
从视频中提取图片
ffmpeg -i input.mp4 -r 1 -f image2 -ss 00:00:10 -t 2 image-%2d.png
-r– 设置帧速度。即,每秒提取帧到图像的数字。默认值是 25。-f– 表示输出格式,即,在我们的实例中是图像。image-%2d.png– 表明我们如何想命名提取的图像。在这个实例中,命名应该像这样image-01.png、image-02.png、image-03.png 等等开始。如果你使用%3d,那么图像的命名像 image-001.png、image-002.png 等等开始。
添加/修改封面
ffmpeg -y -i input.mp4 -i cover.png -map 0 -map 1 -c copy -disposition:v:1 attached_pic cover_output.mp4
如果需要把视频第一帧截出来坐封面,那就先提取
ffmpeg -ss 00:00:01 -i input.mp4 -f image2 cover.png
提取视频里的音频文件
ffmpeg -i input.mp4 -vn -c:a copy output.aac
裁剪视频
ffmpeg -i input.mp4 -filter:v "crop=640:480:120:240" cut.mp4
-filter:v– 表示视频过滤器。crop– 表示裁剪过滤器。w– 我们想自源视频中裁剪的矩形的宽度。h– 矩形的高度。x– 我们想自源视频中裁剪的矩形的 x 坐标 。y– 矩形的 y 坐标。
视频截取
ffmpeg -i input.mp4 -ss 00:00:05 -codec copy -t 10 cutout.mp4
-ss开始时间-t10,截取十秒
视频切割拆分成多个
ffmpeg -i input.mp4 -t 00:00:13 -c copy part1.mp4 -ss 00:00:13 -codec copy part2.mp4
-t 00:00:13表示从视频的开始到视频的第 30 秒创建一部分视频。-ss 00:00:13为视频的下一部分显示开始时间戳。它意味着第 2 部分将从第 30 秒开始,并将持续到原始视频文件的结尾。
视频合并拼接
ffmpeg -i "concat:part1.mp4|part2.mp4" -c:a copy -c:v copy combine.mp4
设置视屏屏蔽宽高
ffmpeg -i input.mp4 -aspect 4:3 4_3.mp4
通常使用的高宽比是:
- 16:9
- 4:3
- 16:10
- 5:4
- 2:21:1
- 2:35:1
- 2:39:1
添加字幕
ffmpeg -i input.mp4 -i subtitle.srt -c copy output.mkv
subtitle.srt 是字幕文件,然后这里条件的是软字幕比较快
总结
根据项目需要,简单学习了下音视频的非常基本的概念和FFmpeg的基本使用,留个记录;
[参考]
https://www.ruanyifeng.com/blog/2020/01/ffmpeg.html
https://zhuanlan.zhihu.com/p/67878761
廖庆富视频教程
音视频基本概念和FFmpeg的简单入门的更多相关文章
- ffmpeg实战-音视频基础概念
转发自白狼栈:查看原文 关于音视频,相信大家都看过电影(视频),听过音乐(音频),至少应该都知道mp4是视频文件,mp3是音频文件. 对于一个音视频文件,都有哪些属性呢?以视频为例,我们可以通过 ff ...
- Android IOS WebRTC 音视频开发总结(九)-- webrtc入门001
下面这篇介绍webrtc的文章不错,我花了大半天翻译了一下. 翻译的时候不是逐字逐句的,而是按照自己的理解翻译的,同时为了便于理解,也加入一些自己组织的语言. 本文主要介绍webrtc的信令,stun ...
- Android IOS WebRTC 音视频开发总结(十)-- webrtc入门002
继续上一篇中未翻译完成的部分,主要包括下面三个部分: 1,扩展:WebRTC多方通话. 2,MCU Multipoint Control Unit. 2, 扩展:VOIP,电话,消息通讯. 注意:翻译 ...
- Android 音视频深入 二十一 FFmpeg视频剪切
视频剪切我意外的发现上一次的视频压缩的代码能够运行FFmpeg视频剪切的命令,但是不能做视频合并的命令,因为不能读取记录了几个视频的路径的txt文件. 这里我就说直说视频剪切的过程,不说代码,只说lo ...
- Android 音视频深入 十五 FFmpeg 推流mp4文件(附源码下载)
源码地址https://github.com/979451341/Rtmp 1.配置RTMP服务器 这个我不多说贴两个博客分别是在mac和windows环境上的,大家跟着弄 MAC搭建RTMP服务器h ...
- Android 音视频深入 六 使用FFmpeg播放视频(附源码下载)
本篇项目地址,求starhttps://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpeg%E6%92 ...
- Android 音视频深入 二十 FFmpeg视频压缩(附源码下载)
项目源码https://github.com/979451341/FFmpegCompress 这个视频压缩是通过类似在mac终端上输入FFmpeg命令来完成,意思是我们需要在Android上达到能够 ...
- Android 音视频深入 十六 FFmpeg 推流手机摄像头,实现直播 (附源码下载)
源码地址https://github.com/979451341/RtmpCamera/tree/master 配置RMTP服务器,虽然之前说了,这里就直接粘贴过来吧 1.配置RTMP服务器 这个我不 ...
- Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)
项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...
随机推荐
- 西门子S210驱动器接线
参考:SINAMICS S210 操作说明 1.系统概述 P28 节2.2 单相版驱动器的系统组件和附件 2.电源接线 P56 节3.2 单相 230 V 版驱动器的连接示例 单相版驱动器在 IT 电 ...
- CF375E Red and Black Tree(线性规划)
CF375E Red and Black Tree(线性规划) Luogu 题解时间 很明显有一个略显复杂的 $ n^3 $ dp,但不在今天讨论范围内. 考虑一些更简单的方法. 设有 $ m $ 个 ...
- ::before和:after中的的双冒号和单冒号有什么区别及这两个伪元素的作用
::before和:after中的的双冒号和单冒号有什么区别及这两个伪元素的作用 单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素(伪元素由双冒号和伪元素名称组成),为了兼容已有的伪元素 ...
- 🍛 餐厅吃饭版理解 IO 模型:阻塞 / 非阻塞 / IO 复用 / 信号驱动 / 异步
IO 概念 一个基本的 IO,它会涉及到两个系统对象,一个是调用这个 IO 的进程对象,另一个就是系统内核 (kernel).当一个 read 操作发生时,它会经历两个阶段: 通过 read 系统调用 ...
- 什么是tar 命令?
用来压缩和解压文件.tar 本身不具有压缩功能,只具有打包功能,有关压缩及解压是调用其它的功能来完成.弄清两个概念:打包和压缩.打包是指将一大堆文件或目录变成一个总的文件:压缩则是将一个大的文件通过一 ...
- 如何实现数组与List的相互转换?在 Queue 中 poll()和 remove()有什么区别?哪些集合类是线程安全的?
如何实现数组与List的相互转换? List转数组:toArray(arraylist.size()方法 数组转List:Arrays的asList(a)方法 /** * 〈一句话功能简述〉; * 〈 ...
- linux发布常用命令
一.linux发布常用命令 //启动Tomcat sh /opt/apache-tomcat-8.5.29/bin/startup.sh //停止tomcat sh /opt/apache-tomca ...
- spring-boot 注解解析
package com.hllq.quan.controller; import com.hllq.quan.mapper.WeiboUserMapper; import com.hllq.quan. ...
- Spring Bean生命周期回调
参阅官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory ...
- WordPress 网站开发“微信小程序“实战(二)
原文链接:https://devework.com/wordpres...,转载请用明链注明来源,谢谢! 本文是"WordPress 开发微信小程序"系列的第二篇,本文记录的是开发 ...