python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python FFmpeg视频添加字幕

Python结合FFmpeg实现为视频添加内嵌字幕SRT的完整教程

作者:weixin_46244623

这篇文章主要为大家详细介绍了如何使用 Python 调用 FFmpeg,将 视频文件(MP4)与字幕文件(SRT)进行无损合并,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

摘要

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

一、背景需求

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

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

二、实现原理

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

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

说明:

三、依赖环境

你的系统需要安装:

检查 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

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

七、知识扩展

Python实现json字幕转换为srt字幕

在B站下载了一个英文视频,点开来看,发现没有字幕,又在B站上下了字幕,是json格式的,但我的PotPlayer不支持json格式的字幕,顿时感觉被坑了,上网搜了搜json字幕转换其他字幕格式的工具,结果并没有这种东西,倒是找到了一篇srt字幕转json字幕的博客,反正闲着没事,我就参照着这篇博客用python写了个将json字幕转换为srt字幕的脚本。

先看看json字幕的格式:

from为开始时间,to为结束时间,location是位置,content是字幕内容。

再看看srt字幕的格式:

首先第一行是序号,第二行是开始时间(时:分:秒,小数位,如00:00:02,81就是2.81秒)和终止时间,第三行是字幕文字,后面一定要加上一个空行。

所以我们要做的工作主要就是把json文件的时间格式转换为srt文件的时间格式,另外再把字幕和序号添加上就可以了。

把该程序文件和json字幕文件放在同一文件夹下,运行此程序即可。

代码如下:

import json
import math
import os

for doc in os.listdir():    # 遍历当前文件夹的所有文件
    file = ''  # 这个变量用来保存数据
    i = 1
    if (doc[-4:] == 'json'):    # 若是json文件则进行处理
        name = doc[:-5]     # 提取文件名
        # 将此处文件位置进行修改,加上utf-8是为了避免处理中文时报错
        with open(doc, encoding='utf-8') as f:
            datas = json.load(f)  # 加载文件数据
            f.close()
        for data in datas:
            start = data['from']  # 获取开始时间
            stop = data['to']  # 获取结束时间
            content = data['content']  # 获取字幕内容
            file += '{}\n'.format(i)  # 加入序号
            hour = math.floor(start) // 3600
            minute = (math.floor(start) - hour * 3600) // 60
            sec = math.floor(start) - hour * 3600 - minute * 60
            minisec = int(math.modf(start)[0] * 100)  # 处理开始时间
            file += str(hour).zfill(2) + ':' + str(minute).zfill(2) + ':' + str(sec).zfill(2) + ',' + str(minisec).zfill(2)  # 将数字填充0并按照格式写入
            file += ' --> '
            hour = math.floor(stop) // 3600
            minute = (math.floor(stop) - hour * 3600) // 60
            sec = math.floor(stop) - hour * 3600 - minute * 60
            minisec = abs(int(math.modf(stop)[0] * 100 - 1))  # 此处减1是为了防止两个字幕同时出现
            file += str(hour).zfill(2) + ':' + str(minute).zfill(2) + ':' + str(sec).zfill(2) + ',' + str(minisec).zfill(2)
            file += '\n' + content + '\n\n'  # 加入字幕文字
            i += 1
        with open('./{}.srt'.format(name), 'w', encoding='utf-8') as f:
            f.write(file)  # 将数据写入文件
            f.close()

最后得到的srt文件如图所示:

到此这篇关于Python结合FFmpeg实现为视频添加内嵌字幕SRT的完整教程的文章就介绍到这了,更多相关Python FFmpeg视频添加字幕内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文