【问题标题】:Trying to merge wav with video file using ffmpeg尝试使用 ffmpeg 将 wav 与视频文件合并
【发布时间】:2020-08-28 03:42:50
【问题描述】:

这个批处理文件不起作用,我知道 ffmpeg 命令在单独运行时起作用。

我使用的 WAV 文件与视频的长度完全相同(它是从我尝试添加回的视频中提取的)。

如果我从 ffmpeg.exe 和批处理文件所在的文件夹中删除 wav 和/或视频文件,NOAUDIO 和 NOVIDEO 标签会正常工作。

当批处理文件与 wav 音频和 mp4 视频文件一起运行时,它只会闪现一个命令窗口。我尝试在每个命令后暂停,但仍然没有乐趣。

这里有错误吗?

各位干杯...

:: --------------------
::
:: This will put any included WAV file with any included
:: video file, assuming the video file type exists:
::
:: - AVI
:: - MKV
:: - MP4
:: - WEBM
::
:: --------------------

@echo off
title Replace Video Audio with WAV
color 0f

:: --------------------

if not exist *.wav goto NOAUDIO
if not exist *.avi if not exist *.mkv if not exist *.mp4 if not exist *.webm goto NOVIDEO

:: --------------------

if exist *.avi goto AVIFILE
if exist *.mkv goto MKVFILE
if exist *.mp4 goto MP4FILE
if exist *.webm goto WEBMFILE

:: --------------------

For %%a IN ("*.wav") DO Set "FILEWAV=%%~na"

:: --------------------

:AVIFILE
For %%a IN ("*.avi") DO Set "FILEAVI=%%~na"
start /wait ffmpeg.exe -i "%FILEAVI%.avi" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEAVI%-NEW.mp4"
goto FINISHED

:MP4FILE
For %%a IN ("*.mp4") DO Set "FILEMP4=%%~na"
start /wait ffmpeg.exe -i "%FILEMP4%.mp4" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEMP4%-NEW.mp4"
goto FINISHED

:WEBMFILE
For %%a IN ("*.webm") DO Set "FILEWEBM=%%~na"
start /wait ffmpeg.exe -i "%FILEWEBM%.webm" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEWEBM%-NEW.mp4"
goto FINISHED

:MKVFILE
For %%a IN ("*.mkv") DO Set "FILEMKV=%%~na"
start /wait ffmpeg.exe -i "%FILEMKV%.mkv" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEMKV%-NEW.mp4"
goto FINISHED

:: --------------------

:NOAUDIO
cls
echo.
echo.
echo    There is no audio to put with the video!
echo.
echo    Exiting...
timeout 6 >nul
goto FINISHED

:: --------------------

:NOVIDEO
cls
echo.
echo.
echo    There is no video to put audio with!
echo.
echo    Exiting...
timeout 6 >nul
goto FINISHED

:: --------------------

:FINISHED
exit

:: --------------------

我刚刚对此进行了测试,它确实有效,使用与上述批处理文件中完全相同的命令,只是删除了所有标签...

For %%a IN ("*.wav") DO Set FILEWAV=%%~na

:MP4FILE
For %%a IN ("*.mp4") DO Set FILEMP4=%%~na
start /wait ffmpeg.exe -i "%FILEMP4%.mp4" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEMP4%-NEW.mp4"
goto FINISHED

:FINISHED
exit

所以我知道它不起作用的原因与批处理文件的运行顺序有关。这很奇怪,因为我有另一个批处理文件,就像它首先用于提取 WAV 并且确实有效,标签的设置就像上面的第一个批处理文件一样。令人困惑。

如果我把它简化为这个,它会起作用......

For %%a IN ("*.wav") DO Set FILEWAV=%%~na

For %%a IN ("*.avi") DO Set FILEAVI=%%~na
start /wait ffmpeg.exe -i "%FILEAVI%.avi" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEAVI%-NEW.mp4"

For %%a IN ("*.mp4") DO Set FILEMP4=%%~na
start /wait ffmpeg.exe -i "%FILEMP4%.mp4" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEMP4%-NEW.mp4"

For %%a IN ("*.webm") DO Set FILEWEBM=%%~na
start /wait ffmpeg.exe -i "%FILEWEBM%.webm" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEWEBM%-NEW.mp4"

For %%a IN ("*.mkv") DO Set FILEMKV=%%~na
start /wait ffmpeg.exe -i "%FILEMKV%.mkv" -i "%FILEWAV%.wav" -c:v copy -map 0:v:0 -map 1:a:0 "%FILEMKV%-NEW.mp4"

exit

【问题讨论】:

    标签: batch-file audio video ffmpeg wav


    【解决方案1】:

    主要问题是命令行

    For %%a IN ("*.wav") DO Set "FILEWAV=%%~na"
    

    由于上述四个if 条件下的命令goto,永远不会对找到的任何视频文件执行。因此,ffmpeg.exe 命令行之一是使用环境变量 FILEWAV 执行的,很可能根本没有定义,至少批处理文件没有定义。

    批处理文件可以改进为:

    @echo off
    :: --------------------
    ::
    :: This will put any included WAV file with any included
    :: video file, assuming the video file type exists:
    ::
    :: - AVI
    :: - MKV
    :: - MP4
    :: - WEBM
    ::
    :: --------------------
    
    setlocal EnableExtensions DisableDelayedExpansion
    title Replace Video Audio with WAV
    color 0f
    
    if not exist %SystemRoot%\System32\where.exe goto CheckAudio
    %SystemRoot%\System32\where.exe ffmpeg.exe >nul 2>nul
    if not errorlevel 1 goto CheckAudio
    echo/
    echo/
    echo    There is ffmpeg.exe not found in current directory or
    echo    any directory defined in environment variable PATH!
    echo/
    if exist %SystemRoot%\System32\timeout.exe (echo    Exiting...& %SystemRoot%\System32\timeout.exe 6 >nul) else pause
    goto FINISHED
    
    if exist *.wav goto ProcessVideo
    cls
    echo/
    echo/
    echo    There is no audio to put with the video!
    echo/
    if exist %SystemRoot%\System32\timeout.exe (echo    Exiting...& %SystemRoot%\System32\timeout.exe 6 >nul) else pause
    goto FINISHED
    
    :ProcessVideo
    rem Get file name of (last) WAV file in current directory.
    for %%I in (*.wav) do set "AudioFile=%%I"
    
    rem Process all AVI, MKV, MP4 and WBEM video files in current directory.
    set "NoVideo=1"
    for /F "eol=| delims=" %%# in ('dir *.avi *.mkv *.mp4 *.webm /A-D /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /E /L /V /C:"-new.mp4"') do ffmpeg.exe -i "%%#" -i "%AudioFile%" -c:v copy -map 0:v:0 -map 1:a:0 "%%~n#-NEW.mp4" & set "NoVideo="
    if not defined NoVideo goto FINISHED
    
    cls
    echo/
    echo/
    echo    There is no video to put audio with!
    echo/
    if exist %SystemRoot%\System32\timeout.exe (echo    Exiting...& %SystemRoot%\System32\timeout.exe 6 >nul) else pause
    
    :FINISHED
    color
    endlocal
    

    FOR 命令支持使用多个通配符搜索文件名,例如命令DIR。因此,批处理文件不需要对每种类型的视频文件格式使用几乎相同的代码来支持。修改会导致处理当前目录中的所有视频文件,而不仅仅是最后一个,除了视频文件名已经以 -NEW 结尾不区分大小写。

    字符a 是循环变量的修饰符。尽管如此,它仍可以用作循环变量,但最好将永远不会被解释为修饰符的字符用作循环变量。上面的批处理文件使用一次I 和一次# 作为循环变量来证明这一点。

    start /wait 根本没有必要。默认情况下,Windows 命令处理器cmd.exe 等待从批处理文件中启动的任何可执行文件的自终止,否则timeout.exe 的执行将无法按预期工作。因此ffmpeg.exe 可以在不使用命令start 及其选项/wait 的情况下运行。

    批处理文件末尾的命令exit 总是无用的。对于批处理文件的开发人员而言,debug the batch file 变得更加困难,并且它存在于批处理文件末尾而没有任何参数对于从命令提示符窗口中执行批处理文件的批处理文件用户或用户来说适得其反想要从另一个批处理文件多次调用批处理文件,例如在循环中。

    最好在批处理文件中指定带有完整限定文件名的Windows Command,以使批处理文件尽可能独立于PATHPATHEXT。然后,Windows 命令处理器不需要搜索可执行文件并且批处理文件可以工作,即使用户以某种方式破坏了环境变量 PATH 的值。

    默认情况下,可执行文件timeout.exe 在 Windows XP 和旧版本的 Windows 上不存在。因此,IF 条件用于在 Windows Vista 和较新版本的 Windows 上使用 timeout.exe,在较旧版本的 Windows 上使用 pause

    要了解所使用的命令及其工作原理,请打开command prompt 窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • cls /?
    • color /?
    • dir /?
    • echo /?
    • endlocal /?
    • findstr /?
    • for /?
    • goto /?
    • if /?
    • pause /?
    • rem /?
    • set /?
    • setlocal /?
    • timeout /?
    • title /?
    • where /?

    另见:

    阅读有关Using command redirection operators 的Microsoft 文档,了解>nul2>nul|。重定向运算符 >| 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令之前处理此命令行时将其解释为文字字符 FOR 在单独的命令进程中执行嵌入的 dir 命令行,该进程在后台启动,%ComSpec% /c' 中的命令行作为附加参数附加。

    【讨论】:

    • 干杯 Mofi,我给了答案并使用您在某个时候给出的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多