FFMPEG – Pre-Fill File Duration Into FFMPEG’s MP3-Concatenation File-List, Using FFPROBE

This is will generate a text file filed with all the mp3 files in the folder,
it will also PRE QUERY each file using FFPROBE and will add the result to the file,
helping to avoid sync-or-duration problems.

ffprobe supports built-in formatting, which might help you avoid using external commands such as cut, sed, grep, etc… .

The result is an improved (but not encoded) combination of all the mp3 files,

name it something like merge_mp3.cmd.

@echo off
if exist list.txt   ( del /f /q list.txt   >nul );
if exist output.mp3 ( del /f /q output.mp3 >nul );


echo # MP3 LIST(%DATE% %TIME%)>list.txt
for %%e in (*.mp3) do (
  echo file '%%e'>>list.txt

  for /f "tokens=*" %%a in ('ffprobe -i "%%e" -v "error" -select_streams "a:0" -show_entries "stream=duration" -print_format "default=noprint_wrappers=1:nokey=1"') do ( 
    echo duration %%a>>list.txt
  );
  
  echo.>>list.txt
)

call ffmpeg.exe -y -hide_banner -loglevel "info" -stats        ^
-flags             "-loop+naq+low_delay+global_header"         ^
-fflags            "-fastseek+genpts+discardcorrupt+nofillin"  ^
-flags2            "+fast+ignorecrop+showall+export_mvs"       ^
-avoid_negative_ts "make_zero"                                 ^
-analyzeduration   "2000000"                                   ^
-threads 16                                                    ^
-safe "0" -f concat -i "list.txt"                              ^
-movflags          "+rtphint+dash+disable_chpl+faststart"      ^
-map_metadata      "0" -write_id3v2 "1" -id3v2_version "3"     ^
-c:a libmp3lame ^
-c copy  ^
-f mp3 output.mp3

pause

the ffprobe command above will output a single float value (for example: 607.503673) which should not be wrapped in inverted commas,
you can get a human-readable value (but not for the use of the concat process, maybe just for your information) by adding -sexagesimal (example output: 0:10:07.503673).

you can follow-up and encode the result with the following code.

name it something like re_encode_mp3.cmd

@echo off

call ffmpeg.exe -y -hide_banner -loglevel "info" -stats        ^
-flags             "-loop+naq+low_delay+global_header"         ^
-fflags            "-fastseek+genpts+discardcorrupt+nofillin"  ^
-flags2            "+fast+ignorecrop+showall+export_mvs"       ^
-avoid_negative_ts "make_zero"                                 ^
-analyzeduration   "2000000"                                   ^
-threads 16                                                    ^
-i "output.mp3"                                                ^
-movflags          "+rtphint+dash+disable_chpl+faststart"      ^
-map_metadata      "0" -write_id3v2 "1" -id3v2_version "3"     ^
 ^
-af "asetpts=PTS-STARTPTS,aresample=async=1:min_hard_comp=0.100000"  ^
-c:a libmp3lame -b:a 128k -ar 44100                                  ^
output_fixed.mp3

pause

the result should be faster than encoding in one go :]

Leave a Reply