2

I have a library of decrypted DVDs, which all have their video in a series of VOB files within the usual VIDEO_TS folder. I wondered if I could use FFMPEG to combine them into a single MPEG files. So first I found this (example assumes 2 VOB files) from an old non-stack exchange post, and it works...

ffmpeg -i "concat:VTS_01_1.VOB|VTS_01_2.VOB" -f DVD -c copy output.mpg

ffmpeg complains sometimes about possible missing timestamps, but I've not seen any issues in the video, audio, or synchronization. This works too with slightly different complaints

ffmpeg -i "concat:VTS_01_1.VOB|VTS_01_2.VOB" -f mpeg -c copy output.mpeg

So I've written a batch file (windows 10) that gathers the number of VOB files I want to process. What I had hoped to do then is create the "concat" string for FFMPEG to process. But I made on by hand just to try like this...

set concat="concat: VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB|VTS_01_5.VOB"

Then I tried passing that string to FFMPEG like this in my batch file

ffmpeg -i %concat% -f DVD -c copy output.mpg

Well that doesn't work at all. I guess FFMPEG cant recognize the string variable as a substitute. So I looked up the ffmpeg docs on the "concat" subject, and they suggest using a list of files stored in a text file, like this...

file 'VTS_01_1.VOB'
file 'VTS_01_2.VOB' (etc...)

Then, saving the file as "mylist.txt", and using a call to FFMPEG like this...

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mpg

Well I tried that and it didn't work very well. After the first VOB file, I was getting continuous warnings about buffer underflow and time stamps, and the usually fast concatenation process slowed to a creep. Warnings typically looked like this...

[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.

So can anyone suggest a method that WORKS as well as my first example, but taking the list of files from an input text file?

Randy
  • 131

1 Answers1

1

After a lot of experimentation and research, I found that the best thing to do was to make a BAT file script to build a second BAT file script in a variable and save it as a temp BAt file. The constructed BAT file can then be built with a custom constructed "concat: " parameter, based on the DVD titleset desired, and the discovered number of files in the titleset. The only fly in the ointments is that it is near impossible to build a string in a variable containing the pipe (|) character. I solved this by substituting a '@' character during the build, and later used an open source file search and replace utility to change the '@' instances to "|". It works fine. Note I'm using windows 10, and FFMPEG version git-2020-06-26-7447045, downloaded and installed June,2020. Below is the commented batch file I created, so if anyone wants to do something similar they can start with this. I know it can be improved, but it WORKS (always a good start)!

::
:: 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

Randy
  • 131