%20von%20VOB-Dateien%20von%20DVD%20mit%20FFMPEG.png)
Ich habe eine Bibliothek entschlüsselter DVDs, deren Videos alle in einer Reihe von VOB-Dateien im üblichen VIDEO_TS-Ordner enthalten sind. Ich habe mich gefragt, ob ich sie mit FFMPEG zu einer einzigen MPEG-Datei zusammenfassen könnte. Also habe ich zuerst dies (Beispiel geht von 2 VOB-Dateien aus) in einem alten Nicht-Stack-Austauschbeitrag gefunden, und es funktioniert ...
ffmpeg -i "concat:VTS_01_1.VOB|VTS_01_2.VOB" -f DVD -c copy output.mpg
ffmpeg beschwert sich manchmal über möglicherweise fehlende Zeitstempel, aber ich habe keine Probleme bei Video, Audio oder Synchronisierung gesehen. Dies funktioniert auch mit leicht unterschiedlichen Beschwerden
ffmpeg -i "concat:VTS_01_1.VOB|VTS_01_2.VOB" -f mpeg -c copy output.mpeg
Also habe ich eine Batchdatei (Windows 10) geschrieben, die die Anzahl der VOB-Dateien sammelt, die ich verarbeiten möchte. Ich hatte gehofft, damit die „Concat“-Zeichenfolge für die Verarbeitung durch FFMPEG erstellen zu können. Aber ich habe eine von Hand erstellt, nur um es so auszuprobieren …
set concat="concat: VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB|VTS_01_5.VOB"
Dann habe ich versucht, diese Zeichenfolge in meiner Batchdatei wie folgt an FFMPEG zu übergeben
ffmpeg -i %concat% -f DVD -c kopiere Ausgabe.mpg
Nun, das funktioniert überhaupt nicht. Ich schätze, FFMPEG kann die String-Variable nicht als Ersatz erkennen. Also habe ich die ffmpeg-Dokumente zum Thema „concat“ nachgeschlagen und sie schlagen vor, eine Liste von Dateien zu verwenden, die in einer Textdatei gespeichert sind, wie diese ...
file 'VTS_01_1.VOB'
file 'VTS_01_2.VOB' (etc...)
Speichern Sie die Datei dann als „mylist.txt“ und verwenden Sie einen Aufruf von FFMPEG wie folgt …
ffmpeg -f concat -safe 0 -i mylist.txt -c kopiere output.mpg
Nun, ich habe das versucht, aber es hat nicht sehr gut funktioniert. Nach der ersten VOB-Datei erhielt ich ständig Warnungen über Pufferunterlauf und Zeitstempel, und der normalerweise schnelle Verkettungsprozess wurde langsam langsamer. Warnungen sahen normalerweise so aus ...
[mpeg @ 00000185e32b4200] buffer underflow st=1 bufi=1466 size=1998
[mpeg @ 00000185e32b4200] Non-monotonous DTS in output stream 0:1; previous: 328415794, current: 9265348; changing to 328415795. This may result in incorrect timestamps in the output file.
Kann also jemand eine Methode vorschlagen, die genauso gut FUNKTIONIERT wie mein erstes Beispiel, aber die Dateiliste aus einer Eingabetextdatei übernimmt?
Antwort1
Nach vielen Experimenten und Recherchen kam ich zu dem Schluss, dass es am besten ist, ein BAT-Dateiskript zu erstellen, um ein zweites BAT-Dateiskript in einer Variablen zu erstellen und es als temporäre BAt-Datei zu speichern. Die erstellte BAT-Datei kann dann mit einem benutzerdefinierten Parameter „concat:“ erstellt werden, basierend auf dem gewünschten DVD-Titelsatz und der erkannten Anzahl von Dateien im Titelsatz. Der einzige Wermutstropfen ist, dass es nahezu unmöglich ist, eine Zeichenfolge in einer Variablen zu erstellen, die das Pipe-Zeichen (|) enthält. Ich habe dies gelöst, indem ich während des Builds ein „@“-Zeichen ersetzt habe und später ein Open-Source-Dateisuch- und -ersetzungsprogramm verwendet habe, um die „@“-Instanzen in „|“ zu ändern. Es funktioniert einwandfrei. Beachten Sie, dass ich Windows 10 und FFMPEG-Version git-2020-06-26-7447045 verwende, die im Juni 2020 heruntergeladen und installiert wurde. Unten ist die kommentierte Batchdatei, die ich erstellt habe. Wenn also jemand etwas Ähnliches tun möchte, kann er damit beginnen. Ich weiß, dass es verbessert werden kann, aber es FUNKTIONIERT (immer ein guter Anfang)!
::
:: Batch file to automate conversion of a series of VOB files in a DVD
:: titleset into a single MPG file, via FFMPEG.
:: Pass a name you'd like for the final output movie file in param 1
:: This script needs a a file search and replace utility, and I'm useing
:: SKF (Swiss Army Knife), which is open source and free ...
:: https://sourceforge.net/projects/swissfileknife/
:: Whatever search/replace util you use, you'll have to put it in a
:: 'utilities' folder somewhere in your C: drive, and make sure
:: your system (or USER) PATH variable includes it.
:: Also, unless you have unencrytpted DVD copies to work with, OR a
:: Decryptor that automatically works in the background (like DVD43),
:: you'll have to start with a program like "1-Click DVD Copy (Pro)".
:: In that case you can put the Resulting VIDEO_TS folder in a temp
:: area on your HD. This will make this batch process run faster,
:: and eliminate the needs to waste a blank DVD.
echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: Set a path where converted ouptput videos will go
:: Temporary files created by this script will also go here.
set outPath="C:\Users\Public\Videos\Temp"
:: set a path to your DVD. Playable DVDs always have aVIDEO_TS folder
set inPathDVD="Q:\VIDEO_TS"
:: In the event you are making unencrypted copies (maybe with 1-Click),
:: set that software to put its output files here. In that case,
:: the parameter you pass this script should match the folder name
:: created by that software!
set inPathHD="C:\Users\Public\Videos\Temp\%1\Video_TS"
:: some variables to construct expecteed files to seach for and gather
set inpTitleSet=VTS_
set inpExt=.VOB
set output=%outPath%\%1.mpg
set outTemp=%outPath%\%1%inpExt%
:: choose whether files come directly from DVD (must be unencrypted!)
:: or defined location on HD
choice /M "Choose Source 1 = DVD 2 = HD Temp Area" /C 12
if ERRORLEVEL 1 set inPath=%inPathDVD%
if ERRORLEVEL 2 set inPath=%inPathHD%
echo input path is: %inPath%
cd /D %inPath%
echo .
echo VOB files from %inpath%...
echo .
:: create filespec for search "VTS_01_*.vob"
set inputFileSpec=%inpTitleSet%*%inpExt%
dir %inputFileSpec%
echo .
:: select desired titleset. Usually the group with the
:: biggest file sizes is the main movie titleset.
:: You'll be entering the digit after "VTS_0"
choice /M "Select Desired Titleset (digit after VTS_): " /C 12345678
echo you picked %ERRORLEVEL%
set inpTitleSet=%inpTitleSet%0%ERRORLEVEL%_
set inputFileSpec=%inpTitleSet%*%inpExt%
:: use a brute force loop to calculate number of
:: files matching %inputFileSpec% and display them.
:: Note that the '0' file is usually title/menu information,
:: and is skipped by making the %start% var '1'
echo files selected...
echo .
set start=1
:loop0
set tmp=%inpTitleSet%%start%%inpExt%
IF EXIST %tmp% (
echo %tmp%
set /A start=start+1
GOTO loop0
)
set /A count=%start%-1
echo .
:: confirm total files
echo Total Files = %count%
:: safety exit, in odd event where no movie files found
if %count% NEQ 0 GOTO continue1
echo .
echo Must Exit... no Files Found.
goto exit
:continue1
:: Build string containing of file names for FFMPEG "concat:" parameter.
:: Another Brute force loop. Again file *0.VOB will be skipped,
:: by making loop start=1::
:: set an 'empty' variable
set cc=
set start=1
:: create a temp substitute for the pipe "|" character,
:: because | can't be cant be used in a script (^| or similar
:: constructs just won't work here). So I'll use '@' and change it
:: later with a file search/replace utility.
set mypipe=@
:loop1
set tmp=%inpTitleSet%%start%%inpExt%
if %start% EQU %count% set mypipe=
IF EXIST %tmp% (
set cc=%cc%%inp%%tmp%%mypipe%
set /A start=start+1
GOTO loop1
)
:: create whole FFMPEG command as a string
set ffm=ffmpeg -i "concat:%cc%" -f DVD -c copy %output%
:: put it in a tmp batch file
set cmdfile=tmp.bat
echo %ffm% > %outPath%\%cmdfile%
:: now use SKF to replace the @ chars with |
:: if you have another search/replace utility, feel free to use it.
sfk replace %outPath%\%cmdfile% "/@/|/" -yes -quiet
:: prove string in batch file looks right. You can delete
:: these two lines if you want.
echo Final command...
type %outPath%\%cmdfile%
:: run the new batch file... Give user chance to start process
@pause
call %outPath%\%cmdfile%
:: delete batch file?
del %outPath%\%cmdfile%
echo .
echo .
echo %output% converted file should be ready
ENDLOCAL
:exit