当前位置: 首页 > article >正文

使用ffmpeg叠加视频

使用 FFmpeg 的滤镜功能来实现视频叠加和参数调整。

版本要求

请确保 FFmpeg 版本 ≥ 4.0。

参数说明

参数名称作用
背景视频作为背景的视频文件
上层视频叠加在上层的视频文件
上层宽度上层视频的宽度(高度按比例自适应)
时间偏移上层视频从第几秒开始显示
透明度上层视频的透明度(0.0 完全透明,1.0 完全不透明)
x比例上层视频的水平位置比例(0=左侧,1=右侧,0.5=居中)
y比例上层视频的垂直位置比例(0=顶部,1=底部,0.5=居中)
输出文件名最终生成的视频文件名

运行示例
假设:

  • 背景视频:<font style="color:rgb(64, 64, 64);">background.mp4</font>
  • 上层视频:<font style="color:rgb(64, 64, 64);">input1.mp4</font>
  • 上层宽度:<font style="color:rgb(64, 64, 64);">640</font>(宽度640,高度按比例自适应)
  • 时间偏移:<font style="color:rgb(64, 64, 64);">5</font>(从第5秒开始显示上层视频)
  • 透明度:<font style="color:rgb(64, 64, 64);">0.5</font>(50%透明度)
  • x比例:<font style="color:rgb(64, 64, 64);">0.5</font>(水平居中)
  • y比例:<font style="color:rgb(64, 64, 64);">0.2</font>(垂直位置在顶部20%处)
  • 输出文件名:<font style="color:rgb(64, 64, 64);">output.mp4</font>

./merge_videos.sh background.mp4 input1.mp4 640 5 0.5 0.5 0.2 output.mp4

脚本逻辑详解

  1. 位置比例计算
    • 水平位置:<font style="color:rgb(64, 64, 64);">X=(W-w)*$x_ratio</font>
      • <font style="color:rgb(64, 64, 64);">W</font> 是背景视频宽度,<font style="color:rgb(64, 64, 64);">w</font> 是上层视频宽度。
      • <font style="color:rgb(64, 64, 64);">$x_ratio</font> 是水平比例系数(0~1)。
    • 垂直位置:<font style="color:rgb(64, 64, 64);">Y=(H-h)*$y_ratio</font>
      • <font style="color:rgb(64, 64, 64);">H</font> 是背景视频高度,<font style="color:rgb(64, 64, 64);">h</font> 是上层视频高度。
      • <font style="color:rgb(64, 64, 64);">$y_ratio</font> 是垂直比例系数(0~1)。
  2. 动态参数注入
    所有参数(如宽度、透明度、时间偏移、位置比例等)都会动态注入到 FFmpeg 命令中。
  3. 上层视频时长计算
    使用 <font style="color:rgb(64, 64, 64);">ffprobe</font> 提取上层视频时长,确保叠加时间正确。
  4. FFmpeg 滤镜链
    • <font style="color:rgb(64, 64, 64);">scale=$overlay_width:-1</font>:按指定宽度缩放上层视频。
    • <font style="color:rgb(64, 64, 64);">colorchannelmixer=aa=$opacity</font>:设置透明度。
    • <font style="color:rgb(64, 64, 64);">setpts=PTS-STARTPTS+$time_offset/TB</font>:调整上层视频的开始时间。
    • <font style="color:rgb(64, 64, 64);">overlay=X=(W-w)*$x_ratio:Y=(H-h)*$y_ratio</font>:根据比例系数计算实际位置。
    • <font style="color:rgb(64, 64, 64);">enable='gte(t,$time_offset)*lte(t,$duration+$time_offset)'</font>:控制上层视频的显示时间范围。

脚本

#!/bin/bash

# 脚本功能:叠加背景视频和上层视频,支持调整上层视频的宽度、透明度、开始时间、位置比例等参数
# 使用方法:./merge_videos.sh <背景视频> <上层视频> <上层宽度> <时间偏移> <透明度> <x比例> <y比例> <输出文件名>

# 参数说明
# ----------------------------------------------------------------------------------------------
# | 参数名称       | 作用                                                                 |
# ----------------------------------------------------------------------------------------------
# | 背景视频       | 作为背景的视频文件                                                   |
# | 上层视频       | 叠加在上层的视频文件                                                 |
# | 上层宽度       | 上层视频的宽度(高度按比例自适应)                                   |
# | 时间偏移       | 上层视频从第几秒开始显示                                             |
# | 透明度         | 上层视频的透明度(0.0 完全透明,1.0 完全不透明)                     |
# | x比例          | 上层视频的水平位置比例(0=左侧,1=右侧,0.5=居中)                   |
# | y比例          | 上层视频的垂直位置比例(0=顶部,1=底部,0.5=居中)                   |
# | 输出文件名     | 最终生成的视频文件名                                                 |
# ----------------------------------------------------------------------------------------------

# 检查参数数量
if [ "$#" -ne 8 ]; then
    echo "错误:参数数量不正确!"
    echo "使用方法:$0 <背景视频> <上层视频> <上层宽度> <时间偏移> <透明度> <x比例> <y比例> <输出文件名>"
    exit 1
fi

# 从命令行读取参数
background_video=$1      # 背景视频文件名
overlay_video=$2         # 上层视频文件名
overlay_width=$3         # 上层视频宽度
time_offset=$4           # 上层视频开始时间偏移(秒)
opacity=$5               # 上层视频透明度
x_ratio=$6               # 上层视频水平位置比例(0~1)
y_ratio=$7               # 上层视频垂直位置比例(0~1)
output_file=$8           # 输出文件名

# 获取上层视频时长
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$overlay_video")

# 合成视频
ffmpeg -i "$background_video" -i "$overlay_video" \
-filter_complex "
[1:v]scale=$overlay_width:-1,colorchannelmixer=aa=$opacity,format=rgba,setpts=PTS-STARTPTS+$time_offset/TB[fg];
[0:v][fg]overlay=x='(W-w)*$x_ratio':y='(H-h)*$y_ratio':enable='gte(t,$time_offset)*lte(t,$duration+$time_offset)'" \
-c:a copy "$output_file"

# 输出完成信息
echo "视频合成完成!输出文件:$output_file"

http://www.kler.cn/a/580368.html

相关文章:

  • C# BlockingCollection
  • 华为OD机试九日集训第1期 - 按算法分类,由易到难,循序渐进,提升编程能力和解题技巧,从而提高机试通过率
  • Bootstrap:图标库的安装及其使用
  • 如何管理 Facebook 的隐私设置,确保账户安全
  • React-异步队列执行方法useSyncQueue
  • 每天五分钟玩转深度学习PyTorch:基于GoogLeNet完成CAFIR10分类
  • 使用miniforge安装python并用pycharm打开使用
  • Deepseek可以通过多种方式帮助CAD加速工作
  • 网络安全之数据加密(DES、AES、RSA、MD5)
  • Stream流学习
  • 【基于C#实现Bartender多条码打印的示例】
  • 比特币中的相关技术
  • 数据结构(蓝桥杯常考点)
  • 【测试框架篇】单元测试框架pytest(4):assert断言详解
  • 使用Beanshell前置处理器对Jmeter的请求body进行加密
  • uniapp简单table表
  • clickhouse可视化分析工具
  • el-pagination的使用说明
  • 基于STC89C52的4x4矩阵键盘对应键值显示测试
  • 基于Spring Boot的社区老人健康信息管理系统设计与实现(LW+源码+讲解)