如何解决尝试使用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,以使批处理文件尽可能独立于PATH
和PATHEXT
。这样,即使用户以某种方式破坏了环境变量PATH
的值,Windows命令处理器也不需要搜索可执行文件,并且批处理文件也可以工作。
在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文档,以获取>nul
,2>nul
和|
的解释。重定向操作符>
和|
在Windows命令行解释器处理此命令行时,必须在 FOR 命令行上使用脱字符号^
进行转义,以将其解释为文字字符。在执行命令 FOR 之前,该命令将在后台以dir
开始的单独命令过程中执行嵌入的%ComSpec% /c
命令行,并将'
中的命令行附加为附加参数
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。