2017-09-18 4 views
0

Ich versuche, eine Windows-Batch-Datei zu schreiben, die ffmpeg verwendet, um ganze Ordner mit alten * .flv Videos in * .mp4 Videos zu konvertieren.Warum kann meine Batchdatei die Dateigröße nicht erreichen?

Die Batch-Datei funktioniert mehr oder weniger, aber ich möchte einige Tests vor dem Löschen der Quelldatei durchführen. Einer dieser Tests ist, dass die Ausgabedatei mindestens 2/3 der Originaldatei sein sollte, aber ich kann es nicht zum Laufen bringen.

Hier ist meine bat-Datei (mit allen Debugging-Echolinien enthalten):

@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 

Dies ist die Ausgabe:

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 bedeutet Fehlende Operanden-0 nicht atteso bedeutet Unexpected 0

Warum habe ich nicht die Dateigröße in den Variablen? Was ist der fehlende Operand?

+1

Warum verwenden Sie 'for/F', um die Dateigröße zu bestimmen? 'for/F' soll den Dateiinhalt lesen; Sie sollten stattdessen "for" ohne den '/ F'-Schalter verwenden ... – aschipfl

+0

Das war das Problem! Ich habe es benutzt, weil ich gegoogelt habe und die akzeptierte Antwort einer ähnlichen Frage benutzt habe. – Parduz

+0

Ich frage mich, warum diese Frage abgelehnt wurde ... während meine Frage dumm sein konnte, habe ich meine Suche gemacht, meinen Versuch gemacht, meinen Code gepostet, nicht um eine Antwort "Tu es für mich" ... – Parduz

Antwort

2

Die Umgebungsvariablen infile und outfile sind definiert, wobei der Dateiname in doppelte Anführungszeichen gesetzt wird. Das wird nicht empfohlen, wie in der Antwort auf Why is no string output with 'echo %var%' after using 'set var = text' on command line? erklärt, aber es ist gültig und funktioniert hier wie erwartet.

Die Befehlszeile Dateigröße der Ausgabedatei

for /f %%S in (%outfile%) do set "outsize=%%~zS" 

verarbeitet wird, bevor die Ausführung von Windows-Befehlsinterpreter zum Beispiel

for /f %S in ("C:\Path\File Name.mp4") do set "outsize=%~zS" 

Es kann in einem Fenster der Eingabeaufforderung erhalten auf die Ausführung gelesen werden for /?, dass for /F interpretiert die Set (Zeichenfolge zwischen runden Klammern) als String zu verarbeiten, wenn in doppelten Anführungszeichen mit Ausnahme der Option usebackq wird verwendet, was hier nicht gemacht wird. Aus diesem Grund teilt FOR die Zeichenfolge C:\Path\File Name.mp4 in Token unter Verwendung von Leerzeichen/Tab als Trennzeichen auf und weist das erste Token der Schleifenvariablen S zu. So ist S für das Beispiel C:\Path\File zugeordnet. Die Dateigröße für diese Datei kann nicht vom Windows-Befehlsinterpreter bestimmt werden, da diese Datei nicht existiert.

Die Lösung FÜR ohne Option ist mit /F:

for %%S in (%outfile%) do set "outsize=%%~zS" 

Und die Befehlszeile durch

ersetzt werden Dateigröße der Eingabedatei

for /f %%S in (%infile%) do set insize=%%~zS 

kann bekommen

set "insize=%~z1" 

Die Hilfeausgabe läuft In einem Eingabeaufforderungsfenster erläutert call /? diesen Argumentmodifikator, um die Größe einer Datei, die beim Aufruf als erste Argument übergeben wird, an die Stapeldatei zu übergeben.


Die Hilfe Ausgabe set /? auf Lauf erklärt, dass in arithmetischen Ausdrücken die aktuellen Werte von Umgebungsvariablen können ohne % oder ! Verwendung durch die Angabe der Umgebungsvariablen mit nur ihren Namen referenziert werden. Dies funktioniert sogar innerhalb eines Befehlsblocks, der mit ( beginnt und mit dem übereinstimmenden ) endet.

Die Kommandozeile mit dem arithmetischen Ausdruck

set /A "minsize=(%insize%*3)/2" 

auf insize führen kann nicht in der Ausführung von

set /A "minsize=(*3)/2" 

Nachricht Dies erklärt den Fehler definiert wird, weil es in der Tat ist den linken Operanden für die fehlende Multiplikation. Die Lösung verwendet den arithmetischen Ausdruck wie mit Hilfe des Befehls SET empfohlen.

set /A "minsize=(insize*3)/2" 

Dieser arithmetische Ausdruck kann nie auf Auswertung. Wenn die Umgebungsvariable nicht definiert ist, wird sie durch 0 bei der Auswertung des arithmetischen Ausdrucks ersetzt, wie in der Hilfe erläutert.

Siehe auch Debugging a batch file.

Und bitte beachten Sie, dass Windows-Befehlsinterpreter nur arithmetische Ausdrücke mit 32-Bit-Ganzzahl mit Vorzeichen unterstützt. Daher können Videodateien mit einer Dateigröße von 2 GiB oder mehr nicht korrekt von Ihrem Stapelcode verarbeitet werden.

Verwandte Themen