ffmpeg+python给目录下的所有mp4文件加上双语字幕

环境

  • 环境变量可以找到ffmpeg
  • PC安装python

原始问题

目录D:\UE_mp4\source下有许多子文件夹,子文件夹中包含很多mp4文件,每个mp4的格式为filename.mp4,并且同目录下可能存在filename.en.srt,filename.srt,如果存在一种字幕文件使用ffmpeg合入到mp4文件里,如果存在两种字幕文件先合并字幕文件再把合并后的字幕文件合入到mp4文件中,
我的PC性能很强,使用10个进程同时处理,
合并后的文件按照原目录结构输出到D:\UE_mp4\test_merge目录下

给出的代码

import os
import shutil
import subprocess
from concurrent.futures import ProcessPoolExecutor

source_dir = r'D:\UE_mp4\source'
target_dir = r'D:\UE_mp4\test_merge'
processes = 10  # 你想要使用的进程数

def combine_subtitles(eng_subtitle, chn_subtitle, combined_subtitle):
    with open(eng_subtitle, 'r', encoding='utf-8') as eng, open(chn_subtitle, 'r', encoding='utf-8') as chn:
        with open(combined_subtitle, 'w', encoding='utf-8') as combined:
            subtitle_number = 1
            while True:
                eng_number = eng.readline()
                chn_number = chn.readline()

                # 判断是否到达文件末尾
                if not eng_number or not chn_number:
                    break

                eng_time = eng.readline()
                chn_time = chn.readline()

                # 读取并合并字幕内容,直到遇到空行
                eng_content = ""
                chn_content = ""
                line = eng.readline()
                while line.strip() != "":
                    eng_content += line
                    line = eng.readline()

                line = chn.readline()
                while line.strip() != "":
                    chn_content += line
                    line = chn.readline()

                # 写入合并后的字幕
                combined.write(f"{subtitle_number}\n")
                combined.write(eng_time)  # 由于时间线应该相同,只写入一次
                combined.write(eng_content)
                combined.write(chn_content)
                combined.write("\n")  # 在字幕块之间添加空行

                subtitle_number += 1

def merge_subtitles_and_video(video_file, subtitle_file, target_file):
    command = [
        'ffmpeg',
        '-i', video_file,
        '-i', subtitle_file,
        '-c', 'copy',
        '-c:s', 'mov_text',  # 使用mov_text选项来编码字幕
        target_file
    ]
    subprocess.run(command, check=True)


def process_video(root, file):
    # 构建视频和可能的字幕文件路径
    video_path = os.path.join(root, file)
    subtitle_en_path = os.path.splitext(video_path)[0] + '.en.srt'
    subtitle_path = os.path.splitext(video_path)[0] + '.srt'
    combined_subtitle_path = os.path.splitext(video_path)[0] + '.combined.srt'
    target_path = root.replace(source_dir, target_dir)

    # 确保目标目录存在
    if not os.path.exists(target_path):
        os.makedirs(target_path)

    # 合并字幕(如果存在两种字幕)
    if os.path.exists(subtitle_en_path) and os.path.exists(subtitle_path):
        combine_subtitles(subtitle_en_path, subtitle_path, combined_subtitle_path)
        subtitle_to_use = combined_subtitle_path
    elif os.path.exists(subtitle_en_path):
        subtitle_to_use = subtitle_en_path
    elif os.path.exists(subtitle_path):
        subtitle_to_use = subtitle_path
    else:
        subtitle_to_use = None

    # 构建目标视频文件路径
    target_video_path = os.path.join(target_path, file)

    # 如果存在字幕文件,则合并
    if subtitle_to_use:
        merge_subtitles_and_video(video_path, subtitle_to_use, target_video_path)
    else:
        # 如果不存在字幕文件,只复制视频文件
        shutil.copy2(video_path, target_video_path)

    # 清理临时合并的字幕文件
    if os.path.exists(combined_subtitle_path):
        os.remove(combined_subtitle_path)


# 遍历源目录并找到所有的视频文件
def main():
    with ProcessPoolExecutor(max_workers=processes) as executor:
        for root, dirs, files in os.walk(source_dir):
            for file in files:
                if file.lower().endswith('.mp4'):
                    executor.submit(process_video, root, file)


if __name__ == '__main__':
    main()

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值