Python 使用 FFmpeg 给视频添加内嵌字幕(SRT)完整教程(含代码示例)

📌 摘要

本文介绍如何使用 Python 调用 FFmpeg,将 视频文件(MP4)与字幕文件(SRT)进行无损合并,并输出带字幕的新视频。文中提供了完整可运行的 Python 脚本,包括文件校验、FFmpeg 调用、错误处理等。适用于想要批量合并视频 + 字幕、制作教学视频、课程字幕嵌入等场景。

🎯 一、背景需求

在视频编辑、课程制作、影视处理等场景中,我们经常需要:

  • 下载的视频没有内嵌字幕

  • 手里有 .srt 字幕文件

  • 需要把字幕"封装"到 .mp4 里(但不烧录,只是内封)

使用 FFmpeg 可以轻松做到,而 Python 则可以让流程自动化、批量化。


🔧 二、实现原理

FFmpeg 提供了丰富的视频/音频/字幕处理功能,这里我们用到:

复制代码
ffmpeg -i video.mp4 -i subtitle.srt -c:v copy -c:a copy -c:s mov_text output.mp4

说明:

  • -c:v copy:不重新编码视频(无损、快速)

  • -c:a copy:不重新编码音频

  • -c:s mov_text:将 SRT 封装为 MP4 支持的字幕格式

  • 使用 Python 的 subprocess.run() 调用 FFmpeg


📦 三、依赖环境

你的系统需要安装:

✔ Python 3.x

✔ FFmpeg(必需)

检查 FFmpeg 是否安装:

复制代码
复制代码
ffmpeg -version

没有安装请到官网或使用包管理工具安装。


🧩 四、完整 Python 代码(含中文注释)

下面是可直接运行的脚本,已加上完整中文说明,适合新手和入门 FFmpeg/Python 的读者:


复制代码
import subprocess
import os
import sys

def validate_file(file_path, file_type="file"):
    """验证文件是否存在"""
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"{file_type.capitalize()} 文件不存在: {file_path}")
    print(f"{file_type.capitalize()} 已验证: {file_path}")
    return True


def merge_video_with_subtitles(video_path, srt_path, output_path):
    """使用 FFmpeg 将视频与 SRT 字幕合并"""

    # 1. 验证输入文件
    validate_file(video_path, "video")
    validate_file(srt_path, "subtitle")

    # 2. FFmpeg 指令
    ffmpeg_cmd = [
        'ffmpeg',
        '-i', video_path,     # 输入视频
        '-i', srt_path,       # 输入字幕
        '-c:v', 'copy',       # 视频无损copy
        '-c:a', 'copy',       # 音频无损copy
        '-c:s', 'mov_text',   # 字幕转换为 mp4 可识别格式
        '-metadata:s:s:0', 'language=chi',  # 字幕语言设置为中文
        output_path
    ]

    # 强制字幕按 UTF-8 解码(避免乱码)
    ffmpeg_cmd.insert(3, '-sub_charenc')
    ffmpeg_cmd.insert(4, 'UTF-8')

    try:
        # 3. 调用 FFmpeg 进行处理
        result = subprocess.run(
            ffmpeg_cmd,
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        print(f"成功生成视频: {output_path}")
        print(result.stdout)

    except subprocess.CalledProcessError as e:
        print(f"FFmpeg 处理失败: {e.stderr}")
        raise
    except Exception as e:
        print(f"运行 FFmpeg 时发生异常: {e}")
        raise


def main():
    # 输入文件路径(可自行修改)
    video_path = r"SS.online_Gesture Drawing Practice _ 20 and 40 sec. poses_1080p.mp4"
    srt_path = r"SS.online_Gesture Drawing Practice _ 20 and 40 sec. poses_1080p.srt"
    output_path = "output.mp4"

    # 合并视频 + 字幕
    merge_video_with_subtitles(video_path, srt_path, output_path)


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(f"程序错误: {e}")
        sys.exit(1)

▶️ 五、运行方式

直接:

复制代码
python merge.py

执行完成后,将生成:

复制代码
output.mp4

用任意播放器(如 VLC)打开 → 字幕即可选择显示。


📝 六、说明与注意事项

1. 字幕不会"烧录"

此方法是 内封字幕(soft subtitle),播放器可以选择开启/关闭。

2. 字幕乱码?

可尝试:

复制代码
-sub_charenc UTF-8

代码中已自动加入该选项。

3. 多字幕?

支持。可扩展代码进行批量字幕封装。

4. 输出文件不会重新压制视频

因为:

复制代码
-c:v copy -c:a copy

速度极快(几秒内完成)。

相关推荐
火车叼位4 分钟前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
孤狼warrior14 分钟前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Katecat9966324 分钟前
YOLO11分割算法实现甲状腺超声病灶自动检测与定位_DWR方法应用
python
玩大数据的龙威1 小时前
农经权二轮延包—各种地块示意图
python·arcgis
ZH15455891311 小时前
Flutter for OpenHarmony Python学习助手实战:数据库操作与管理的实现
python·学习·flutter
belldeep1 小时前
python:用 Flask 3 , mistune 2 和 mermaid.min.js 10.9 来实现 Markdown 中 mermaid 图表的渲染
javascript·python·flask
喵手1 小时前
Python爬虫实战:电商价格监控系统 - 从定时任务到历史趋势分析的完整实战(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·电商价格监控系统·从定时任务到历史趋势分析·采集结果sqlite存储
喵手1 小时前
Python爬虫实战:京东/淘宝搜索多页爬虫实战 - 从反爬对抗到数据入库的完整工程化方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·京东淘宝页面数据采集·反爬对抗到数据入库·采集结果csv导出
凉辰1 小时前
使用uni.createInnerAudioContext()播放指定音频(踩坑分享功能)
开发语言·javascript·音视频
B站_计算机毕业设计之家2 小时前
猫眼电影数据可视化与智能分析平台 | Python Flask框架 Echarts 推荐算法 爬虫 大数据 毕业设计源码
python·机器学习·信息可视化·flask·毕业设计·echarts·推荐算法