运维日志您现在的位置是:首页 > 博客日志 > 运维日志

从.m3u8到.mp4:使用批处理脚本完成视频处理的完整指南

<a href='mailto:'>微wx笑</a>的头像微wx笑 2025-02-23运维日志 0 0关键字: m3u8  mp4  bat  批处理  

这里介绍一个Windows批处理脚本(Windows Batch Script),主要用于处理 .m3u8 ts 视频文件的下载和合并功能。以下是程序的主要功能和逻辑流程:功能概述参数检查与路径处理: 检查

无知人生,ivu4e.com,ivu4e.cn

这里介绍一个Windows批处理脚本(Windows Batch Script),主要用于处理 .m3u8 ts 视频文件的下载和合并功能。bSX无知


bSX无知

以下是程序的主要功能和逻辑流程:bSX无知

功能概述

  1. bSX无知

  2. bSX无知

    参数检查与路径处理bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      检查是否传递了文件或文件夹路径作为参数。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      判断传递的路径是文件还是文件夹,并根据路径切换到相应的目录。bSX无知

      bSX无知

    • bSX无知

  3. bSX无知

  4. bSX无知

    文件处理逻辑bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      如果目标目录中存在 .m3u8 文件(如 index.m3u8 或以当前目录名命名的 .m3u8 文件),程序会解析该文件。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      根据 .m3u8 文件中的内容,提取有效的文件链接(如 .ts 文件的 URL)。bSX无知

      bSX无知

    • bSX无知

  5. bSX无知

  6. bSX无知

    文件下载bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      使用 aria2c 工具批量下载 .m3u8 文件中列出的文件(如 .ts 文件)。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      下载的文件会保存到当前目录。bSX无知

      bSX无知

    • bSX无知

  7. bSX无知

  8. bSX无知

    文件合并bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      使用 ffmpeg 将下载的文件片段(如 .ts 文件)合并为一个完整的视频文件(如 .mp4 文件)。bSX无知

      bSX无知

    • bSX无知

  9. bSX无知

  10. bSX无知

    清理操作bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      提供选项删除下载的片段文件、临时文件(如 newindex.m3u8links.list 等)。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      根据用户选择,保留或删除这些文件。bSX无知

      bSX无知

    • bSX无知

  11. bSX无知

  12. bSX无知

    错误处理与用户交互bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      检查目标文件是否已存在,并提示用户是否需要重新生成。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果 .m3u8 文件或目标文件已存在,程序会询问用户是否覆盖。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果下载或合并过程中出现错误,程序会提示用户。bSX无知

      bSX无知

    • bSX无知

详细逻辑流程

  1. bSX无知

  2. bSX无知

    参数检查bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      如果未传递参数,程序提示用户并退出。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果传递了参数,程序会判断路径是文件还是文件夹。bSX无知

      bSX无知

    • bSX无知

  3. bSX无知

  4. bSX无知

    目录切换bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      如果路径是文件夹,程序切换到该文件夹。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果路径是文件,程序切换到文件所在的目录。bSX无知

      bSX无知

    • bSX无知

  5. bSX无知

  6. bSX无知

    解析 .m3u8 文件bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      程序会尝试解析 index.m3u8 或以当前目录名命名的 .m3u8 文件。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      提取文件链接(如 .ts 文件的 URL)并保存到 links.list 文件中。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果 .m3u8 文件中包含加密信息(如 AES-128 密钥链接),程序会提取并处理这些链接。bSX无知

      bSX无知

    • bSX无知

  7. bSX无知

  8. bSX无知

    文件下载bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      使用 aria2c 根据 links.list 文件中的链接批量下载文件。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      下载的文件会保存到当前目录。bSX无知

      bSX无知

    • bSX无知

  9. bSX无知

  10. bSX无知

    文件合并bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      使用 ffmpeg 将下载的文件片段(如 .ts 文件)合并为一个 .mp4 文件。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      提供多种 ffmpeg 命令选项,用户可以根据需要选择合适的命令。bSX无知

      bSX无知

    • bSX无知

  11. bSX无知

  12. bSX无知

    清理操作bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      提供选项删除下载的片段文件、临时文件(如 newindex.m3u8links.list 等)。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      用户可以选择保留或删除这些文件。bSX无知

      bSX无知

    • bSX无知

  13. bSX无知

  14. bSX无知

    错误处理与用户交互bSX无知

    bSX无知

    • bSX无知

    • bSX无知

      如果目标文件已存在,程序会提示用户是否重新生成。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果 .m3u8 文件或目标文件已存在,程序会询问用户是否覆盖。bSX无知

      bSX无知

    • bSX无知

    • bSX无知

      如果下载或合并过程中出现错误,程序会提示用户。bSX无知

      bSX无知

    • bSX无知

应用场景

  • bSX无知

  • bSX无知

    该脚本主要用于处理视频片段的下载和合并,通常用于处理 .m3u8 格式的视频文件(如在线视频、直播回放等)。bSX无知

    bSX无知

  • bSX无知

  • bSX无知

    用户可以通过传递文件或文件夹路径作为参数,让脚本自动完成下载和合并操作。bSX无知

    bSX无知

  • bSX无知

  • bSX无知

    脚本提供了用户交互功能,允许用户根据需要选择是否覆盖文件或删除临时文件。bSX无知

    bSX无知

注意事项

  • bSX无知

  • bSX无知

    程序依赖于外部工具 aria2cffmpeg,需要确保这些工具已安装并配置在系统路径中。bSX无知

    bSX无知

  • bSX无知

  • bSX无知

    程序的逻辑较为复杂,涉及文件路径处理、文件下载、文件合并等多个步骤,需要谨慎使用。bSX无知

    bSX无知

  • bSX无知

  • bSX无知

    用户在运行脚本时需要确保传递的参数正确,否则可能导致程序无法正常运行。bSX无知

    bSX无知

完整的程序代码bSX无知

 bSX无知

@echo off
echo 正在处理文件:%~1
rem ~可以确保获取到的参数不包含多余的引号
rem 判断是否传递了参数
if "%~1"=="" (
    echo 未传递任何参数,请提供文件或文件夹路径。
    exit /b 1
)

rem 获取参数的属性
set "attribute=%~a1"
set "fpath=%~1"

rem 判断是否为文件夹
if "%attribute:~0,1%"=="d" (
    echo "%~1 是一个文件夹目录。"
    rem 这里可以添加处理文件夹的逻辑
    rem set "fpath=%~1"
) else if "%attribute:~0,1%"=="-" (
    echo "%~1 是一个文件路径。"
    rem 这里可以添加处理文件的逻辑
    set "fpath=%~dp1"
) else (
    echo "无法识别 %~1 是文件还是文件夹。"
    exit /b 1
)

echo 切换目录到 "%fpath%"
pushd "%fpath%"
if errorlevel 1 (
    echo "Error: Directory %~1 not found."
    pause
    exit /b
)
for %%i in (.) do set "curr=%%~ni"
echo "使用最后一级目录 %curr% 作为文件名"

rem 判断文件是否存在,如果存在询问用户是否删除重新生成
setlocal enableextensions enabledelayedexpansion

rem 检查 index.m3u8 文件是否存在
rem set "m3u8=index.m3u8"
set "m3u8=%curr%.m3u8"
if not exist "!m3u8!" (
    set "m3u8=index.m3u8"
)
echo "!m3u8!"

rem if exist "%curr%.mp4" (del /f "%curr%.mp4")
rem 定义目标文件路径,你可以根据实际情况修改

set "target_file=%curr%.mp4"

rem 检查目标文件是否存在
if exist "%target_file%" (

    :ask_user
    set /p "choice=目标文件 %target_file% 已存在,是否重新生成?(Y/N)(回车=是): "
    :: 检测用户输入
    if /i "!choice!"=="" (
        set "choice=Y" :: 如果用户直接回车,则设置默认值为 Y
    )
    if /i "!choice!"=="Y" (
        rem 用户选择重新生成,删除原有文件
        del /f "%target_file%"
        echo "已删除原有文件 %target_file%。"
    ) else if /i "!choice!"=="N" (
        echo 你选择不重新生成,程序将退出。
        goto ask_user3
        pause
        exit /b
    ) else (
        echo 无效的输入,请输入 Y 或 N。
        goto ask_user
    )
)


rem 如果 newindex.m3u8 文件存在则直接合并文件
if exist "newindex.m3u8" (
    :ask_user2
    set /p "choice=目标文件 newindex.m3u8 已存在,是否重新生成?(Y/N)(回车=是): "
    echo !choice!
    :: 检测用户输入
    if /i "!choice!"=="" (
        set "choice=Y" :: 如果用户直接回车,则设置默认值为 Y
    )
    if /i "!choice!"=="Y" (
        rem 用户选择重新生成,删除原有文件
        del /f newindex.m3u8
        del /f links.list
        echo 已删除原有文件 newindex.m3u8。
    ) else if /i "!choice!"=="N" (
        echo 你选择不重新生成,直接跳转到合并过程。
        goto ffmpeg_merge
    ) else (
        echo 无效的输入,请输入 Y 或 N。
        goto ask_user2
    )
)

set /a b=0
set /a fn=0
rem 遍历 index.m3u8 文件的每一行
for /f "usebackq delims=" %%a in ("!m3u8!") do (
    rem 去除可能的引号
    set "url=%%a"
    set "url=!url:"=!"
    
    rem 判断 url 是否为有效的文件链接(简单判断是否以 http 或 https 开头)
    if "!url:~0,4!"=="http" (
        rem 提取文件名
        for %%f in ("!url!") do set "filename=%%~nxf"
        if exist "!filename!" (
            rem 判断文件大小 for /f %%i in ('dir /b %%a') do if 0 lss %%~zi (echo file %%a >> newindex.m3u8)
            echo !filename! 文件已存在!
        ) else (
            echo !url! >> links.list
        )
        echo !filename! >> newindex.m3u8
    ) else (
        if "!b!"=="0" (
            if "!url:~0,30!"=="#EXT-X-KEY:METHOD=AES-128,URI=" (
                echo "!url!"
                set "uri=!url:~30!"
                set "uri=!uri:"=!"
                echo "uri=!uri!"
                if "!uri:~0,4!"=="http" (
                    if not exist "!uri!" (
                        echo !uri! >> links.list
                    )
                    set /a b+=1
                    echo #EXT-X-KEY:METHOD=AES-128,URI=key.key >> newindex.m3u8
                    rem 输出提取到的 URI
                    echo 提取到的 URI 是: !uri!
                    
                )
            )
            
            if "!b!"=="0" (
                rem echo !url! 不是有效的文件链接,跳过
                echo !url! >> newindex.m3u8
            )
        ) else (
            rem echo !url! 不是有效的文件链接,跳过
            echo .
            echo !url! >> newindex.m3u8
        )
    )
    set /a fn+=1
)

rem 设置包含下载链接的文本文件路径
set "links_file=links.list"
rem 设置下载文件保存的目录
set "download_dir=%cd%"
if exist "%links_file%" (
    rem 调用 aria2c 批量下载文件
    aria2c -i "%links_file%" -d "%download_dir%" -x 16 -s 8 -j 10 -c
    echo 调用 aria2c 批量下载完成!
)

:ffmpeg_merge
rem 如果 key.key 文件不存在,ffmpeg 不会报错,会继续执行
echo ffmpeg merge begin

ffmpeg -protocol_whitelist "file,crypto" -allowed_extensions ALL -threads auto -i "newindex.m3u8" -c copy -bsf:a aac_adtstoasc "%curr%.mp4"
rem ffmpeg -protocol_whitelist "file,crypto" -allowed_extensions ALL -i "newindex.m3u8" -c copy -bsf:a aac_adtstoasc "output.mp4"
rem ffmpeg -protocol_whitelist "file,crypto" -allowed_extensions ALL -threads auto -i "newindex.m3u8" -c copy "%curr%.mp4"
rem ffmpeg -protocol_whitelist "file,crypto" -allowed_extensions ALL -i "newindex.m3u8" -c:v libx264 -c:a aac "%curr%.mp4"
rem ffmpeg -f concat -safe 0 -protocol_whitelist "file,concat" -i newindex.m3u8 -c copy %curr%.mp4
if errorlevel 1 (
    echo Error: ffmpeg failed to merge files.
) else (
    echo "%curr%.mp4 合并成功!"
    :ask_user3
    set /p "choice=是否删除下载的切片文件?(Y/N)(回车=Y): "
    echo "!choice!"
    :: 检测用户输入
    if /i "!choice!"=="" (
        set "choice=Y" :: 如果用户直接回车,则设置默认值为 Y
    )
    if /i "!choice!"=="Y" (
        rem 用户选择重新生成,删除原有文件
        
        echo "!m3u8!"
        del /f *.ts
        rem 遍历 index.m3u8 文件的每一行
        for /f "usebackq delims=" %%a in ("!m3u8!") do (
            rem 去除可能的引号
            set "url=%%a"
            set "url=!url:"=!"
            rem 判断 url 是否为有效的文件链接(简单判断是否以 http 或 https 开头)
            if "!url:~0,4!"=="http" (
                rem 提取文件名
                for %%f in ("!url!") do set "filename=%%~nxf"
                echo !filename!
                if exist "!filename!" (
                    del /f "!filename!"
                )
            )
        )
        if exist "newindex.m3u8" (
            del /f newindex.m3u8
        )
        if exist "links.list" (
            del /f links.list
        )
        if exist "index.html" (
            del /f index.html
        )
        if exist "index.m3u8" (
            del /f index.m3u8
        )
        if exist "index.1.html" (
            del /f index.1.html
        )
        if exist "url.txt" (
            del /f url.txt
        )
        if exist "!m3u8!" (
            del /f "!m3u8!"
        )
        
    ) else if /i "!choice!"=="N" (
        echo 你选择不删除,程序即将退出!
        exit /b 0
    ) else (
        echo 无效的输入,请输入 Y 或 N。
        goto ask_user3
    )
)

endlocal
pause

如何使用呢?bSX无知

将以上内容保存为 “ts2mp4.bat”,放在系统目录下,比如:C:\Windows,这样你就可以在任何一个目录调用它了;bSX无知


bSX无知

首先你得知道如何拿到视频的 .m3u8 文件的URL地址 ,下载到本地;bSX无知

然后就可以使用上面的bat下载ts切片并合并为 mp4视频文件了,例如: ts2mp4 index.m3u8bSX无知

 你也可以将以下内容导入注册表:bSX无知

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\VLC.m3u8\shell\ts2mp4\command]
@="ts2mp4.bat \"%1\""

这样在  .m3u8 文件上点击鼠标右键时,就可以通过右键菜单的形成调用  ts2mp4 了;bSX无知

该程序目前还存在一个问题 :如果  .m3u8 文件中的ts切片url地址是相对的,不是完整的url的话,无法实现下载;bSX无知

编写该bat文件遇到的坑:bSX无知

echo 后面输出的内容中有变量(并且变量中包含特殊字符,比如小括号)的情况必须使用双引号将输出内容括起来,否则即使程序没有执行到那一行,而是执行到那个程序块的话也是会报错停止执行,这给查找问题发生的位置带来不小的麻烦bSX无知

bat的字符查找功能比较弱,要要找字符串的话实现起来比较麻烦;bSX无知


bSX无知

无知人生,ivu4e.com,ivu4e.cn

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/service/2025-02-23/2029.html

很赞哦! () 有话说 ()