首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将多个mp4文件合并为最终mp4中的章节?

如何将多个mp4文件合并为最终mp4中的章节?
EN

Unix & Linux用户
提问于 2023-05-08 00:32:23
回答 1查看 79关注 0票数 0

我有一个文件夹,文件名叫0001.mp40002.mp4,.我希望将所有这些文件合并到一个combined.mp4中,并且希望它有一个内部章节标记。例如,在vlc中播放时非常方便,因为您可以在时间线中看到章节名称。

我怎么能做出这样的combined.mp4呢?最好是使用ffmpeg命令行脚本,而不需要额外的依赖项。

相似的问题,但提问者想要使用手闸。

EN

回答 1

Unix & Linux用户

发布于 2023-05-08 00:32:23

章节信息存储在文件元数据中。Ffmpeg允许将元数据导出到文件,并从文件中加载元数据。文档在这里:元数据1

现在我们需要准备一个元数据文件,用于combined.mp4。我们可以一次完成这个任务,不需要先从所有文件生成组合文件,然后再用注入的元数据创建另一个文件。我们节省了存储空间。

我制作了一个python脚本multiple_mp4_to_single_mp4_with_chapters.py,它完成了以下工作:

代码语言:javascript
复制
import subprocess
import os
import re


def make_chapters_metadata(list_mp4: list):
    print(f"Making metadata source file")

    chapters = {}
    for single_mp4 in list_mp4:
        number = single_mp4.removesuffix(".mp4")
        duration_in_microseconds = int((subprocess.run(f"ffprobe -v quiet -of csv=p=0 -show_entries format=duration {folder}/{single_mp4}", shell=True, capture_output=True).stdout.decode().strip().replace(".", "")))
        chapters[number] = {"duration": duration_in_microseconds}

    chapters["0001"]["start"] = 0
    for n in range(1, len(chapters)):
        chapter = f"{n:04d}"
        next_chapter = f"{n + 1:04d}"
        chapters[chapter]["end"] = chapters[chapter]["start"] + chapters[chapter]["duration"]
        chapters[next_chapter]["start"] = chapters[chapter]["end"] + 1
    last_chapter = f"{len(chapters):04d}"
    chapters[last_chapter]["end"] = chapters[last_chapter]["start"] + chapters[last_chapter]["duration"]

    metadatafile = f"{folder}/combined.metadata.txt"
    with open(metadatafile, "w+") as m:
        m.writelines(";FFMETADATA1\n")
        for chapter in chapters:
            ch_meta = """
[CHAPTER]
TIMEBASE=1/1000000
START={}
END={}
title={}
""".format(chapters[chapter]["start"], chapters[chapter]["end"], chapter)
            m.writelines(ch_meta)


def concatenate_all_to_one_with_chapters():
    print(f"Concatenating list of mp4 to combined.mp4")
    metadatafile = f"{folder}/combined.metadata.txt"
    os.system(f"ffmpeg -hide_banner -loglevel error -y -f concat -i list_mp4.txt -i {metadatafile} -map_metadata 1 combined.mp4")

if __name__ == '__main__':

    folder = "."  # Specify folder where the files 0001.mp4... are

    list_mp4 = [f for f in os.listdir(folder) if re.match(r'[0-9]{4}\.mp4', f)]
    list_mp4.sort()

    # Make the list of mp4 in ffmpeg format
    if os.path.isfile("list_mp4.txt"):
        os.remove("list_mp4.txt")
    for filename_mp4 in list_mp4:
        with open("list_mp4.txt", "a") as f:
            line = f"file '{filename_mp4}'\n"
            f.write(line)

    make_chapters_metadata(list_mp4)
    concatenate_all_to_one_with_chapters()

现在您可以将它与您的mp4文件放在文件夹中(或在脚本中编辑folder变量),并运行它:

代码语言:javascript
复制
$ ls
0001.mp4 0002.mp4 0003.mp4 0004.mp4 multiple_mp4_to_single_mp4_with_chapters.py
$ python multiple_mp4_to_single_mp4_with_chapters.py

现在您将拥有combined.mp4,当它在vlc中打开时,您将看到章节标记。

我在bash上看到了一个脚本,它使用mp4box和mp4chaps:这个要旨也有bash版本,没有这样的依赖关系:这个要旨和python上的另一个版本,但是它创建了两次合并文件:这个要旨

票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/745238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档