ffmpeg 时间裁剪之-ss -t与滤镜中trim=start=*:duration=*的区别和联系

2024-02-03 09:52

本文主要是介绍ffmpeg 时间裁剪之-ss -t与滤镜中trim=start=*:duration=*的区别和联系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

工作中遇到的呗。记下来贡着。

滤镜重置时间戳:setpts=PTS-STARTPTS

在FFmpeg中,setpts=PTS-STARTPTS是一种用于调整视频时间戳(PTS)的滤镜表达式。这个表达式通常用于视频编辑和处理过程中,用于修改视频的时间轴。

让我们解释一下这个表达式的各个部分:

PTS:表示当前帧的原始时间戳(针对滤镜的输入而言,而非原始文件)。时间戳是用于确定视频中每一帧的时刻的数值。在ffmpeg执行过程中,这是个动态值

STARTPTS:表示流的开始时间戳。这是输入流的第一帧的时间戳。在一个处理链中,STARTPTS用于引用流的初始时间戳,而不是每一帧的时间戳。这是个确定的值,等于滤镜拿到的「视频流的开始时间戳」,在ffmpeg执行过程中,恒定不变。这里强调一下,滤镜内trim指定的起始时间(不指定则默认0)如果还没有出现视频流,则STARTPTS会一直向后找到视频流,把遇到的首帧时间戳作为其值。

PTS-STARTPTS(相减):这部分表示当前帧相对于开始时间戳的偏移量。使用这个表达式会将视频的时间轴重新设置,以使第一帧的时间戳为零,后续帧的时间戳相对于第一帧进行调整。

setpts:这是一个滤镜指令,用于设置帧的新时间戳。通过将setptsPTS-STARTPTS结合使用,可以重新计算和调整视频帧的时间戳。

综合起来,setpts=PTS-STARTPTS的效果是将视频的时间轴重新调整,使第一帧的时间戳为零,后续帧相对于第一帧进行相应的时间调整。这在一些视频处理场景中很有用,例如剪辑、拼接或进行时间轴变换。

在这里插入图片描述

另外,滤镜的输入,是-ss -t 等参数裁剪完之后的结果,这个结果的时间戳从0开始。所以对于滤镜来说,滤镜拿到的输入文件的时间戳总是起始于0。但是,视频流却未必起始于0。例如,-ss -t裁剪完,传给滤镜的文件 总时长10秒,但视频流只在7~10秒(也就是前7秒没画面),那么STARTPTS值恒为7,PTS值为变量,即每一帧的时间戳(起始于STARTPTS)。

案例一:滤镜不重置时间戳

ffmpeg -ss 10 -stream_loop -1 -i dongwu_25min.mp4 -t 30 -filter_complex "[0:v]scale=1920:1080,trim=start=5.000000:duration=10.000,showinfo[node1_f2_media1]" -map "[node1_f2_media1]" -y output.mp4

注意:滤镜中的duration=10.000会严格取视频流的持续时长,如有空白则跳过。

打印中间信息:

[Parsed_showinfo_2 @ 0x6000026b0160] n:   1 pts:  64538 pts_time:5.04203 duration:    512 duration_time:0.04    pos:  6978739 fmt:yuv420p sar:1/1 s:1920x1080 i:P iskey:1 type:I checksum:6E67BBE3 plane_checksum:[4C14CFED 616C9631 542B55B6] mean:[114 114 140] stdev:[46.7 10.5 8.2]
[Parsed_showinfo_2 @ 0x6000026b0160] color_range:tv color_space:bt709 color_primaries:bt709 color_trc:bt709
[Parsed_showinfo_2 @ 0x6000026b0160] n:   2 pts:  65050 pts_time:5.08203 duration:    512 duration_time:0.04    pos:  7073379 fmt:yuv420p sar:1/1 s:1920x1080 i:P iskey:0 type:B checksum:7F7442B0 plane_checksum:[5183AB5E C054091B A25D8E28] mean:[114 114 140] stdev:[46.9 10.5 8.3]
[Parsed_showinfo_2 @ 0x6000026b0160] color_range:tv color_space:bt709 color_primaries:bt709 color_trc:bt709
[Parsed_showinfo_2 @ 0x6000026b0160] n:   3 pts:  65562 pts_time:5.12203 duration:    512 duration_time:0.04    pos:  7082240 fmt:yuv420p sar:1/1 s:1920x1080 i:P iskey:0 type:B checksum:A5B5226D plane_checksum:[EC5F922E 1D3CB01D 4CF5E004] mean:[113 114 140] stdev:[47.0 10.5 8.3]# .........[Parsed_showinfo_2 @ 0x6000026b0160] n: 248 pts: 191002 pts_time:14.922  duration:    512 duration_time:0.04    pos: 11124238 fmt:yuv420p sar:1/1 s:1920x1080 i:P iskey:0 type:P checksum:2DD2E7F0 plane_checksum:[C0E163CA 3CD3F5D4 0B798E43] mean:[118 116 138] stdev:[38.6 7.5 6.8]
[Parsed_showinfo_2 @ 0x6000026b0160] color_range:tv color_space:bt709 color_primaries:bt709 color_trc:bt709
[Parsed_showinfo_2 @ 0x6000026b0160] n: 249 pts: 191514 pts_time:14.962  duration:    512 duration_time:0.04    pos: 11221829 fmt:yuv420p sar:1/1 s:1920x1080 i:P iskey:0 type:B checksum:46C2FCF7 plane_checksum:[129AED32 F4604F36 708DC080] mean:[118 116 138] stdev:[38.6 7.5 6.8]
[Parsed_showinfo_2 @ 0x6000026b0160] color_range:tv color_space:bt709 color_primaries:bt709 color_trc:bt709
frame=  375 fps= 60 q=-1.0 Lsize=    4848kB time=00:00:14.88 bitrate=2669.2kbits/s dup=125 drop=0 speed=2.39x
video:4843kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.104424%
[libx264 @ 0x128006460] frame I:2     Avg QP:17.26  size: 95752

产出视频总时长15秒,前5秒静止为首帧。原因是时间戳保留为滤镜的输入,即输入流从第5秒才开始出现。

案例二:滤镜重置时间戳

ffmpeg -ss 10 -stream_loop -1 -i dongwu_25min.mp4 -t 30 -filter_complex "[0:v]scale=1920:1080,trim=start=5.000000:duration=10.000,setpts=PTS-STARTPTS,showinfo[node1_f2_media1]" -map "[node1_f2_media1]" -y output.mp4

由于设置了setpts=PTS-STARTPTS,视频流导出后的时间戳从0开始。注意-t最好给足,不然滤镜拿到的视频流可能不够用而导致产出视频变短。

案例三:讨论-i -ss -t 顺序问题

情况1: -ss -t -i (可能不符合预期)

ffmpeg -ss 8 -t 4 -i _part1.mp4 -y output.mp4

-ss是截取输入文件的时间戳,-t视频流的最大持续时长。如果-ss指定的开始时间有一段时间不含视频流,那么-t的截取会跳过这段空白,直到找到视频流才计算时长。

在这里插入图片描述

如图视频的视频流是第10秒才开始有,则-ss 8 -t 4 -i a.mp4的情况下,实际产物总时长6秒,且只有后4秒有视频流。

情况2: -ss -i -t (强烈推荐使用)

ffmpeg -ss 8 -i _part1.mp4 -t 4 -y output.mp4

-ss是截取输入文件的时间戳,-t输出文件的最大持续时长。如果-ss指定的开始时间有一段时间不含视频流,那么-t的截取不会跳过这段空白。
在这里插入图片描述

-t-i之前和之后的区别

-t-i之前,则持续时长是针对-i输入文件的流而言;-i-t之前,则持续时长是针对输出文件而言。

情况3:-i -ss -t(慎用)

ffmpeg -i _part1.mp4  -ss 14:8 -t 4 -y output.mp4

-ss是截取输入文件解码后的时间戳,-t输出文件的最大持续时长。

-ss-i之前和之后的区别

-ss-i之前,则截取的起始是针对-i输入文件(不是流)而言;-i-ss之前,则截取起始时间是针对解码后加粗样式的文件而言,比如-ss 20:00会浪费性能为前20分钟解码。

关于滤镜中的duration和PTS

滤镜中的duration会严格截取视频流的时长,有空白则跳过。

时间戳PTS如果设的超出预期时长,则还是会按时间戳播放,从而导致总时长变长。

这篇关于ffmpeg 时间裁剪之-ss -t与滤镜中trim=start=*:duration=*的区别和联系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/673778

相关文章

C# 委托中 Invoke/BeginInvoke/EndInvoke和DynamicInvoke 方法的区别和联系

《C#委托中Invoke/BeginInvoke/EndInvoke和DynamicInvoke方法的区别和联系》在C#中,委托(Delegate)提供了多种调用方式,包括Invoke、Begi... 目录前言一、 Invoke方法1. 定义2. 特点3. 示例代码二、 BeginInvoke 和 EndI

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

在Dockerfile中copy和add的区别及说明

《在Dockerfile中copy和add的区别及说明》COPY和ADD都是Dockerfile中用于文件复制的命令,但COPY仅用于本地文件或目录的复制,不支持自动解压缩;而ADD除了复制本地文件或... 目录在dockerfile中,copy 和 add有什么区别?COPY 命令ADD 命令总结在Doc

MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

解读Pandas和Polars的区别及说明

《解读Pandas和Polars的区别及说明》Pandas和Polars是Python中用于数据处理的两个库,Pandas适用于中小规模数据的快速原型开发和复杂数据操作,而Polars则专注于高效数据... 目录Pandas vs Polars 对比表使用场景对比Pandas 的使用场景Polars 的使用

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav