12.时间操作

多媒体处理包括改变输入持续时间,设置延迟,仅从输入中选择特定部分等。这些时间操作接受2种格式的时间规格:

  • [-]HH:MM:SS[.m…]
  • [-]S+[.m…]

    HH是小时数,MM是分钟数,SSS是秒数,m是毫秒数。

音频和视频的持续时间

使用- t选项设置

要设置媒体文件的持续时间,我们可以使用-t选项,其值是以秒为单位的时间或格式为HH:MM:SS.milliseconds的时间。 例如,要为music.mp3文件设置3分钟的持续时间,我们可以使用该命令

  1. ffmpeg -i music.mp3 -t 180 music_3_minutes.mp3
  • 上面这个命令我就不测试了,应该没啥问题

通过帧数设置

在某些情况下,通过指定具有可用选项的帧数来设置录制的持续时间可能很有用:

  • 音频: -aframes number 或者 -frames:a number
  • 数据: -dframes number 或者 -frames:d number
  • 视频: -vframes number 或者 -frames:v number

帧数等于以秒为单位的持续时间乘以帧速率。 例如,要将25帧/秒的video.avi文件的持续时间设置为10分钟(600秒),我们可以使用以下命令:

  1. ffmpeg -i video.avi -vframes 15000 video_10_minutes.avi

我的测试命令:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vframes 1500 /Users/zhangfangtao/Desktop/newtest.mp4

从开始设置延迟

要从指定时间开始记录输入,我们可以使用-ss(从开始搜索)选项,其值是以秒或HH:MM:SS.milliseconds格式表示的时间。 该选项既可以在输入文件和输出文件之前使用,也可以在输出文件之前使用,编码更精确。 例如,要从第10秒开始转换,我们可以使用以下命令:

  1. ffmpeg -i input.avi -ss 10 output.mp4

我的测试命令:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -ss 10 /Users/zhangfangtao/Desktop/test2.mp4

从媒体文件中提取特定部分。

要从音频或视频文件中剪辑特定部分,我们同时使用-ss-t选项,ffplay在左下角显示当前时间,可以使用空格键或P键暂停/开启播放。 例如,要从文件video.mpg保存第5分钟(4x60 = 240秒),我们可以使用以下命令:

  1. ffmpeg -i video.mpg -ss 240 -t 60 clip_5th_minute.mpg
  • 太简单了,就不测试了

输入流之间的延迟

通常有两种情况,当其中一个输入流应该被延迟到输出时,我们都使用-itsoffset(输入时间戳偏移)选项来创建延迟和-map选项来选择特定的流。 请注意,像AVI,FLV,MOV,MP4等容器有不同的标题,在某些情况下,它的偏移选项不起作用,然后可以使用-ss选项将较慢的流保存到文件中,并且可以将这两个文件合并为 如下例所示,其中音频延迟1秒:

  1. ffmpeg -i input.avi -ss 1 audio.mp3
  2. ffmpeg -i input.avi -i audio.mp3 -map 0:v -map 1:a video.mp4

*很麻烦的样子

第一个测试的命令行:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -ss 20 /Users/zhangfangtao/Desktop/test2.mp3
  • 结果是生成了这个视频里面的所有的音频数据,文件名是test2.mp3,并且这个mp3文进里面的音频信息是从视频信息里面的地20秒开始的。

第二个测试命令:

  1. fmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -map 0:v -map 1:a /Users/zhangfangtao/Desktop/test2.mp4
  • 结果是生成了一个新的视频,这个视频的音频是我传入的那个mp3的声音,画面还是视频的画面,因为视频只有四十秒,音频三分钟,所以新的视频三分钟,不过进度条只能拖动到四十秒的位置。剩下的时间音乐继续播放,只是视频画面不动了。

一个输入文件

输入文件包含不同步的音频和视频流,例如,如果音频提前1.5秒,我们可以通过命令延迟音频流:(这个命令我试了,报错。。。。。-itsoffset语法问题)

  1. ffmpeg -i input.mov -map 0:v -map 0:a -itsoffset 1.5 -c:a copy -c:v copy output.mov

我的测试命令:

  1. ffmpeg -itsoffset 5 -i /Users/zhangfangtao/Desktop/test.mp4 /Users/zhangfangtao/Desktop/test2.mp4

*我把那些杂七杂八的参数都删除了,也不知道干啥用的,反正加上就会报错,这行命令执行之后的效果是在视频的开头,会有5秒钟的空白声音,5秒钟之后才开始正常的声音播放

如果视频是提前的,例如5秒,我们可以用命令延迟它:(这种命令在我的电脑上也是编译不过的)

  1. ffmpeg -i input.mov -map 0:v -itsoffset 5 -map 0:a -c:a copy -c:v copy ^ output.mov

我自己的测试命令如下:

  1. ffmpeg -itsoffset -5 -i /Users/zhangfangtao/Desktop/test.mp4 /Users/zhangfangtao/Desktop/test3.mp4
  • 这样岂不是更简单?????

两个或多个输入文件。

输出是由两个文件创建的,通常音频应该比视频流晚些开始,然后我们改变映射参数,例如延迟音频3秒,我们可以使用命令:

  1. ffmpeg -i v.mpg -itsoffset 3 -i a.mp3 -map 0:v:0 -map 1:a:0 output.mp4

我的测试命令如下:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -itsoffset 5 -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -t 35 -map 0:v:0 -map 1:a:0 /Users/zhangfangtao/Desktop/test2.mp4
  • 上述代码的执行效果是:从第五秒钟之后开始有音乐,因为音乐时间比较长,我截取了前35秒钟。

限制处理时间

有时候,限制ffmpeg命令运行和-timelimit选项可以在几秒钟内设置这个限制是有用的。例如,在10分钟(600秒)之后停止编码,我们可以使用下一个命令:

  1. ffmpeg -i input.mpg -timelimit 600 output.mkv

我的测试指令:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -timelimit 10 /Users/zhangfangtao/Desktop/test2.mp4

*这个时间也不是很严谨的,我设置的时长是10秒钟,结果生成的是20多秒。

最短的流决定编码时间

要将整体输出持续时间设置为最短输入流值,可以使用-shortest选项在最短流处理准备就绪时完成编码。 例如,要加入(复用)video.avi文件和audio.mp3文件,其中音频文件持续时间少于视频,我们可以使用下一个命令(没有-shortest选项,剩下的音频流将被静音替代):

  1. ffmpeg -i video.avi -i audio.mp3 -shortest output.mp4

我的测试命令:

  1. ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -shortest /Users/zhangfangtao/Desktop/test2.mp4
  • 这样会按照音视频中最短的那个来生成。

时间戳和时间基

要在媒体容器中设置记录时间戳,我们可以使用-timestamp选项,该选项的值是一个以表单输入的时间:

  • 现在(当前时间)
  • 日期被指定为YYYY-MM-DDYYYYMMDD,如果未指定,则使用当前日期。
  • 时间被指定为HH:MM:SS[.m…]HHMMSS[m…],秒的小数部分是可选的。
  • 在时间值可以是可选的字母T或T之前。
  • 如果附加Zz,则时间为UTC,否则为本地

时间戳的例子:2010-12- 24t12 00:00, 20101224t120000z, 20101224120000。

一个视频流的FFmpeg处理的控制台输出包含了关于流时间基的信息,这些信息可以看起来像下一个例子:

  1. 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

缩写tbrtbntbc表示FFmpeg时间戳的3个不同时基:

基于FFmpeg的时间戳的时间基础
Specification 控制台输出包含每个视频流3个时基值,其中打印值是实际值的倒数,这意味着打印值为1 / tbc,1 / tbn和1 / tbr。
时间基的描述
tbc 在AVCodecContext中用于给定流的编解码器的时间基,它用于所有的AVCodecContext和相关的时间戳
tbn 来自容器的AVStream时基,它用于所有AVStream时间戳
tbr 从视频流中猜测(计算)的时基并等于帧速率值,除非输入是交错的,那么它会加倍

编码器时基设置

为了为流复制指定编码器的时间基,我们可以使用-copytb选项,该选项的值模式有3个可能的整数值:

  • 1 - 使用分路器时基

时基从相应的输入分路器复制到输出编码器,有时需要复制具有可变帧频(VBR)的视频流以避免非单调增加时间戳。

  • 0 -解码器使用时基

时间戳从对应的输入解码器复制到输出编码器。

  • -1 -自动选择最佳输出,默认值

例如,要为输出选择一个demuxer时间基数,我们可以使用以下命令:

  1. ffmpeg -i input.mp4 -copytb 1 output.webm

音频和视频速度修改

视频速度变化

为了改变视频文件的速度,我们可以使用表中描述的setpts(设置表示时间戳)过滤器:

12.时间操作 - 图1

描述 更改输入帧的表示时间戳(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,命令为:

  1. ffplay -i input.mpg -vf setpts=PTS/3

我的测试命令:

  1. ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setpts=PTS/5
  • 显示的结果:音频正常播放,视频的播放速度是原来的五倍

为了以3/4的速度观看视频,输入时间戳除以3/4,我们可以使用命令:(我测试了一下,这个括号属于语法错误)

  1. ffplay -i input.mpg -vf setpts=PTS/(3/4)

我的测试命令如下:

  1. ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setpts=PTS/3*4

音频变速

为了调整音频的速度,我们可以使用表中描述的特殊atempo过滤器。

12.时间操作 - 图2

描述 改变音频速度-音频流的速度
语法 atempo[=tempo]
参数的描述
tempo 从0.5 - 2.0范围的浮点数,小于1.0的值降低,超过1.0的值加快速度,默认值为1.0

例如,要以2倍的速度听到输入音频,我们可以使用以下命令:

  1. ffplay -i speech.mp3 -af atempo=2

我的测试命令如下:

  1. ffplay -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -af atempo=2
  • 如果输入的结果不在0.5~2这个范围,也能打开ffplay,不过没有声音,终端也会报错的:

12.时间操作 - 图3

四倍速度播放就这样,没有声音

我们可以使用atempo=0.5设置,如果速度变化不够,则可以使用更多的时间。

同步音频数据与时间戳

为了使音频数据与时间戳同步,我们可以使用表中描述的asyncts音频过滤器:

12.时间操作 - 图4

描述 将音频数据与时间戳同步,通过压缩和删除样本或在需要时进行拉伸和添加静默
语法 asyncts=parameters
描述可用的参数
compensate 启用拉伸/压缩数据以使其与时间戳相匹配。默认情况下禁用。当残疾的时候,时间间隔是沉默的
min_delta 时间戳和音频数据之间的最小差异(以秒为单位)触发添加/删除示例。默认值是0.1。如果您与此过滤器不完全同步,请尝试将此参数设置为0
max_comp max。样品每秒钟的补偿,仅当补偿=1时,默认值为500
first_cts 假设第一个pts应该是这个值。这允许在流的开始处填充/修剪。默认情况下,没有对第一个帧的预期值做任何假设,所以没有填充或修剪。例如,如果音频流在视频流之后启动,则可以将其设置为0以填充开始时的静默

例如,与时间戳同步文件音乐中的数据。mpg我们可以使用以下命令:(在我电脑上-asyncts命令会报错)

  1. ffmpeg -i music.mpg -af asyncts=compensate=1 -f mpegts music.ts

我这边会报错:(我已经在github上面提问了,还没有人回复我)

12.时间操作 - 图5