FFmpeg 的 Drawvg 滤镜
Drawvg Filter for FFmpeg

原始链接: https://ayosec.github.io/ffmpeg-drawvg/

## drawvg:FFmpeg 中的矢量图形 `drawvg` 是一个 FFmpeg 滤镜(自 8.1 版本起可用),它使用其自身语言 VGS 编写的脚本,直接在视频帧上渲染矢量图形。VGS 的设计注重简洁性和易用性,灵感来自 Magick Vector Graphics 和 SVG 路径,语法类似于 TCL 或 shell 脚本。 VGS 利用 Cairo 库进行栅格化,并允许通过 FFmpeg 表达式创建动态图形——从而实现基于帧尺寸、元数据甚至像素颜色的效果。 示例展示了 `drawvg` 的多功能性:创建进度指示器、利用 `cropdetect` 元数据绘制裁剪区域、构建自定义过渡效果(如圆形裁剪或 alpha 合并)、通过读取像素颜色应用像素化效果,以及与 `displace` 滤镜结合生成波浪效果。一个专门的 Playground 提供了更多展示 VGS 功能的示例。`drawvg` 提供了一种强大的方法,可以在 FFmpeg 工作流程中添加自定义视觉元素和效果。

## Drawvg:FFmpeg 的一个用于矢量图形的新滤镜 一个新的滤镜 `drawvg` 已被添加到 FFmpeg 中,允许直接在视频流上绘制矢量图形。这对于遮蔽视频中的元素特别有用——一位用户专门用它来遮盖科技教程中的演讲者叠加层,认为传统的像便签纸这样的方法不方便。 与仅限于矩形的旧滤镜不同,`drawvg` 可以处理圆形等形状,使用简单的内联语法或外部 `.vgs` 文件定义。该滤镜的灵感来自 SVG 路径语法,甚至与“海龟图形”具有概念上的渊源。 讨论强调了未来与机器学习模型集成以实现自动化任务(如面部审查)的可能性,但也指出最近更新导致 FFmpeg 二进制文件大小显著增加。用户正在探索像 mpv 这样的替代方案以获得类似效果,并且一些用户正在利用像 `yt-dlp` 和 FFmpeg 这样的工具来处理 iPad 视频,因为平台存在限制。虽然功能强大,但 FFmpeg 复杂的命令行语法仍然对一些人来说是一个挑战,促使他们使用脚本和 LLM 来管理滤镜配置。
相关文章

原文

drawvg is a FFmpeg filter, available since 8.1, to render vector graphics on top of video frames.

The render is done by executing a script written in its own language, called VGS (Vector Graphics Script). The script consists of a series of commands to describe 2D graphics, which are rasterized using the Cairo library.

VGS is not intended to be used as a general-purpose language. Since its scope is limited, it prioritizes being concise and easy to use. The syntax is heavily inspired by languages like Magick Vector Graphics, or SVG's <path>. Some features of the syntax (like using whitespaces to separate arguments) are also present in languages like TCL or shell scripts. Many command names are taken from PostScript. VGS is fully documented in the language reference.

Scripts can use FFmpeg expressions to describe graphics dynamically, so they can compute coordinates based on frame dimensions, frame metadata, generate random values, read pixel colors, etc.

This is a short list of examples to showcase how to integrate the drawvg filter with other filters in FFmpeg.

The Playground has a gallery with more examples, focused on the capabilities of the VGS language.

Progress Indicator

The variable t can be used to compute one of the angles of the arcn command. Then, we can create an animation like this:

The script can be rendered directly on top of a video:

ffmpeg \
    -an \
    -ss 12 -t 3 -i bigbuckbunny.mov \
    -vf 'crop=iw-1, drawvg=file=progress.vgs, format=yuv420p' \
    -c:v libvpx-vp9 \
    output.webm

This example uses clips from the Big Buck Bunny movie, available under CC BY 3.0 license.

Using Frame Metadata

The cropdetect filter calculates the necessary cropping parameters to remove black borders around a video. These parameters are added to each frame as metadata.

drawvg can access the output of cropdetect with the getmetadata command. The following example draws a red rectangle to represent the calculated area by cropdetect.

ffmpeg \
    -an \
    -i highway.mp4 \
    -vf 'cropdetect, drawvg=file=cropdetect.vgs, format=yuv420p' \
    -c:v libvpx-vp9 \
    output.webm

This example uses the video Night Drive on Highway with Passing Cars, free to use by the pexels license.

CircleCrop Transition

This example creates a transition similar to the circlecrop transition of the xfade filter, but the circle can be positioned anywhere, not only at the center of the frame.

crop = iw-1 ,
drawvg = file=circlecrop.vgs : enable='gt(t,0.8)' ,
format = yuv420p
ffmpeg \
    -an \
    -ss 14 -t 4.2 -i bigbuckbunny.mov \
    -/vf circlecrop.filter \
    -c:v libvpx-vp9 \
    output.webm

This example uses clips from the Big Buck Bunny movie, available under CC BY 3.0 license.

Custom Transitions

Another way to create custom transitions is to use the alphamerge and overlay filters, with a mask rendered with a drawvg script.

This is the output of the drawvg script:

alphamerge can set these frames as the alpha channel of a video. Then, use overlay to put the video with the mask on top of another one.

[0] split [mask-bg] [mask-delay] ;

[mask-bg] drawvg = file=transition.vgs [bars] ;

[mask-delay] [bars] concat [mask] ;

[1] [mask] alphamerge [a] ;

[2] [a]
    overlay = enable='lt(t,4)' ,
    crop = iw-1 ,
    format = yuv420p
ffmpeg \
    -f lavfi -i 'color=white:s=853x480:r=24:d=2' \
    -ss 16 -t 4 -i bigbuckbunny.mov \
    -ss 7:51 -t 6 -i bigbuckbunny.mov \
    -/filter_complex transition.filter \
    -an \
    -c:v libvpx-vp9 \
    output.webm

This example uses clips from the Big Buck Bunny movie, available under CC BY 3.0 license.

Reading Colors

The function p(x, y) returns the color of a pixel at the given coordinates. It can be used to apply pixelization to a frame, similar to the pixelize filter.

Instead of rectangles, the shape used for pixelization are rhombuses, and each one has a thin border to highlight its outline.

The output below shows the original frame on the left, and the frame updated by the drawvg script on the right:

[0] scale = iw/1.5 : -2 , split [a] [b] ;

[a]
    pixelize ,
    drawvg = file=pixelate.vgs ,
    pad = iw*2+30 : ih+20 : iw+20 : ih+10
    [a0] ;

[a0] [b]
    overlay = 10 : 10 ,
    format = yuv420p
ffmpeg \
    -an \
    -ss 1 -t 18 -i bigbuckbunny.mov \
    -/filter_complex pixelate.filter \
    -c:v libvpx-vp9 \
    output.webm

This example uses clips from the Big Buck Bunny movie, available under CC BY 3.0 license.

Waves Effect

drawvg can be combined with the displace filter to create a wave effect:

First, a drawvg script renders horizontal rectangles with different shades of gray. Then, boxblur is used to soften the transition between rectangles. This image is used as the xmap input for displace. The output below contains the intermediate images.

[0] crop = iw-1, split [source0] [source1] ;

[source0]
    drawvg = rect 0 0 w h setcolor gray fill ,
    loop = -1 : 1 : 0 ,
    split
    [gray0] [gray1] ;

[gray0]
    drawvg = file=waves.vgs ,
    split
    [xmap_src0] [xmap_src1] ;

[xmap_src0]
    boxblur = h/40 ,
    split
    [xmap0] [xmap1] ;

[source1] [xmap1] [gray1]
    displace = mirror ,
    pad = iw*2+30 : ih*2+30 : 10:10
    [pad0] ;

[pad0] [xmap_src1] overlay = 10 : h+20 [pad1] ;

[pad1] [source1] overlay = w+20 : 10 : shortest=1 [pad2] ;

[pad2] [xmap0]
    overlay = w+20 : h+20 : shortest=1 ,
    drawtext = text='drawvg' : y=h-20 : x=20 : y_align=baseline : fontsize=32 : fontcolor=white ,
    drawtext = text='boxblur' : y=h-20 : x=w/2+20 : y_align=baseline : fontsize=32 : fontcolor=white ,
    drawtext = text='Source' : y=h/2-20 : x=w/2+20 : y_align=baseline : fontsize=32 : fontcolor=white ,
    format = yuv420p
ffmpeg \
    -an \
    -ss 5 -t 10 -i bigbuckbunny.mov \
    -/filter_complex waves.filter \
    -c:v libvpx-vp9 \
    output.webm

This example uses clips from the Big Buck Bunny movie, available under CC BY 3.0 license.

联系我们 contact @ memedata.com