使用 FFmpeg 为视频添加文字并带角度旋转

如何通过Drawtext给视频画上文字,并且能够给文字旋转个角度,比如30度角?本文将重点介绍一下利用FFmpeg如何做到这样的效果,首先看一下效果图:

图片

这样的效果操作原理比较简单,步骤如下:

1. 给文字创建一个需要写字的画布,带上纯色

2. 因为旋转的话,可能会有对角被画出原本宽高范围导致显示不全,所以可以计算一下文字宽高,需要显示的文字的个数,旋转角度后需要用的显示宽高,然后计算出来在画布的显示偏移,这样就可以了

3. 将文字铺在画布上之前做一个旋转,旋转后剩余的空间填充与画布纯色相同的颜色

4. 将旋转后的文字铺在画布上

5. 用纯色抠图的colorkey设置Alpha通道

6. 将抠图设置好Alpha通道后的图像数据铺在最终需要铺的画布的位置

整个过程看上去相对来说比较简单。

用到的滤镜主要如下:

  1.  lavfi   可以作为输入设备的滤镜例如color,testsrc,testsrc2等
  2. drawtext  用来绘制文字,主要需要使用FreeType、Fontconfig
  3. rotate  用来旋转角度用,但是这里面参数是弧度,需要自己演算一下角度
  4. colorkey 用来做纯色抠像,主要根据传入的颜色设置一下 Alpha
  5. overlay 和名字一样的功能

其实主要需要注意的参数是drawtext与rotate部分的,看一下参数说明:


Filter drawtext
  Draw text on top of video frames using libfreetype library.
    Inputs:
#0: default (video)
    Outputs:
#0: default (video)
drawtext AVOptions:
  fontfile          <string>     ..FV..... set font file
  text              <string>     ..FV..... set text
  textfile          <string>     ..FV..... set text file
  fontcolor         <color>      ..FV..... set foreground color (default "black")
  fontcolor_expr    <string>     ..FV..... set foreground color expression (default "")
  boxcolor          <color>      ..FV..... set box color (default "white")
  bordercolor       <color>      ..FV..... set border color (default "black")
  shadowcolor       <color>      ..FV..... set shadow color (default "black")
  box               <boolean>    ..FV..... set box (default false)
  boxborderw        <int>        ..FV..... set box border width (from INT_MIN to INT_MAX) (default 0)
  line_spacing      <int>        ..FV..... set line spacing in pixels (from INT_MIN to INT_MAX) (default 0)
  fontsize          <string>     ..FV..... set font size
  x                 <string>     ..FV..... set x expression (default "0")
  y                 <string>     ..FV..... set y expression (default "0")
  shadowx           <int>        ..FV..... set shadow x offset (from INT_MIN to INT_MAX) (default 0)
  shadowy           <int>        ..FV..... set shadow y offset (from INT_MIN to INT_MAX) (default 0)
  borderw           <int>        ..FV..... set border width (from INT_MIN to INT_MAX) (default 0)
  tabsize           <int>        ..FV..... set tab size (from 0 to INT_MAX) (default 4)
  basetime          <int64>      ..FV..... set base time (from I64_MIN to I64_MAX) (default I64_MIN)
  font              <string>     ..FV..... Font name (default "Sans")
  expansion         <int>        ..FV..... set the expansion mode (from 0 to 2) (default normal)
     none                         ..FV..... set no expansion
     normal                       ..FV..... set normal expansion
     strftime                     ..FV..... set strftime expansion (deprecated)
  timecode          <string>     ..FV..... set initial timecode
  tc24hmax          <boolean>    ..FV..... set 24 hours max (timecode only) (default false)
  timecode_rate     <rational>   ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
  r                 <rational>   ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
  rate              <rational>   ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
  reload            <boolean>    ..FV..... reload text file for each frame (default false)
  alpha             <string>     ..FV..... apply alpha while rendering (default "1")
  fix_bounds        <boolean>    ..FV..... check and fix text coords to avoid clipping (default false)
  start_number      <int>        ..FV..... start frame number for n/frame_num variable (from 0 to INT_MAX) (default 0)
  ft_load_flags     <flags>      ..FV..... set font loading flags for libfreetype (default 0)
default                      ..FV.....
     no_scale                     ..FV.....
     no_hinting                   ..FV.....
     render                       ..FV.....
     no_bitmap                    ..FV.....
     vertical_layout              ..FV.....
     force_autohint               ..FV.....
     crop_bitmap                  ..FV.....
     pedantic                     ..FV.....
     ignore_global_advance_width              ..FV.....
     no_recurse                   ..FV.....
     ignore_transform              ..FV.....
     monochrome                   ..FV.....
     linear_design                ..FV.....
     no_autohint                  ..FV.....

This filter has support for timeline through the 'enable' option.

最好一行不差的读完,不会英语的用有道翻译,谷歌翻译都可以,不知道某讯有没有翻译产品,反正我没用过,估计是翻译产品应该都差不多可以知道啥意思。

本文主要用了这么几个参数:

  1.  fontfile 用来指定字体文件,比如微软雅黑比较常见,就是系统里面的ttc、ttf、otf这类字体
  2. x 文字显示的x坐标
  3. y 文字显示的y坐标
  4. fontsize 文字大小

文字部分大概介绍完毕。下面看一下rotate参数。

rotate的参数如下:


Filter rotate
  Rotate the input image.
    slice threading supported
    Inputs:
       #0: default (video)
    Outputs:
       #0: default (video)
rotate AVOptions:
  angle             <string>     ..FV..... set angle (in radians) (default "0")
  a                 <string>     ..FV..... set angle (in radians) (default "0")
  out_w             <string>     ..FV..... set output width expression (default "iw")
  ow                <string>     ..FV..... set output width expression (default "iw")
  out_h             <string>     ..FV..... set output height expression (default "ih")
  oh                <string>     ..FV..... set output height expression (default "ih")
  fillcolor         <string>     ..FV..... set background fill color (default "black")
  c                 <string>     ..FV..... set background fill color (default "black")
  bilinear          <boolean>    ..FV..... use bilinear interpolation (default true)

This filter has support for timeline through the 'enable' option.

本问主要用到了如下两个参数:

  1.  angle或者a  注意看说明,这可不是角度,是弧度,弧度与角度有个计算公式,需要自己去平面几何基础课程补一下相关知识。
  2. fillcolor或者c 旋转后原来显示图像的区域需要填充些什么,比如黑色,白色等,默认是黑色。

命令行部分:

好,基本部分描述完毕,下面我们看一下怎么拼一下这样的命令行:


ffmpeg -i ~/Movies/objectC/facebook.mp4 -filter_complex "color=White:s=400x400[v1];[v1]drawtext=fontfile=/Library/Fonts/Songti.ttc:text='这是什么东西?':x=60:y=50:fontsize=20[o1];[o1]rotate=a=-PI*30/180:fillcolor=White@0[o1];[o1]colorkey=White:0.01:1[o2];[0:v][o2]overlay=x=(W-w)/2:y=(H-h)/2" -y b.mp4

这条命令行执行后,效果图就是本文第一张图的效果。

API部分:

命令行部分介绍完了,下面是上API使用时间,看一下API部分怎么操作。

StevenLiu:dash StevenLiu$ git diff
diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index e48837cbd2..5dbcd376e8 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -391,7 +391,7 @@ static int init_filters(void)


         if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
-            filter_spec = "null"; /* passthrough (dummy) filter for video */
+            filter_spec = "color=White:s=400x400[v1];[v1]drawtext=fontfile=/Library/Fonts/Songti.ttc:text='这是什么东西?':x=60:y=50:fontsize=20[o1];[o1]rotate=a=-PI*30/180:fillcolor=White@0[o1];[o1]colorkey=White:0.01:1[o2];[in][o2]overlay=x=(W-w)/2:y=(H-h)/2"; /* passthrough (dummy) filter for video */
         else
             filter_spec = "anull"; /* passthrough (dummy) filter for audio */
         ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,

照着做问题不大。这回就介绍这么些。

作者:悟空;公众号:流媒体技术

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(1)

相关推荐

发表回复

登录后才能评论