batch-file - 尝试使用 ffmpeg 将 wav 与视频文件合并

标签 batch-file audio video ffmpeg wav

这个批处理文件不起作用,我知道 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

最佳答案

主要问题是命令行

For %%a IN ("*.wav") DO Set "FILEWAV=%%~na"
由于上述四个 goto 条件下的命令 if,因此不会在任何视频文件上执行。所以 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 的值,批处理文件也能工作。
默认情况下,Windows XP 和旧版本的 Windows 上不存在可执行文件 timeout.exe。因此, 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 /?

  • 也可以看看:
  • Single line with multiple commands using Windows batch file
  • DosTips 论坛主题:ECHO. FAILS to give text or blank line - Instead use ECHO/

  • 阅读有关 Using command redirection operators 的 Microsoft 文档,了解 >nul2>nul| 的解释。重定向操作符 >| 必须在 FOR 命令行上用脱字符号 ^ 转义,当 Windows 命令解释器在执行命令 FOR FOR FOR FOR FOR _0404070x_70x_0x 嵌入命令之前处理该命令行时,将被解释为文字字符进程在后台启动,dir%ComSpec% /c 中的命令行作为附加参数附加。

    关于batch-file - 尝试使用 ffmpeg 将 wav 与视频文件合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63627133/