FFMPEG를 사용하여 DVD에서 VOB 파일을 자동으로 연결(병합)하는 데 문제가 있습니다.

FFMPEG를 사용하여 DVD에서 VOB 파일을 자동으로 연결(병합)하는 데 문제가 있습니다.

나는 일반적인 VIDEO_TS 폴더 내의 일련의 VOB 파일에 비디오를 포함하는 해독된 DVD 라이브러리를 가지고 있습니다. FFMPEG를 사용하여 단일 MPEG 파일로 결합할 수 있는지 궁금했습니다. 그래서 먼저 오래된 비스택 교환 게시물에서 이것을 찾았고(예제는 2개의 VOB 파일로 가정) 작동했습니다...

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

ffmpeg는 때때로 타임스탬프 누락 가능성에 대해 불평하지만 비디오, 오디오 또는 동기화에는 어떤 문제도 발견되지 않았습니다. 이것은 약간 다른 불만에도 적용됩니다.

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

그래서 처리하려는 VOB 파일 수를 수집하는 배치 파일(Windows 10)을 작성했습니다. 내가 원했던 것은 FFMPEG가 처리할 "concat" 문자열을 생성하는 것이었습니다. 그런데 이렇게 하려고 손으로 만들었는데..

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

그런 다음 배치 파일에서 이와 같이 해당 문자열을 FFMPEG에 전달해 보았습니다.

ffmpeg -i %concat% -f DVD -c 출력.mpg 복사

글쎄, 그건 전혀 작동하지 않습니다. FFMPEG가 문자열 변수를 대체 변수로 인식하지 못하는 것 같습니다. 그래서 "concat" 주제에 대한 ffmpeg 문서를 찾아보았는데 다음과 같이 텍스트 파일에 저장된 파일 목록을 사용할 것을 제안했습니다.

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

그런 다음 파일을 "mylist.txt"로 저장하고 다음과 같이 FFMPEG를 호출하여 ...

ffmpeg -f concat -safe 0 -i mylist.txt -c 출력.mpg 복사

글쎄, 나는 그것을 시도했지만 잘 작동하지 않았습니다. 첫 번째 VOB 파일 이후에는 버퍼 언더플로 및 타임스탬프에 대한 지속적인 경고를 받았으며 일반적으로 빠른 연결 프로세스가 서서히 느려졌습니다. 경고는 일반적으로 다음과 같습니다.

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

그렇다면 입력 텍스트 파일에서 파일 목록을 가져오는 것 외에 제 첫 번째 예제와 마찬가지로 작동하는 방법을 제안할 수 있는 사람이 있을까요?

답변1

많은 실험과 연구 끝에 BAT 파일 스크립트를 만들어 변수에 두 번째 BAT 파일 스크립트를 작성하고 임시 BAt 파일로 저장하는 것이 가장 좋은 방법이라는 것을 알았습니다. 그런 다음 구성된 BAT 파일은 원하는 DVD 타이틀 세트와 타이틀 세트에서 검색된 파일 수를 기반으로 사용자 정의 구성된 "concat: " 매개변수를 사용하여 빌드할 수 있습니다. 연고의 유일한 문제점은 파이프(|) 문자가 포함된 변수에 문자열을 작성하는 것이 거의 불가능하다는 것입니다. 저는 빌드 중에 '@' 문자를 대체하여 이 문제를 해결했고 나중에 오픈 소스 파일 검색 및 교체 유틸리티를 사용하여 '@' 인스턴스를 "|"로 변경했습니다. 잘 작동합니다. 참고 저는 2020년 6월에 다운로드하여 설치된 Windows 10 및 FFMPEG 버전 git-2020-06-26-7447045를 사용하고 있습니다. 아래는 제가 만든 주석 처리된 배치 파일입니다. 비슷한 작업을 원하는 사람이 있으면 이 파일로 시작할 수 있습니다. 개선될 수 있다는 것을 알고 있지만 작동합니다(항상 좋은 시작입니다)!

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

관련 정보