这个系列文章我们来介绍一位海外工程师如何探索 FFmpeg Basics 音视频技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,这是第 12 篇:FFmpeg 时间操作。
—— 来自公众号“关键帧Keyframe”的分享
多媒体处理包括改变输入持续时间,设置延迟,仅从输入中选择特定部分等。这些时间操作接受2种格式的时间规格:
[-]HH:MM:SS[.m...][-]S+[.m...]
HH是小时数, MM是分钟数, SS或 S是秒数, m是毫秒数。
1、音频和视频的持续时间
要设置媒体文件的持续时间,我们可以使用 -t选项,其值是以秒为单位的时间或格式为 HH:MM:SS.milliseconds的时间。 例如,要为music.mp3文件设置3分钟的持续时间,我们可以使用该命令
ffmpeg -i music.mp3 -t 180 music_3_minutes.mp3
2、通过帧数设置
在某些情况下,通过指定具有可用选项的帧数来设置录制的持续时间可能很有用:
- 音频:
-aframes number或者-frames:a number - 数据:
-dframes number或者-frames:d number - 视频:
-vframes number或者-frames:v number
帧数等于以秒为单位的持续时间乘以帧速率。 例如,要将25帧/秒的video.avi文件的持续时间设置为10分钟(600秒),我们可以使用以下命令:
ffmpeg -i video.avi -vframes 15000 video_10_minutes.avi
3、从开始设置延迟
要从指定时间开始记录输入,我们可以使用 -ss(从开始搜索)选项,其值是以秒或 HH:MM:SS.milliseconds格式表示的时间。 该选项既可以在输入文件和输出文件之前使用,也可以在输出文件之前使用,编码更精确。 例如,要从第10秒开始转换,我们可以使用以下命令:
ffmpeg -i input.avi -ss 10 output.mp4
4、从媒体文件中提取特定部分
要从音频或视频文件中剪辑特定部分,我们同时使用 -ss和 -t选项,ffplay在左下角显示当前时间,可以使用空格键或P键暂停/开启播放。 例如,要从文件video.mpg保存第5分钟(4×60 = 240秒),我们可以使用以下命令:
ffmpeg -i video.mpg -ss 240 -t 60 clip_5th_minute.mpg
5、输入流之间的延迟
通常有两种情况,当其中一个输入流应该被延迟到输出时,我们都使用 -itsoffset(输入时间戳偏移)选项来创建延迟和 -map选项来选择特定的流。 请注意,像AVI,FLV,MOV,MP4等容器有不同的标题,在某些情况下,它的偏移选项不起作用,然后可以使用 -ss选项将较慢的流保存到文件中,并且可以将这两个文件合并为 如下例所示,其中音频延迟1秒:
ffmpeg -i input.avi -ss 1 audio.mp3
ffmpeg -i input.avi -i audio.mp3 -map 0:v -map 1:a video.mp4
6、一个输入文件
输入文件包含不同步的音频和视频流,例如,如果音频提前1.5秒,我们可以通过命令延迟音频流:(这个命令我试了,报错。。。。。-itsoffset语法问题)
ffmpeg -i input.mov -map 0:v -map 0:a -itsoffset 1.5 -c:a copy -c:v copy output.mov
如果视频是提前的,例如5秒,我们可以用命令延迟它:(这种命令在我的电脑上也是编译不过的)
ffmpeg -i input.mov -map 0:v -itsoffset 5 -map 0:a -c:a copy -c:v copy ^ output.mov
7、两个或多个输入文件
输出是由两个文件创建的,通常音频应该比视频流晚些开始,然后我们改变映射参数,例如延迟音频3秒,我们可以使用命令:
ffmpeg -i v.mpg -itsoffset 3 -i a.mp3 -map 0:v:0 -map 1:a:0 output.mp4
8、限制处理时间
有时候,限制ffmpeg命令运行和-timelimit选项可以在几秒钟内设置这个限制是有用的。例如,在10分钟(600秒)之后停止编码,我们可以使用下一个命令:
ffmpeg -i input.mpg -timelimit 600 output.mkv
9、最短的流决定编码时间
要将整体输出持续时间设置为最短输入流值,可以使用 -shortest选项在最短流处理准备就绪时完成编码。 例如,要加入(复用)video.avi文件和audio.mp3文件,其中音频文件持续时间少于视频,我们可以使用下一个命令(没有 -shortest选项,剩下的音频流将被静音替代):
ffmpeg -i video.avi -i audio.mp3 -shortest output.mp4
10、时间戳和时间基
要在媒体容器中设置记录时间戳,我们可以使用 -timestamp选项,该选项的值是一个以表单输入的时间:
- 现在(当前时间)
- 日期被指定为
YYYY-MM-DD或YYYYMMDD,如果未指定,则使用当前日期。 - 时间被指定为
HH:MM:SS[.m…]或HHMMSS[m…],秒的小数部分是可选的。 - 在时间值可以是可选的字母T或T之前。
- 如果附加
Z或z,则时间为UTC,否则为本地
时间戳的例子:2010-12- 24t12 00:00, 20101224t120000z, 20101224120000。
一个视频流的FFmpeg处理的控制台输出包含了关于流时间基的信息,这些信息可以看起来像下一个例子:
Stream #0:0, 1, 1/25: Video: mpeg4 (Simple Profile) (FMP4 yuv420p, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
缩写 tbr, tbn和 tbc表示FFmpeg时间戳的3个不同时基:
| 基于FFmpeg的时间戳的时间基础 | |
|---|---|
| Specification | 控制台输出包含每个视频流3个时基值,其中打印值是实际值的倒数,这意味着打印值为1 / tbc,1 / tbn和1 / tbr。 |
| 时间基的描述 | |
| tbc | 在AVCodecContext中用于给定流的编解码器的时间基,它用于所有的AVCodecContext和相关的时间戳 |
| tbn | 来自容器的AVStream时基,它用于所有AVStream时间戳 |
| tbr | 从视频流中猜测(计算)的时基并等于帧速率值,除非输入是交错的,那么它会加倍 |
11、编码器时基设置
为了为流复制指定编码器的时间基,我们可以使用 -copytb选项,该选项的值模式有3个可能的整数值:
- 1 – 使用分路器时基
时基从相应的输入分路器复制到输出编码器,有时需要复制具有可变帧频(VBR)的视频流以避免非单调增加时间戳。
- 0 -解码器使用时基
时间戳从对应的输入解码器复制到输出编码器。
- -1 -自动选择最佳输出,默认值
例如,要为输出选择一个demuxer时间基数,我们可以使用以下命令:
ffmpeg -i input.mp4 -copytb 1 output.webm
12、音频和视频速度修改
为了改变视频文件的速度,我们可以使用表中描述的 setpts(设置表示时间戳)过滤器:
| 描述 | 更改输入帧的表示时间戳(PTS) |
|---|---|
| 语法 | setpts=expression |
| 可用变量的表达式 | |
| FRAME_RATE | 帧速率,只定义为一个有固定帧的视频 |
| INTERLACED | 判断当前帧是否交错 |
| N | 输入框的计数,从0开始 |
| NB_CONSUMED_SAMPLES | 消耗的样本数量,没有当前帧(只有音频) |
| NB_SAMPLES | 当前帧中样本数量(仅为音频) |
| POS | 文件中的初始帧位置,或者如果未定义当前帧,则未定义 |
| PREV_INT | 之前的输入时间以秒为单位 |
| PREV_INPTS | 之前输入的PTS |
| PREV_OUTPTS | 之前输出的PTS |
| PREV_OUTT | 之前的输出时间以秒为单位 |
| PTS | 展示正在输入的时间戳 |
| SAMPLE_RATE | 音频采样率 |
| STARTPTS | 第一帧的PTS |
| STARTT | 第一个帧的秒数 |
| T | 在当前帧数秒内的时间 |
| TB | 时间基 |
每个视频帧都包含一个带有时间戳值的标头,顺序中2帧之间的差值为1 / fps,例如,如果fps为25,则差值为0.04秒。 为了加速视频,这个时间差必须更小,速度更低一定要更大。 例如,要快3倍观看视频,输入时间戳除以3,命令为:
ffplay -i input.mpg -vf setpts=PTS/3
为了以3/4的速度观看视频,输入时间戳除以3/4,我们可以使用命令:(我测试了一下,这个括号属于语法错误)
ffplay -i input.mpg -vf setpts=PTS/(3/4)
13、音频变速
为了调整音频的速度,我们可以使用表中描述的特殊atempo过滤器。
| 描述 | 改变音频速度-音频流的速度 |
|---|---|
| 语法 | atempo[=tempo] |
| 参数的描述 | |
| tempo | 从0.5 – 2.0范围的浮点数,小于1.0的值降低,超过1.0的值加快速度,默认值为1.0 |
例如,要以2倍的速度听到输入音频,我们可以使用以下命令:
ffplay -i speech.mp3 -af atempo=2
我们可以使用atempo=0.5设置,如果速度变化不够,则可以使用更多的时间。
14、同步音频数据与时间戳
为了使音频数据与时间戳同步,我们可以使用表中描述的asyncts音频过滤器:
| 描述 | 将音频数据与时间戳同步,通过压缩和删除样本或在需要时进行拉伸和添加静默 |
|---|---|
| 语法 | asyncts=parameters |
| 描述可用的参数 | |
| compensate | 启用拉伸/压缩数据以使其与时间戳相匹配。默认情况下禁用。当残疾的时候,时间间隔是沉默的 |
| min_delta | 时间戳和音频数据之间的最小差异(以秒为单位)触发添加/删除示例。默认值是0.1。如果您与此过滤器不完全同步,请尝试将此参数设置为0 |
| max_comp | max。样品每秒钟的补偿,仅当补偿=1时,默认值为500 |
| first_cts | 假设第一个pts应该是这个值。这允许在流的开始处填充/修剪。默认情况下,没有对第一个帧的预期值做任何假设,所以没有填充或修剪。例如,如果音频流在视频流之后启动,则可以将其设置为0以填充开始时的静默 |
例如,要与时间戳同步文件music.mpg中的数据,我们可以使用以下命令:
ffmpeg -i music.mpg -af asyncts=compensate=1 -f mpegts music.ts
音视频方向学习、求职,欢迎加入我们的星球
丰富的音视频知识、面试题、技术方案干货分享,还可以进行面试辅导

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。