FFmpeg 命令行视频处理拼接实战

涉及ffmpeg效果如下:
截取、拼接、添加文字、图片转视频、混音、横批转竖屏

效果:

固定的片头片尾+视频中间内容是对用户之前提交过的n个历史视频的截取片段的拼接+固定片尾,视频片段切换添加了转场特效。

示例描述:
片头 +
第一次提交视频的相关信息展示(2s 时长) +
第一次提交的视频截取片段 +
第N次提交视频的相关信息展示(2s 时长) +
第N次提交的视频截取片段 +
片尾

大致操作步骤:

  1. 对n个MP4视频进行截取。
  2. 对n个截取片段进行缩放,保证每个视频的宽高是一样的。
  3. 生成介绍视频
  4. 拼接
  5. 添加背景音乐

实际命令

公共编码参数:

-c:v libx264 -profile:v high -crf 18 -r 30 -b:v 665k -acodec aac -ar 48000 -ab 128k

下文以 {commonFFmpegArg} 代替

1.截取视频

-ss 5 视频开始时长
-t 25 截取时长
-vbsf h264_mp4toannexb mp4 转 ts 文件的时候添加这个参数,不太清楚。

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.mp4 -ss 5 -t 25 -c:v libx264 -profile:v high -crf 18 -r 30 -b:v 665k -acodec aac -ar 48000 -ab 128k -y -vbsf h264_mp4toannexb /video_splicing/2077357_0_55257_cut.ts > /dev/null 2>&1

参数位置与截取速度
-ss 在 -i 参数之前,截取处理数据,但是时间时长偏差较。(时长偏差值大概 1-10 s之间,实际值好像解决取视频中关键帧的位置)
-ss 在 -i 参数之后,时间时长偏差较,但截取处理数据

2. 缩放视频

竖屏缩放

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.ts -vf scale=544:960 {$this->commonFFmpegArg} -y /video_splicing/2077357_0_55257_scale.ts

横批转竖屏

# 等比缩放+模糊背景

# 同一个视频分开为a,b 两个流
# a -> 按照308:544(544/960比例)截取视频 -> e -> 使用模糊效果 -> f -> 放大到544/960 尺寸 -> 1
# b -> 缩小到544/-1(544/960比例) 尺寸 -> 2
# 将 2 放到 1 的视频中间。

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.ts -vf "split[a][b];[a]crop=ih*(544/960):ih[e];[e]boxblur=5:5[f];[f]scale=544:960[1];[b]scale=544:308[2];[1][2]overlay=0:326" {commonFFmpegArg} -y /video_splicing/2077357_0_55257_scale.ts

背景模糊.jpg

scale=544:-1 缩放至宽度544,高度等比缩放
pad=544:960:0:326:black 视频宽高为544*960,将前面视频(左上角)贴在 x(0),y(326)的位置,背景色设置为 黑色。

# 等比缩放+上下黑边
/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.ts -vf scale=544:-1,pad=544:960:0:326:black {commonFFmpegArg} -y /video_splicing/2077357_0_55257_scale.ts

3. 图片添加文字

drawtext 添加文字
fontfile=/usr/share/fonts/HYZhengYuan/HYZhengYuan-65W.ttf 字体文件
fontsize=32 文字大小
fontcolor=white 文字颜色
text='05月15日' 文本内容

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/page_bg_img.png -vf "[in]drawtext=fontfile=/usr/share/fonts/HYZhengYuan/HYZhengYuan-65W.ttf:fontsize=32:fontcolor=white:text='05月15日':x=(w-text_w)/2:y=155[a];[a]drawtext=fontfile=/usr/share/fonts/HYZhengYuan/HYZhengYuan-65W.ttf:fontsize=30:fontcolor=#682A28:text='第十一讲':x=(w-text_w)/2:y=270[b];[b]drawtext=fontfile=/usr/share/fonts/HYZhengYuan/HYZhengYuan-65W.ttf:fontsize=24:fontcolor=#5E1A1B:text='提交时间:05月16日 17\:20':x=(w-text_w)/2:y=852[out];[out]drawtext=fontfile=/usr/share/fonts/HYZhengYuan/HYZhengYuan-85W.ttf:fontsize=48:fontcolor=#E5756A:text='周长与面积':x=(w-text_w)/2:y=332[str0]" -y /video_splicing/2077357_546206_page_bg_img.png > /dev/null 2>&1

文字换行
drawtext 添加的文本不能换行,过长的文本内容将会超出视频宽度。需要手动换行。
我以为的手动换行是给文本内容里添加 n 。但是没起效果。
后来改成手动切割文本内容。分为添加多个 drawtext 过滤器(每个的 y 是上行位置+行高)。
或者使用字幕过滤器(默认支持自动换行)。
文字换行.jpg

4. 图片转视频

-f lavfi 启用虚拟音视频源。(link:https://www.jianshu.com/p/c84...
-f lavfi -i anullsrc=sample_rate=48000:channel_layout=stereo 生成空白的音频数据,48000采样率和左右声道。不添加此选项生成的视频文件没有音频流,在视频拼接和添加背景音乐的时候会出现音视频时间不同步的问题。
-loop 1 单个图片转视频
-pix_fmt yuvj420p 设置颜色空间,不懂啥意思,一直设置的这个。
-t 2.5 设置视频时长 2.5 s
-vbsf h264_mp4toannexb 生成 ts 文件的时候添加这个参数,不太清楚。

/var/ffmpeg_build/bin/ffmpeg -f lavfi -i anullsrc=sample_rate=48000:channel_layout=stereo -loop 1 -i /video_splicing/2077357_546206_page_bg_img.png -pix_fmt yuvj420p -t 2.5 {commonFFmpegArg} -vbsf h264_mp4toannexb -y /video_splicing/2077357_546206_video.ts

5.淡入特效

fade=t=in:st=0:d=0.5:c=white 设置淡入特效,.5 s过渡时长,背景色为白色。

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257_cut.ts -vf "fade=t=in:st=0:d=0.5:c=white" {commonFFmpegArg} -pix_fmt yuvj420p -y /video_splicing/2077357_0_55257_cut_fade.ts

背景色与 pix_fmt 的关联

当 fade 指定背景色时需要指定颜色空间值,否则会报一下错误。

x264 [error]: high profile doesn't support 4:4:4
[libx264 @ 0x471afc0] Error setting profile high.
[libx264 @ 0x471afc0] Possible profiles: baseline main high high10 high422 high444
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

6. 视频拼接

-f concat 指定虚拟输入为文件连接器。
-safe 0 添加上,否则会报错误:“Unsafe file name xxxxxx”。
-bsf:a aac_adtstoasc 不懂啥意思,反正加上了。
-movflags +faststart 建议加上。这样分享文件给别人的时候可以边下边看

/var/ffmpeg_build/bin/ffmpeg -f concat -safe 0 -i /video_splicing/2077357_files.txt -bsf:a aac_adtstoasc -movflags +faststart -y /video_splicing/2077357_splice.mp4

公共编码参数
没有添加 公共编码参数,添加上后生成的视频码率一直在 1200 左右,-b:v 665k 好像没有生效,不知道什么原因,就去除了音视频编码参数。
去除后生成的视频码率为 600k 左右,文件大小减少为近一半。

7. 加入背景音乐

volume=0.13 减小背景音乐的音量
aloop=loop=-1:size=2e+09 背景音乐无限循环。如果背景音乐时长小于视频时长需要添加此过滤器
atrim=7:138 背景音乐的截取时间段为 7 至 138 秒。(片尾没有背景音乐,片尾在138秒之后)
adelay=6000|6000 背景音乐延迟 6 秒进行播放。(片头没有背景音乐)
[out][0:a]amix 将背景音乐和视频原音轨进行混音。等效于[out][0:a]amix:inputs=2:duration=longest:dropout_transition=2 (默认值),2个音轨进行混音,时长取最长的音轨。'out' 位置不能互换位置,按说应该可以互换,但是我这边互换后最后2秒没有声音。

 /var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_splice.mp4 -i /video_splicing/background.aac -filter_complex "[1:a]volume=0.13[vo];[vo]aloop=loop=-1:size=2e+09[loo];[loo]atrim=7:138[tr];[tr]adelay=6000|6000[out];[out][0:a]amix" -y /video_splicing/2077357_splice_music.mp4

公共编码参数
没有添加 公共编码参数,添加上后生成的视频码率一直在 1200 左右,-b:v 665k 好像没有生效,不知道什么原因,就去除了音视频编码参数。
去除后生成的视频码率为 600k 左右,文件大小减少为近一半。

遇到的问题

视频旋转角度对视频缩放的影响

先来看两张横屏转竖屏失败案例。

2201108_200602170450[00_00_36][20200602-193956].png

导致上面效果的原因是视频的文件信息里包含了视频旋转角度是设置:
可通过 ffmpeg -i file.mp4 命令查看。

# rotate:  视频旋转了多少度
# displaymatrix:播放时旋转多少度

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/video_splicing/2201108_5_29744.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100
  Duration: 00:02:46.30, start: 0.000000, bitrate: 637 kb/s
    Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 128 kb/s (default)
    Metadata:
      rotate          : 270
      handler_name    : SoundHandler
    Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 368x640, 502 kb/s, 29.95 fps, 29.97 tbr, 180k tbn, 360k tbc (default)
    Metadata:
      rotate          : 270
      handler_name    : VideoHandler
    Side data:
      displaymatrix: rotation of 90.00 degrees



Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '/video_splicing/2201108_6_89957.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100
  Duration: 00:03:45.28, start: 0.000000, bitrate: 639 kb/s
    Stream #1:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      rotate          : 90
      handler_name    : SoundHandler
    Stream #1:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368, 503 kb/s, 29.96 fps, 29.97 tbr, 180k tbn, 360k tbc (default)
    Metadata:
      rotate          : 90
      handler_name    : VideoHandler
    Side data:
      displaymatrix: rotation of -90.00 degrees

所以旋转了 90度或 270度的时候,视频的宽度对应的 y 值, 视频的高度对应的 x 值。

也可以 先去除视频角度,再获取视频的 xy 值。

去除视频角度方式一:

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357.mp4 -metadata:s:v:0 rotate=0 -y /video_splicing/2077357_0.mp4

去除视频角度方式二:

/var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.mp4 -y -vbsf h264_mp4toannexb /video_splicing/2077357_0_55257_cut.ts

你可能感兴趣的:(ffmpeg)