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.

 

  1. Analize input video
    1. Need to know the width, height
    2. 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)
    3. Maybe: detect for English stream, discard others.
    4. Maybe: detect sub titles and discard or keep
  2. Rip the audio streams from it
  3. Edit the audio streams
    1. Signal level compression/expansion of the audio streams
    2. Signal level normalization of the audio streams
  4. Re-encode the video and recombine with the audio
    1. The DivX codec will work with MPEG4 but I'm looking for a way to use H.264
    2. Force FourCC to be DX50
    3. Force the resolution to be 720x480 (use 720x432 to fill the entire screen) even though the screen is 800x480
    4. Force the G.O.P. to 15 (group of pictures is the number of frames before a keyframe)
    5. 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.
    6. 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:
  1. http://www.ffmpeg.org/ Download here: http://ffmpeg.zeranoe.com/builds/
  2. 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