写在前面
如果您对音视频技术感兴趣,可以订阅我的专题:音视频专辑
也可以关注我的简书账户: 张芳涛,我后期会发布更多的音视频以及图像处理方面的文章。
正文
多媒体处理包括改变输入持续时间,设置延迟,仅从输入中选择特定部分等。这些时间操作接受2种格式的时间规格:
[-]HH:MM:SS[.m...]
-
[-]S+[.m...]
HH
是小时数,MM
是分钟数,SS
或S
是秒数,m
是毫秒数。
音频和视频的持续时间
使用- t选项设置
要设置媒体文件的持续时间,我们可以使用-t
选项,其值是以秒为单位的时间或格式为HH:MM:SS.milliseconds
的时间。 例如,要为music.mp3文件设置3分钟的持续时间,我们可以使用该命令
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秒),我们可以使用以下命令:
ffmpeg -i video.avi -vframes 15000 video_10_minutes.avi
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -vframes 1500 /Users/zhangfangtao/Desktop/newtest.mp4
从开始设置延迟
要从指定时间开始记录输入,我们可以使用-ss
(从开始搜索)选项,其值是以秒或HH:MM:SS.milliseconds
格式表示的时间。 该选项既可以在输入文件和输出文件之前使用,也可以在输出文件之前使用,编码更精确。 例如,要从第10秒开始转换,我们可以使用以下命令:
ffmpeg -i input.avi -ss 10 output.mp4
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -ss 10 /Users/zhangfangtao/Desktop/test2.mp4
从媒体文件中提取特定部分。
要从音频或视频文件中剪辑特定部分,我们同时使用-ss
和-t
选项,ffplay在左下角显示当前时间,可以使用空格键或P键暂停/开启播放。 例如,要从文件video.mpg保存第5分钟(4x60 = 240秒),我们可以使用以下命令:
ffmpeg -i video.mpg -ss 240 -t 60 clip_5th_minute.mpg
- 太简单了,就不测试了
输入流之间的延迟
通常有两种情况,当其中一个输入流应该被延迟到输出时,我们都使用-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
*很麻烦的样子
第一个测试的命令行:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -ss 20 /Users/zhangfangtao/Desktop/test2.mp3
- 结果是生成了这个视频里面的所有的音频数据,文件名是test2.mp3,并且这个mp3文进里面的音频信息是从视频信息里面的地20秒开始的。
第二个测试命令:
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语法问题)
ffmpeg -i input.mov -map 0:v -map 0:a -itsoffset 1.5 -c:a copy -c:v copy output.mov
我的测试命令:
ffmpeg -itsoffset 5 -i /Users/zhangfangtao/Desktop/test.mp4 /Users/zhangfangtao/Desktop/test2.mp4
*我把那些杂七杂八的参数都删除了,也不知道干啥用的,反正加上就会报错,这行命令执行之后的效果是在视频的开头,会有5秒钟的空白声音,5秒钟之后才开始正常的声音播放
如果视频是提前的,例如5秒,我们可以用命令延迟它:(这种命令在我的电脑上也是编译不过的)
ffmpeg -i input.mov -map 0:v -itsoffset 5 -map 0:a -c:a copy -c:v copy ^ output.mov
我自己的测试命令如下:
ffmpeg -itsoffset -5 -i /Users/zhangfangtao/Desktop/test.mp4 /Users/zhangfangtao/Desktop/test3.mp4
- 这样岂不是更简单?????
两个或多个输入文件。
输出是由两个文件创建的,通常音频应该比视频流晚些开始,然后我们改变映射参数,例如延迟音频3秒,我们可以使用命令:
ffmpeg -i v.mpg -itsoffset 3 -i a.mp3 -map 0:v:0 -map 1:a:0 output.mp4
我的测试命令如下:
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秒)之后停止编码,我们可以使用下一个命令:
ffmpeg -i input.mpg -timelimit 600 output.mkv
我的测试指令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -timelimit 10 /Users/zhangfangtao/Desktop/test2.mp4
*这个时间也不是很严谨的,我设置的时长是10秒钟,结果生成的是20多秒。
最短的流决定编码时间
要将整体输出持续时间设置为最短输入流值,可以使用-shortest
选项在最短流处理准备就绪时完成编码。 例如,要加入(复用)video.avi文件和audio.mp3文件,其中音频文件持续时间少于视频,我们可以使用下一个命令(没有-shortest
选项,剩下的音频流将被静音替代):
ffmpeg -i video.avi -i audio.mp3 -shortest output.mp4
我的测试命令:
ffmpeg -i /Users/zhangfangtao/Desktop/test.mp4 -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -shortest /Users/zhangfangtao/Desktop/test2.mp4
- 这样会按照音视频中最短的那个来生成。
时间戳和时间基
要在媒体容器中设置记录时间戳,我们可以使用-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 | 从视频流中猜测(计算)的时基并等于帧速率值,除非输入是交错的,那么它会加倍 |
编码器时基设置
为了为流复制指定编码器的时间基,我们可以使用-copytb
选项,该选项的值模式有3个可能的整数值:
1 - 使用分路器时基
时基从相应的输入分路器复制到输出编码器,有时需要复制具有可变帧频(VBR)的视频流以避免非单调增加时间戳。0 -解码器使用时基
时间戳从对应的输入解码器复制到输出编码器。-
-1 -自动选择最佳输出,默认值
例如,要为输出选择一个demuxer时间基数,我们可以使用以下命令:ffmpeg -i input.mp4 -copytb 1 output.webm
音频和视频速度修改
视频速度变化
为了改变视频文件的速度,我们可以使用表中描述的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
我的测试命令:
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setpts=PTS/5
- 显示的结果:音频正常播放,视频的播放速度是原来的五倍
为了以3/4的速度观看视频,输入时间戳除以3/4,我们可以使用命令:(我测试了一下,这个括号属于语法错误)
ffplay -i input.mpg -vf setpts=PTS/(3/4)
我的测试命令如下:
ffplay -i /Users/zhangfangtao/Desktop/test.mp4 -vf setpts=PTS/3*4
音频变速
为了调整音频的速度,我们可以使用表中描述的特殊atempo过滤器。
描述 | 改变音频速度-音频流的速度 |
---|---|
语法 | atempo[=tempo] |
参数的描述 | |
tempo | 从0.5 - 2.0范围的浮点数,小于1.0的值降低,超过1.0的值加快速度,默认值为1.0 |
例如,要以2倍的速度听到输入音频,我们可以使用以下命令:
ffplay -i speech.mp3 -af atempo=2
我的测试命令如下:
ffplay -i /Users/zhangfangtao/Desktop/DYZDJ.mp3 -af atempo=2
- 如果输入的结果不在0.5~2这个范围,也能打开ffplay,不过没有声音,终端也会报错的:
我们可以使用atempo=0.5设置,如果速度变化不够,则可以使用更多的时间。
同步音频数据与时间戳
为了使音频数据与时间戳同步,我们可以使用表中描述的asyncts音频过滤器:
描述 | 将音频数据与时间戳同步,通过压缩和删除样本或在需要时进行拉伸和添加静默 |
---|---|
语法 | asyncts=parameters |
描述可用的参数 | |
compensate | 启用拉伸/压缩数据以使其与时间戳相匹配。默认情况下禁用。当残疾的时候,时间间隔是沉默的 |
min_delta | 时间戳和音频数据之间的最小差异(以秒为单位)触发添加/删除示例。默认值是0.1。如果您与此过滤器不完全同步,请尝试将此参数设置为0 |
max_comp | max。样品每秒钟的补偿,仅当补偿=1时,默认值为500 |
first_cts | 假设第一个pts应该是这个值。这允许在流的开始处填充/修剪。默认情况下,没有对第一个帧的预期值做任何假设,所以没有填充或修剪。例如,如果音频流在视频流之后启动,则可以将其设置为0以填充开始时的静默 |
例如,与时间戳同步文件音乐中的数据。mpg我们可以使用以下命令:(在我电脑上-asyncts命令会报错)
ffmpeg -i music.mpg -af asyncts=compensate=1 -f mpegts music.ts
我这边会报错:(我已经在github上面提问了,还没有人回复我)