Hey folks,
I am wondering if this is even possible…can you take a list of timecodes and corresponding names and make them into chapters in QuickTime Pro?
I’ve downloaded some of the sample scripts for QT, but they don’t seem to work with timecode (only frame counts from the start of the movie). Now, additional timecode support was added in recent QuickTime but I don’t know if it extends to this.
I can do a similar thing with Compressor (using the Commandline interface to load a chapter list file ” this is new to Compressor 3.0.2 incidentally, you can see these new commands if you do a ./Compressor -help in terminal). The problem with using Compressor is that it always recompresses the file. So, even if your movie is a H.264 already, it will recompress it again and degrade the quality.
You can add chapter marks to a H.264 movie via Garageband, one by one, and then export it without changing the quality, but it is not scriptable.
So, that leaves me with QT, which is scriptable, but I don’t know if it has this capability?
A chapter list file is pretty trivial. It usually is formatted as:
01:00:00:00 Start
01:00:10:00 First Scene
01:02:50:05 First Interview
01:05:00:10 Second Interview
Has anyone tried something like this before?
Cheers.
OK, here’s what I have so far. It semi works but it fails to put in the subsequent chapter marks.
The big problem I’m seeing is how QuickTime deals with time. So, it doesn’t seem like I can use straight timecodes, so I’m trying to create durations from two timecodes and add chapters that way.
But I’m getting a little confused now. Sigh.
global theMovieName
global this_track
global theMovie
global fps
tell application "Finder"
set these_items to (choose file with prompt "Pick the Chapter Text file to use:" & return & "The proper format the text file should have is {Timecode Chapter Name}") as list
set theMovie to choose file with prompt "Choose the QuickTime Movie you want to Chapterize:"
set theMovieName to the name of (info for theMovie)
set fps to 30
end tell
OpenMovie(theMovie)
open these_items
end
on open these_items
try
set this_data to read (item 1 of these_items)
set this_data to parseTXT(this_data)
end try
end open
on OpenMovie(theMovie)
tell application "QuickTime Player"
open theMovie
end tell
try
tell application "QuickTime Player" to tell front document
set these_tracks to the name of every track
if these_tracks contains "Chapter Track" then
tell application "Finder"
display dialog "This movie already has a Chapter Track" & return & "Do you want to delete the track and create a new one?" buttons {"Yes", "No"}
if button returned of the result is "No" then error number -128
end tell
delete track "Chapter Track"
end if
end tell
end try
end OpenMovie
on parseTXT(this_data)
repeat with i from 1 to the count of paragraphs in this_data
set this_line to paragraph i of this_data
set theTimecode to trim_line(characters 1 thru 11 of this_line as string, " ", 2)
set theChapter to trim_line(characters 13 thru -1 of this_line as string, " ", 2)
set the chapterInfo to {}
set the end of chapterInfo to theTimecode
set the end of chapterInfo to theChapter
tell application "QuickTime Player"
tell front document
if i is equal to 1 then
set this_track to make new track at beginning with data theChapter
set enabled of this_track to false
set the name of this_track to "Chapter Track"
set chapterlist of track 1 to track "Chapter Track"
set the movie_length to the duration
set firstTime to theTimecode
tell chapter 1
set the time to 0
set the duration to movie_length
end tell
else
set nextTime to theTimecode
set newmovielengthframes to ((my convert_frame_string_to_number(firstTime)) + (my convert_frame_string_to_number(nextTime)))
set newmovielength to my convert_number_to_frame_string(newmovielengthframes)
set the newmovielength to the duration
set the duration of this_track to newmovielength
set the chapter_list to the name of every chapter
set the new_chapter_list to chapter_list & (i as string)
set the contents of the current chapter track to the new_chapter_list
set the time of chapter i to movie_length
set the duration of chapter i to newmovielength - movie_length
set the name of chapter i of this_track to theChapter
set movie_length to the duration
set firstTime to convert_frame_string_to_number(theTimecode)
end if
end tell
end tell
end repeat
end parseTXT
on trim_line(this_text, trim_chars, trim_indicator)
-- 0 = beginning, 1 = end, 2 = both
set x to the length of the trim_chars
-- TRIM BEGINNING
if the trim_indicator is in {0, 2} then
repeat while this_text begins with the trim_chars
try
set this_text to characters (x + 1) thru -1 of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
-- TRIM ENDING
if the trim_indicator is in {1, 2} then
repeat while this_text ends with the trim_chars
try
set this_text to characters 1 thru -(x + 1) of this_text as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
return this_text
end trim_line
on parse_text(this_text, open_tag, close_tag)
set x to the offset of the open_tag in this_text
if x is 0 then return "NO TAG"
set this_text to (characters (x + (length of the open_tag)) thru -1 of this_text) as string
set x to the offset of the close_tag in this_text
if x is 1 then
return "NO DATA"
else
set this_text to (characters 1 thru (x - 1) of this_text) as string
end if
return this_text
end parse_text
on convert_frame_string_to_number(the_string)
tell (a reference to my text item delimiters)
set {old_delim, contents} to {contents, ":"}
set {{h, m, s, f}, contents} to {the_string's text items, old_delim}
end tell
set h to (h as integer) * fps * hours
set m to (m as integer) * fps * minutes
set s to (s as integer) * fps
return h + m + s + f
end convert_frame_string_to_number
on convert_number_to_frame_string(the_number)
set h to ("0" & (the_number div (fps * hours)))'s text -2 thru -1
set m to ("0" & ((the_number mod (fps * hours)) div (fps * minutes)))'s text -2 thru -1
set s to ("0" & (the_number mod (fps * minutes)) div fps)'s text -2 thru -1
set f to ("0" & (the_number mod fps))'s text -2 thru -1
return "" & {h, ":", m, ":", s, ":", f}
end convert_number_to_frame_string