I have a 2011 GM Vehicle with an in-dash Infotainment system that plays AVI/DivX files. Unfortunately, most of my AVI files do not play correctly on the system, or not at all. I get errors like "File format not supported," or the resolution would be miss matched, or even the sound would be horrible.
My goal is to create a batch file that utilizes open-source projects to re-encode my movies to a consistent sound and video format that will work in the vehicle.
- Analize input video
- Need to know the width, height
- Maybe" how many audio streams (to preserve more than 2 channels, each channel will have to be split into it's own wav file, normalized, then recombined)
- Maybe: detect for English stream, discard others.
- Maybe: detect sub titles and discard or keep
- Rip the audio streams from it
- Edit the audio streams
- Signal level compression/expansion of the audio streams
- Signal level normalization of the audio streams
- Re-encode the video and recombine with the audio
- The DivX codec will work with MPEG4 but I'm looking for a way to use H.264
- Force FourCC to be DX50
- Force the resolution to be 720x480 (use 720x432 to fill the entire screen) even though the screen is 800x480
- Force the G.O.P. to 15 (group of pictures is the number of frames before a keyframe)
- Force 0 B-Frames (while H.264 takes full advantage of B-Frames, this particular DivX player does not). What is a B-Frame? A B-Frame is a file-size optimization mechanism for H.264 (and other codecs) that only stores the bitmap changes from a previous frame as apposed to storing the entire frame. When areas of a video remain constant for several seconds, this can save a considerable amount of space. The DivX profile of the player is supposed to be "Home Theater" which should support 1 B-Frame, but I have not had much success using FFMPEG+MPEG4. I will keep investigating with H.264. Edit: FFMPEG+MPEG4 has to run in a single thread to encode B-Frames.
- Reduce the video bit rate... since the screen is small and I would like to cram 8 full length movies onto a single 4GB DVD. 400KB/s is a good mix of quality and size.
This process would take a considerable amount of time for each video, so it would best exist inside a single batch file that can accept parameters. To process multiple files, I'd just create another batch file that will go down the list, or possible use a command-line for loop to process every video in a particular directory.
When burning, make sure to use ISO/Joliet format for the data DVD... I have had mixed/poor results with UDF discs of all versions.
The projects that I am using will be Windows versions:
- http://www.ffmpeg.org/ Download here: http://ffmpeg.zeranoe.com/builds/
- http://sox.sourceforge.net/ Download here: http://sourceforge.net/projects/sox/files/sox/
Check Back Later for more updates.
Usage: filename.bat inputVideoFileName outputVideoFileName videoKBPS [ffmpeg pathToffmpeg] [sox pathToSox]
Example: filename.bat "StarTrek.mkv" "StarTrekForCar.avi" 300 ffmpeg c:\ffmpeg\bin\ffmpeg.exe sox c:\sox\sox.exe
echo off
REM These variables exist only within this file execution
setlocal
REM Change to the batch file directory, where FFMPEG and SOX are located
cd %~dp0
set inputFileName=%1
set outputFileName=%2
set vbr=%3
set width=0
set height=0
set duration=0
set ffmpeg=ffmpeg.exe
set sox=sox.exe
REM Test input parameters
IF %1.==. GOTO Usage
IF %2.==. GOTO Usage
IF %3.==. GOTO Usage
echo %3| findstr /r "^[1-9][0-9]*$">nul
IF ERRORLEVEL 0 GOTO Parameter4
echo Invalid Bitrate
goto Usage
:Parameter4
IF %4. == ffmpeg. GOTO UpdateFFMPEG4
IF %4. == sox. GOTO UpdateSox4
:Parameter6
IF %6. == ffmpeg. GOTO UpdateFFMPEG6
IF %6. == sox. GOTO UpdateSox6
:Continue
if not exist "%ffmpeg%" (
echo Can not find ffmpeg binary: %ffmpeg%
goto Usage
)
if not exist "%sox%" (
echo Can not find Sox binary: %sox%
goto Usage
)
if not exist "%inputFileName%" (
echo Can not find input file: %inputFileName%
goto Usage
)
REM this is the command to print the file information
set info=ffprobe -v quiet -show_format -show_streams -of default %inputFileName%
REM get the input video width
for /f "delims=" %%a in ('%info% ^| findstr "width"') do @set width=%%a
set width=%width:~6%
REM get the input video height
for /f "delims=" %%a in ('%info% ^| findstr "height"') do @set height=%%a
set height=%height:~7%
REM get the input video duration
for /f "delims=" %%a in ('%info% ^| findstr "duration"') do @set duration=%%a
set duration=%duration:~9%
echo Input Video Dimensions: %width%x%height%
echo Input Video Duration : %duration%
set audioFileOriginal=temp1.%outputFileName%.wav
set audioFileFinal=temp2.%outputFileName%.wav
del %outputFileName% > NUL
del %audioFileOriginal% > NUL
set vid_opts=-vcodec mpeg4 -vb %vbr%k -acodec libmp3lame -filter:v scale=720:480 -vtag DX50 -f avi -ab 128k -g 15 -bf 1 -map 0:0 -map 1:0
set com_opts=-ac 2 -threads 1 -y -r 30
REM - Get audio
%ffmpeg% -i %inputFileName% -vn %com_opts% %audioFileOriginal%
REM process audio through sox. We want to reduce the
REM dynamic range with compand and normalize the volume
%sox% %audioFileOriginal% %audioFileFinal% compand 0.3,1 6:-70,-60,-20 -5 -90 0.2 norm
REM todo
REM Calculate the scale for video encoding
REM create a chapter every 10 minutes
REM Recombine video and audio
%ffmpeg% -i %inputFileName% -i %audioFileFinal% %vid_opts% %com_opts% %outputFileName%
Goto CleanExit
REM these are "functions
:Usage
echo
echo Usage: inputFileName outputFileName bitrate [ffmpeg location] [sox location]
echo [ffmpeg location] ie: ffmpeg "c:\ffmpeg\bin\ffmpeg.exe"
echo [sox location] ie: ffmpeg "c:\sox\sox.exe"
goto DirtyExit
:UpdateFFMPEG4
if %5.==. goto LocationErrorFFMPEG
set ffmpeg=%5
goto Parameter6
:UpdateSox4
if %5.==. goto LocationErrorSox
set sox=%5
goto Parameter6
:UpdateFFMPEG6
if %7.==. goto LocationErrorFFMPEG
set ffmpeg=%7
goto Continue
:UpdateSox6
if %7.==. goto LocationErrorSox
set sox=%7
goto Continue
:LocationErrorFFMPEG
echo FFMPEG requires a path.
goto Usage
:LocationErrorFFMPEG
echo Sox requires a path.
goto Usage
REM Clean up temp files
:CleanExit
del %audioFileOriginal% > NUL
del %audioFileFinal% > NUL
:DirtyExit
REM These variables exist only within this file execution
setlocal
REM Change to the batch file directory, where FFMPEG and SOX are located
cd %~dp0
set inputFileName=%1
set outputFileName=%2
set vbr=%3
set width=0
set height=0
set duration=0
set ffmpeg=ffmpeg.exe
set sox=sox.exe
REM Test input parameters
IF %1.==. GOTO Usage
IF %2.==. GOTO Usage
IF %3.==. GOTO Usage
echo %3| findstr /r "^[1-9][0-9]*$">nul
IF ERRORLEVEL 0 GOTO Parameter4
echo Invalid Bitrate
goto Usage
:Parameter4
IF %4. == ffmpeg. GOTO UpdateFFMPEG4
IF %4. == sox. GOTO UpdateSox4
:Parameter6
IF %6. == ffmpeg. GOTO UpdateFFMPEG6
IF %6. == sox. GOTO UpdateSox6
:Continue
if not exist "%ffmpeg%" (
echo Can not find ffmpeg binary: %ffmpeg%
goto Usage
)
if not exist "%sox%" (
echo Can not find Sox binary: %sox%
goto Usage
)
if not exist "%inputFileName%" (
echo Can not find input file: %inputFileName%
goto Usage
)
REM this is the command to print the file information
set info=ffprobe -v quiet -show_format -show_streams -of default %inputFileName%
REM get the input video width
for /f "delims=" %%a in ('%info% ^| findstr "width"') do @set width=%%a
set width=%width:~6%
REM get the input video height
for /f "delims=" %%a in ('%info% ^| findstr "height"') do @set height=%%a
set height=%height:~7%
REM get the input video duration
for /f "delims=" %%a in ('%info% ^| findstr "duration"') do @set duration=%%a
set duration=%duration:~9%
echo Input Video Dimensions: %width%x%height%
echo Input Video Duration : %duration%
set audioFileOriginal=temp1.%outputFileName%.wav
set audioFileFinal=temp2.%outputFileName%.wav
del %outputFileName% > NUL
del %audioFileOriginal% > NUL
set vid_opts=-vcodec mpeg4 -vb %vbr%k -acodec libmp3lame -filter:v scale=720:480 -vtag DX50 -f avi -ab 128k -g 15 -bf 1 -map 0:0 -map 1:0
set com_opts=-ac 2 -threads 1 -y -r 30
REM - Get audio
%ffmpeg% -i %inputFileName% -vn %com_opts% %audioFileOriginal%
REM process audio through sox. We want to reduce the
REM dynamic range with compand and normalize the volume
%sox% %audioFileOriginal% %audioFileFinal% compand 0.3,1 6:-70,-60,-20 -5 -90 0.2 norm
REM todo
REM Calculate the scale for video encoding
REM create a chapter every 10 minutes
REM Recombine video and audio
%ffmpeg% -i %inputFileName% -i %audioFileFinal% %vid_opts% %com_opts% %outputFileName%
Goto CleanExit
REM these are "functions
:Usage
echo
echo Usage: inputFileName outputFileName bitrate [ffmpeg location] [sox location]
echo [ffmpeg location] ie: ffmpeg "c:\ffmpeg\bin\ffmpeg.exe"
echo [sox location] ie: ffmpeg "c:\sox\sox.exe"
goto DirtyExit
:UpdateFFMPEG4
if %5.==. goto LocationErrorFFMPEG
set ffmpeg=%5
goto Parameter6
:UpdateSox4
if %5.==. goto LocationErrorSox
set sox=%5
goto Parameter6
:UpdateFFMPEG6
if %7.==. goto LocationErrorFFMPEG
set ffmpeg=%7
goto Continue
:UpdateSox6
if %7.==. goto LocationErrorSox
set sox=%7
goto Continue
:LocationErrorFFMPEG
echo FFMPEG requires a path.
goto Usage
:LocationErrorFFMPEG
echo Sox requires a path.
goto Usage
REM Clean up temp files
:CleanExit
del %audioFileOriginal% > NUL
del %audioFileFinal% > NUL
:DirtyExit