热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[翻译]FFmpegFiltersDocumentation

注:本文是我在学习FFmpegFiltersDocumentation过程中的中文翻译笔记,为避免英译中过程中一些死板的字面意思引起读者错误理解,有时候我还会加上一些个人注解,若有

注:本文是我在学习FFmpeg Filters Documentation过程中的中文翻译笔记,为避免英译中过程中一些死板的字面意思引起读者错误理解,有时候我还会加上一些个人注解,若有不同见解,请最好参考原文档学习。本翻译仅供参考,转载请注明!





1. 简介

本文档将描述由libavfilter库提供的过滤器(filters)源(sources)接收器(sinks)


关于将Filter翻译为过滤器还是滤波器一直没定论,同时sink也没有比较贴切的中文名词可以放在本语境中。为避免中文翻译之后产生歧义且便于音视频开发者阅读,后续文章中提及上面三个对象以及类似input pad这种不好直接翻译的名词时均用英文表示。



2. Filter

FFmpeg中的Filter相关功能是由库libavfilter提供的。一个Filter可以有N个输入和N个输出(N ≥ 0)。

假设我们现在想将一个视频是上半部分垂直翻转到视频的下半部分镜像显示,我们该怎么做呢?莫慌,我们将以下图作为例子介绍filter处理这个事情的大致流程:

[main]
input --> split ---------------------> overlay --> output
| ^
|[tmp] [flip]|
+-----> crop --> vflip -------+

从上面的filtergraph中可以看出,我们将输入流先分割成两个流并分别被标记为[main][tmp]标签,然后将流[tmp] 经过crop(裁剪)和vflip(垂直翻转)两个过滤器的处理后标记为流[flip],最终将流[flip]这路流overlay(覆盖)到[main]这路流上面去。于是我们可以使用以下命令来实现我们上面的思路:

ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

执行上述命令进行实验之后你会发现,输出的视频是原始视频上半部分垂直翻转镜像的结果,符合预期。

同个链路的Filters使用逗号, 来分隔,每条链路之间用分号; 来分隔。从上面的例子中我们可以看出,cropvflip属于同一条链路,而splitoverlay属于另外独立的两个链路。同时,在每个链路连接点处我们还是用方括号[]的形式来标记链路的输入输出(可以理解为给它们起别名)。

一些过滤器能接受输入参数列表,形式通常是在过滤器名称和等号后面指定,并用冒号彼此隔开,如crop=iw:ih/2:0:0 表示要从原始视频中裁剪出一样宽,一半高的视频。(详见下文的crop过滤器详细介绍)

通常情况下filter都有输入输出,但是在FFmpeg的世界里还存在两种特殊的filter,即:



  • source filters: 没有任何输入

  • sink filters: 没有任何输出


3. graph2dot

不重要,先不翻译


4. Filtergraph

Filtergraph是链接多个Filter的有向图。

它可以包含循环,各个Filter之间也可以有多个链接。每个链接有一个input pad连接到一个Filter并从那里获取输入,有一个output pad连接到另一个Filter提供输出。所有的Filter都是已经注册在程序中的。没有输入的Filter叫source,没有输出的Filter叫sink


4.1 Filtergraph 语法

每个Filtergraph都有对应的结构化的文本表示:



  • 对于命令ffmpeg来说有-filter, -vf, -af-filter_complex这些选项

  • 对于命令ffplay来说有-vf, -af 这些选项


可参考源码libavfilter/avfilter.havfilter_graph_parse_ptr()了解更多细节


从整体看,Filtergraph包含Filterchain,而Filterchain又包含了Filter



  • filtergraph是由一个或多个filterchain组成,filterchain之间使用分号; 来分隔

  • filterchain是由一个或多个filter线性连接而成,filter之间使用逗号, 来分隔

  • filter的语法格式为:[in_link_1]...[in_link_N]filter_name@id=arguments[out_link_1]...[out_link_M]。顾名思义,filter_name就是你所要使用的filter的名称,它必定是已经在libavfilter中有注册的,后面的@id是可选的(基本没用到);紧跟着的=arguments也是可选填的(有些filter并不需要参数),arguments通常有如下格式:

    • : 来分隔一系列值。(这种情况下参数的顺序就是固定的,值的顺序必须按照filter声明的参数顺序来一个个占坑,类似平时写程序时函数调用填实参一样)

    • : 来分隔一系列的key=value的键值对。(这种情况下参数的顺序就不是固定的了,类似Javascript或者Python的指定关键字参数

    • : 来分隔一系列值,之后跟着一系列的key=value的键值对,值必须在键值对前面。(同上,类似Javascript或者Python这类语言的函数调用方式)

    • 有时候value本身就是要填一系列参数值的,那么需要用|来拼接(参考format这个filter)



从上面可以看出,[]=;,这些字符对于参数列表都是特殊字符,所以在参数列表中若要用到特殊字符,可以用单引号''将参数列表包起来,然后用\对特殊字符进行转义。

Filter的名称和参数前后是允许放置一个或多个链接标签link label)的。所谓的链接标签就是一个链接(link)的别名,可以将它们关联到Filter的输入/输出。放在前面的链接标签in_link_1 ... in_link_N 被关联到Filter的input pad,后面的out_link_1 ... out_link_M 被关联到Filter的output pad。当在Filtergraph中匹配到两个同名的链接标签时,Filter将创建其对应的input padoutput pad之间的链接。

如果一个Filter的output pad没被标记链接标签,则它会被默认链接到后续的Filter中第一个未标记链接标签的input pad,如:

nullsrc, split[L1], [L2]overlay, nullsink

上面的split有两个output pad,一个是[L1],另一个是匿名的;而overlay又拥有两个input pad,一个是[L2],另一个是匿名的;因此这两个匿名的pad会被链接起来:split -> overlay

缺省情况下,第一个Filter的输入标签为[in],最后一个Filter的输出标签为[out]。如下面两个Filtergraph是一样的:

ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
ffmpeg -i INPUT -vf "[in] split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2 [out]" OUTPUT

对于一个完整可用的Filterchain来说,所有匿名的链接标签必须有被链接。

对于一个Filtergraph来说,只有所有的Filterchain的input padoutput pad都被连接起来,才是一个有效可用的Filtergraph。

libavfilter在处理Filtergraph过程中当遇到有格式转换的时候会自动插入scale这个Filter,因此你可以在Filtergraph描述中的可能会隐式包含scale的地方前面加上你要指定的缩放参数:sws_flags=flags;

下面是针对Filtergraph语法的一个BNF描述:

NAME ::= sequence of alphanumeric characters and '_'
FILTER_NAME ::= NAME["@"NAME]
LINKLABEL ::= "[" NAME "]"
LINKLABELS ::= LINKLABEL [LINKLABELS]
FILTER_ARGUMENTS ::= sequence of chars (possibly quoted)
FILTER ::= [LINKLABELS] FILTER_NAME ["=" FILTER_ARGUMENTS] [LINKLABELS]
FILTERCHAIN ::= FILTER [,FILTERCHAIN]
FILTERGRAPH ::= [sws_flags=flags;] FILTERCHAIN [;FILTERGRAPH]

4.2 关于Filtergraph的字符转义

详见:(ffmpeg-utils)the "Quoting and escaping" section in the ffmpeg-utils(1) manual。



  1. 优先考虑Filter的参数值本身是否包含:\这些特殊字符

  2. 再考虑整个Filterchain中是否包含\或者[],=;这些特殊字符

  3. 最后如果你是使用命令行,还要从shell命令行的角度去考虑shell语句级别的字符转义

举个例子,假设你要用drawtext这个Filter来给视频加上文字:

this is a 'string': may contain one, or more, special characters

根据第1点提到的,它包含了':两个特殊字符,于是你要这么做:

text=this is a \'string\'\: may contain one, or more, special characters

根据第2点提到的,它包含了\转义字符和', 这些特殊字符,于是你要这么做:

drawtext=text=this is a \\\'string\\\'\\: may contain one\, or more\, special characters

根据第3点提到的,如果你要在shell上使用这个命令,还需要这么做:

-vf "drawtext=text=this is a \\\\\\'string\\\\\\'\\\\: may contain one\\, or more\\, special characters"

5. 时间轴编辑

未完待续




  • https://ffmpeg.org/ffmpeg-filters.html#Filtering-Introduction

  • https://wiki.multimedia.cx/index.php/FFmpeg_filter_HOWTO




推荐阅读
  • OBS Studio自动化实践:利用脚本批量生成录制场景
    本文探讨了如何利用OBS Studio进行高效录屏,并通过脚本实现场景的自动生成。适合对自动化办公感兴趣的读者。 ... [详细]
  • DirectShow Filter 开发指南
    本文总结了 DirectShow Filter 的开发经验,重点介绍了 Source Filter、In-Place Transform Filter 和 Render Filter 的实现方法。通过使用 DirectShow 提供的类,可以简化 Filter 的开发过程。 ... [详细]
  • 入门指南:使用FastRPC技术连接Qualcomm Hexagon DSP
    本文旨在为初学者提供关于如何使用FastRPC技术连接Qualcomm Hexagon DSP的基础知识。FastRPC技术允许开发者在本地客户端实现远程调用,从而简化Hexagon DSP的开发和调试过程。 ... [详细]
  • 处理Android EditText中数字输入与parseInt方法
    本文探讨了如何在Android应用中从EditText组件安全地获取并解析用户输入的数字,特别是用于设置端口号的情况。通过示例代码和异常处理策略,展示了有效的方法来避免因非法输入导致的应用崩溃。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • 本文详细介绍了如何正确设置Shadowsocks公共代理,包括调整超时设置、检查系统限制、防止滥用及遵守DMCA法规等关键步骤。 ... [详细]
  • 小编给大家分享一下Vue3中如何提高开发效率,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获, ... [详细]
  • 在尝试通过自定义端口部署Spring Cloud Eureka时遇到了连接失败的问题。本文详细描述了问题的现象,并提供了有效的解决方案,以帮助遇到类似情况的开发者。 ... [详细]
  • 根据官方定义,RxJava是一种用于异步编程和可观察数据流的API。其核心特性在于流式处理能力和丰富的操作符支持。 ... [详细]
  • 探讨低代码行业发展现状,分析其未能催生大型企业的原因,包括市场需求、技术局限及商业模型等方面。 ... [详细]
  • 腾讯云移动推送TPNS(Tencent Push Notification Service)为APP开发者和运营人员提供了一站式、高效、稳定的推送解决方案,帮助提升用户活跃度和运营效率。 ... [详细]
  • 深入解析Dubbo:使用与源码分析
    本文详细介绍了Dubbo的使用方法和源码分析,涵盖其架构设计、核心特性和调用流程。 ... [详细]
  • 本文介绍了一种通过设置主题(Theme)来实现快速启动的Android引导页,并详细说明了如何避免因不同屏幕分辨率导致的图片拉伸问题。 ... [详细]
  • 本文介绍了如何将Spring属性占位符与Jersey的@Path和@ApplicationPath注解结合使用,以便在资源路径中动态解析属性值。 ... [详细]
author-avatar
袁善恩芷恩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有