我正在尝试编写一个Windows批处理文件,使用 ffmpeg 将整个文件夹与旧的.flv视频转换为* .mp4视频。
批处理文件或多或少有效,但我想在删除源文件之前做一些测试。其中一个测试是输出文件至少应该是原始文件的2/3,但我无法使其工作。
这是我的bat文件(包含所有调试回显线):
@echo off
setlocal EnableExtensions EnableDelayedExpansion
::-------------------------------------------------------------------------------------
:: get options and folder path
set opzione=%~1%
set cartella=%~2%
:: who's who?
if "%opzione:~3,1%"=="" (
echo.
) else (
if "%opzione:~0,1%"=="/" (
echo.
) else (
set opzione=%~2%
set cartella=%~1%
)
)
::echo.
::echo Cartella = %cartella%
::echo Opzione = %opzione%
::echo.
::-------------------------------------------------------------------------------------
:Check_path
set FLV_FOLDER="%cartella%"
if %FLV_FOLDER% == "" (
echo ... Invalid
goto :uscita
) else (
echo ... OK.
)
::-------------------------------------------------------------------------------------
:Check_Options (STILL W.I.P.)
set Lista=0
set Convert=0
set Delete=0
if "%opzione%"=="/c" (set Convert=1)
if "%opzione%"=="/l" (set Lista=1)
if "%opzione%"=="/d" (set Delete=1)
::echo Lista = %Lista%
::-------------------------------------------------------------------------------------
:Loop_path
@cls
echo Looping all .flv files in %FLV_FOLDER%...
for /R %FLV_FOLDER% %%a IN (*.flv) do call :Converting_Function "%%a"
goto :uscita
::-------------------------------------------------------------------------------------
:Converting_Function
set infile="%~1"
set outfile="%~dpn1.mp4"
set outsize=0
set insize=0
set minsize=0
if not %Lista%==0 goto :just_list
echo Converting %infile% to %outfile%
ffmpeg -v error -i %infile% -c copy -copyts %outfile%
::....................CHECKS........................................................
echo Errors from ffmpeg?
if errorlevel 1 goto :error_ffmpeg
echo Do the outfile exist?
if not exist %outfile% goto :error_exist
echo Is outfile big enough?
:: (say yes if outfile size > infile size*2/3)
for /f %%S in (%outfile%) do set "outsize=%%~zS"
echo %outfile% size is %outsize%
for /f %%S in (%infile%) do set insize=%%~zS
echo %infile% size is %insize%
set /A "minsize=(%insize%*3)/2"
echo minsize is %minsize%
if not %outsize% GTR %minsize% goto :error_size
ren "%~1" "%~n1.todelete"
:: del /q %infile%
goto :eof
:error_ffmpeg
echo Convertion error
pause
if exist %outfile% del /q %outfile%
goto :eof
:error_exist
echo %outfile% does not exist
pause
goto :eof
:error_size
echo Size of %outfile% is 0
pause
goto :eof
:just_list
echo %infile%
goto :eof
:uscita
pause
这是输出:
Converting "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" to "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4"
[flv @ 0000000000577320] Packet mismatch 107347968 1638 1638
Errors from ffmpeg?
Do the outfile exist?
Is outfile big enough?
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4" size is
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" size is
Operando mancante.
minsize is 0
0 non atteso.
D:\ffmpeg-20170204-b1e2192-win64-static\bin>
Operando mancante 表示缺少操作数, 0非参加表示意外0
为什么变量中没有文件大小?什么是缺少的操作数?
答案 0 :(得分:2)
定义环境变量infile
和outfile
,文件名用双引号括起来。这不是建议的,如Why is no string output with 'echo %var%' after using 'set var = text' on command line?的答案中所解释的那样,但它是有效的,并按预期在这里工作。
获取输出文件的文件大小的命令行
for /f %%S in (%outfile%) do set "outsize=%%~zS"
在Windows命令解释程序执行之前处理,例如
for /f %S in ("C:\Path\File Name.mp4") do set "outsize=%~zS"
可以在命令提示符窗口for /?
中执行时读取,for /F
将 set (圆括号之间的字符串)解释为要处理的字符串(如果用双引号括起来)除了使用选项usebackq
之外没有在这里完成。因此, FOR 将字符串C:\Path\File Name.mp4
拆分为标记,使用空格/制表符作为分隔符,并将第一个标记分配给循环变量S
。因此,为示例分配给S
的是C:\Path\File
。 Windows命令解释程序无法确定此文件的文件大小,因为此文件不存在。
解决方案是使用 FOR 而不使用选项/F
:
for %%S in (%outfile%) do set "outsize=%%~zS"
命令行获取输入文件的文件大小
for /f %%S in (%infile%) do set insize=%%~zS
可以替换为
set "insize=%~z1"
在命令提示符窗口call /?
中运行的帮助输出解释了这个参数修饰符,用于获取在调用它时作为第一个参数传递给批处理文件的文件的大小。
运行set /?
时的帮助输出解释了在算术表达式中,可以通过仅使用其名称指定环境变量而不使用%
来引用环境变量的当前值或!
。这甚至可以在以(
开头并以匹配)
结尾的命令块中工作。
带有算术表达式
的命令行set /A "minsize=(%insize%*3)/2"
可导致insize
未在执行
set /A "minsize=(*3)/2"
这解释了错误消息,因为确实缺少了乘法的左操作数。
解决方案是使用命令 SET 的帮助推荐的算术表达式。
set /A "minsize=(insize*3)/2"
此算术表达式在评估时永远不会失败。如果未定义环境变量insize
,则在评估算术表达式时将其替换为0
,如帮助所述。
请注意,Windows命令解释程序仅支持具有32位有符号整数值的算术表达式。因此,批处理代码无法正确处理文件大小为2 GiB或更多的视频文件。