我需要将子目录中的所有MP4文件转换为MKV。所以我写了这个剧本:
@ECHO OFF
SET oldName=
SET newName=
FOR /r %%A IN (*.mp4) DO (
SET oldName=%%A
SET newName=%%A
CALL :MAKEMKV
)
:MAKEMKV
SET newName=%newName:mp4=mkv%
IF NOT EXIST %newName% (
START /B /WAIT ffmpeg -i "%oldName%" -map 0 -map -0:s -codec copy "%newName%"
)
问题是只转换文件夹中的第一个文件,然后退出。但我使用for do
循环。所以我无法理解为什么退出。
我的结构是:
/FOLDER
../A/filea.mp4
../B/fileb.mp4
../C/filec.mp4
当我在程序之上运行时,我只会将filea.mp4
转换为filea.mkv
并退出脚本
其他文件fileb.mp4
和filec.mp4
不会被批处理文件转换。
我缺少什么?
答案 0 :(得分:2)
使用修饰符(参见for /?
或call /?
),这基本上是一个单行词:
@ECHO OFF
FOR /r %%A IN (*.mp4) DO (
if not exist "%~dpnA.mkv" (
START /B /WAIT ffmpeg -i "%%~A" -map 0 -map -0:s -codec copy "%%~dpnA.mkv"
)
)
(为了更好的可读性而写成多行)
未使用ffmpeg
,但可能您不需要使用start
命令:
@ECHO OFF
FOR /r %%A IN (*.mp4) DO (
if not exist "%~dpnA.mkv" (
ffmpeg -i "%%~A" -map 0 -map -0:s -codec copy "%%~dpnA.mkv" && del "%%~A"
)
)
如果转化成功,还添加了删除原始mp4
的代码。
答案 1 :(得分:1)
在命令提示符窗口for /?
中运行,并在多个页面上阅读帮助输出。
不需要批处理文件,因为此任务可以通过以下命令行完成:
for /R %I in (*.mp4) do @if not exist "%~dpnI.mkv" ffmpeg.exe -i "%I" -map 0 -map -0:s -codec copy "%~dpnI.mkv" && del "%%I"
批处理文件中的同一命令行:
@echo off
for /R %%I in (*.mp4) do if not exist "%%~dpnI.mkv" ffmpeg.exe -i "%%I" -map 0 -map -0:s -codec copy "%%~dpnI.mkv" && del "%%I"
由于不知道具有真实文件夹名称和真实文件名的文件夹结构,我无法回答为什么批处理文件失败。但是Stephan是正确的,IF NOT EXIST %newName% (
在文件名的情况下失败,完整路径包含空格或其中一个字符&()[]{}^=;!'+,`~
,因为没有用双引号括起来。
注意: && del "%%I"
会导致删除刚刚转换的* .mp4文件,如果转换成功并退出ffmpeg.exe
,0
通常是退出/退货成功的代码。另请参阅Single line with multiple commands using Windows batch file。
如果再次使用子程序再写一个批处理文件,请同时阅读Where does GOTO :EOF return to?。有问题的批处理文件在 FOR 循环后错过goto :EOF
或exit /B
,以避免在 FOR 完成后落入子程序代码。这不是问题,但通常不对。