#!/bin/bash ############################################### # redfist.sh 0.1 # This little script extracts chapter times # from HandBrake-encoded movies and translates # them into a format readable by mkvmerge. ############################################### # It accepts two command-line arguments, the # path to the HandBrake-encoded .mp4 to read, # and the path to a copy of MP4Box. ############################################### # For this to work, you obviously have to use # chapter markers in HandBrake, and for this # process to be useful, it should be done with # HandBrake 0.8.5b2 or later, which has precise # chapter times, instead of following what the # DVD says. INPUTFILE="$1" MP4BOX_PATH="$2" ############# # SED STUFF ############# # First, extract the chapter index to stdout with mp4box. Then, display only # the lines with the timecodes and chapters on them (starts with "") of the line. Strip # control characters like ^M, too. # Store what's left in the TIMECODE array for later use. TIMECODE=($($MP4BOX_PATH -ttxt 3 $INPUTFILE -std | grep '//g' -e 's/[[:cntrl:]]//g')) # First, extract the chapter index to stdout with mp4box. Then, display only # the lines with the timecodes and chapters on them (starts with "") at the end of the line. # Store what's left in the TITLE array for later use. For now, this only works # when you use the default names ("Chapter XX") because of limitations in how # bash handles strings in arrays (it delimits on spaces and so I'm assuming # there will be two spots used in the array per title before the next Chapter). # Oh yeah, it'd also help if bash arrays were multidimensional. TITLE=($($MP4BOX_PATH -ttxt 3 $INPUTFILE -std | grep '//g')) ############# # LOOP PREP ############# # For the timecode index and the loop. ITERATOR1=0 # For the chapter title index. ITERATOR2=0 # We want to iterate through based on the number of timecodes stored # in the TIMECODE array. CHAPTERNUM=$(echo ${#TIMECODE[*]}) # And yet, we don't want the last chapter marker from HandBrake, # because it's just the last frame of the video. So decrement. CHAPTERNUM=$((CHAPTERNUM-1)) # This xml header text only needs to be at the top, so # throw it in before the loop starts. echo -e "" echo -e "" echo -e "" echo -e "" ####################################### # LOOPING, WHERE THE REAL WORK'S DONE ####################################### # Loop through all the chapters. while [ $ITERATOR1 -lt $CHAPTERNUM ] do echo -e "" echo -e " \c" echo -e ${TIMECODE[$ITERATOR1]} "\c" echo -e "" echo -e "" # Timecode written, it's on to the title. echo -e " \c" # Then, two words from the title array. echo -e ${TITLE[$ITERATOR2]} ${TITLE[$ITERATOR2+1]} "\c" echo -e "" echo -e "eng" echo -e "" echo -e "" # Iterate the timecodes and the loop by one. ITERATOR1=$((ITERATOR1+1)) # Because HandBrake uses two-word title names, # and each word is stored separately in the array, # iterate it by two to jump past both words used # this time through the loop. ITERATOR2=$((ITERATOR2+2)) done ############# # POST LOOP ############# # This is just to close out the xml divs. echo -e "" echo -e ""