Finally, here is the new version with the additional block of code (form my first post) incorporated in:
property FrameRate : 30
property xmlType : "public.xml"
on run
display dialog "This is a droplet. Drop Final Cut Pro XML files on the icon to convert them." buttons {"OK"} default button 1
return
end run
on open xmlFiles
my makeFiles_(xmlFiles)
end open
on makeFiles_(xmlFiles)
repeat with i from 1 to the count of xmlFiles
set theFile to item i of xmlFiles
set theXML to XMLOpen (theFile)
--select the Final Cut XML file
--set theXML to XMLOpen (choose file with prompt "Select the XML file which contains your caption markers" of type {"public.xml"} default location (path to the desktop) without invisibles)
set the_root to XMLRoot theXML
set the_child to XMLChild the_root index 1
set theTitle to XMLChild the_child index 3
set youtubeTitle to (XMLGetText theTitle) & " - YouTube Captions"
set flashTitle to (XMLGetText theTitle) & " - Flash Captions"
set dvdTitle to (XMLGetText theTitle) & " - DVD Subtitles"
set mp4Title to (XMLGetText theTitle) & " - MP4 Subtitles"
set allMarkers to XMLXPath the_child with "marker/name"
set theMarkers to XMLGetText (allMarkers)
set startMarker to 11
set theIndex to startMarker
set theList to {}
--character count
set alertString to "Too many characters"
set messageString to "The following comments have too many characters. Please edit your original Final Cut markers." & return & return
repeat with my_item in theMarkers
try
set the_child_2 to XMLChild the_child index theIndex
set theMarker to XMLGetText (XMLChild the_child_2 index 1)
set theComment to XMLGetText (XMLChild the_child_2 index 2)
set theCount to get the count of the characters of theComment
if theCount is greater than 180 then
set messageString to messageString & "Comment " & theMarker & " has " & theCount & " characters." & return & return
end if
set theIndex to theIndex + 1
end try
end repeat
display alert alertString message messageString buttons {"OK"} default button "OK"
--set desktop_ to path to desktop as Unicode text
set theDestination to choose folder with prompt ("Choose or create your destination folder:") default location (path to the desktop)
--create an .xml file on the desktop and add the xml header in the proper format for Flash
set xmlHeader to setXMLHeader()
write_to_Flashfile(xmlHeader, (theDestination & flashTitle & ".xml"), true)
--create an .stl file on the desktop and add the STL header in the proper format for DVD Subtitles
set STLheader to setSTLheader()
write_to_STLfile(STLheader, (theDestination & dvdTitle & ".stl"), true)
--create an .ttxt file on the desktop and add the TTXT header in the proper format for MP4 Subtitles
set MP4header to setMP4header()
write_to_MP4file(MP4header, (theDestination & mp4Title & ".ttxt"), true)
repeat with my_item in theMarkers
try
set the_child_2 to XMLChild the_child index theIndex
set theMarker to XMLGetText (XMLChild the_child_2 index 1)
set theComment to XMLGetText (XMLChild the_child_2 index 2)
--shell script to convert smart quotes to straight quotes
set theComment to do shell script "awk '{gsub(/("|")/,\"\\042\"); gsub(/(˜|')/,\"\\047\"); print}' <<< " & quoted form of theComment
set inFrame to XMLGetText (XMLChild the_child_2 index 3)
set outFrame to XMLGetText (XMLChild the_child_2 index 4)
set durFrame to ((outFrame) - (inFrame))
--convert times from frames to hh:mm:ss,000
set inYouTube to (framesToYouTubeTime from inFrame by FrameRate)
set outYouTube to (framesToYouTubeTime from outFrame by FrameRate)
--convert times from frames to hh:mm:ss.000
set inFlash to (framesToFlashTime from inFrame by FrameRate)
set outFlash to (framesToFlashTime from outFrame by FrameRate)
set durFlash to (framesToFlashTime from durFrame by FrameRate)
--convert times from frames to hh:mm:ss:ff
set inDVD to (framesToSMPTE from inFrame by FrameRate)
set outDVD to (framesToSMPTE from outFrame by FrameRate)
--convert times from frames to hh:mm:ss.000
set inMP4 to (framesToMP4Time from inFrame by FrameRate)
set outMP4 to (framesToMP4Time from outFrame by FrameRate)
--create list of comment index, comment, in point, out point, and duration
set tempList to {theMarker, theComment, inYouTube, outYouTube, durFrame, inDVD, outDVD}
-- write all text to plain text file for spell checking purposes
write_to_Spell(theComment, (theDestination & "tempSpell"), true)
--write the list to an .srt file on the desktop in the proper format for YouTube
write_to_file(return & theIndex - 10 & return & item 3 of tempList & " --> " & item 4 of tempList & return & item 2 of tempList & return, (theDestination & youtubeTitle & ".srt"), true)
--write the list to an .xml file on the desktop in the proper format for Flash
write_to_Flashfile(return & "<p begin=\"" & inFlash & "\" dur=\"" & durFlash & "\" style=\"1\">" & theComment & "</p>", (theDestination & flashTitle & ".xml"), true)
--write the list to an .stl file on the desktop in the proper format for DVD Subtitles
write_to_file(return & item 6 of tempList & " , " & item 7 of tempList & " , " & item 2 of tempList & return, (theDestination & dvdTitle & ".stl"), true)
--write the list to an .ttxt file on the desktop in the proper format for MP4
write_to_MP4file(return & "<TextSample sampleTime=\"" & inMP4 & "\" text=\"'" & theComment & "'\">" & return & "</TextSample>", (theDestination & mp4Title & ".ttxt"), true)
set theIndex to theIndex + 1
end try
end repeat
--add the xml footer in the proper format for Flash
set xmlFooter to setXMLFooter()
write_to_Flashfile(xmlFooter, (theDestination & flashTitle & ".xml"), true)
--add the ttxt footer in the proper format for MP4
set MP4footer to setMP4Footer(outMP4)
write_to_MP4file(MP4footer, (theDestination & mp4Title & ".ttxt"), true)
end repeat
end makeFiles_
-- Subroutine to write to UTF-8 file
to write_to_Flashfile(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
write this_data to the open_target_file as «class utf8» starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
return false
end try
end write_to_Flashfile
-- Subroutine to write to text file
to write_to_file(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
write this_data to the open_target_file as «class utf8» starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
return false
end try
end write_to_file
-- Subroutine to write to STL file
to write_to_STLfile(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
--write this_data to the open_target_file as «class utf8» starting at eof
write this_data to the open_target_file starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
return false
end try
end write_to_STLfile
-- Subroutine to write to UTF-8 file for MP4
to write_to_MP4file(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
write this_data to the open_target_file as «class utf8» starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
return false
end try
end write_to_MP4file
--Subroutine to write plain text file for spell check and transcription purposes
--If text from FCP markers ends mid-sentence, this text file will have words combined. It will show up as misspelled words.
to write_to_Spell(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
write this_data & " " to the open_target_file as «class utf8» starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
return false
end try
tell application "TextEdit"
open document target_file
--get text of document target_file
end tell
return the result
end write_to_Spell
--Timecode conversion subroutines
--Subroutine to convert frames to YouTube timecode in format hh:mm:ss,000
on framesToYouTubeTime from ti by rate
tell ti div rate to tell (1000000 + it div hours * 10000 + it mod hours div minutes * 100 + it mod minutes) as text to return text 2 thru 3 & ":" & text 4 thru 5 & ":" & text 6 thru 7 & "," & text 2 thru 4 of ((1000 + ti mod rate * 1000 / rate) as text)
end framesToYouTubeTime
--Subroutine to convert frames to Flash timecode in format hh:mm:ss.000
on framesToFlashTime from ti by rate
tell ti div rate to tell (1000000 + it div hours * 10000 + it mod hours div minutes * 100 + it mod minutes) as text to return text 2 thru 3 & ":" & text 4 thru 5 & ":" & text 6 thru 7 & "." & text 2 thru 4 of ((1000 + ti mod rate * 1000 / rate) as text)
end framesToFlashTime
--Subroutine to convert frames to SMPTE timecode in format hh:mm:ss:ff
on framesToSMPTE from ti by rate
tell ti div rate to tell (100000000 + it div hours * 1000000 + it mod hours div minutes * 10000 + it mod minutes * 100 + ti mod rate) as text to return text 2 thru 3 & ":" & text 4 thru 5 & ":" & text 6 thru 7 & ":" & text 8 thru 9
end framesToSMPTE
--Subroutine to convert frames to MP4 timecode in format hh:mm:ss.:000
on framesToMP4Time from ti by rate
tell ti div rate to tell (1000000 + it div hours * 10000 + it mod hours div minutes * 100 + it mod minutes) as text to return text 2 thru 3 & ":" & text 4 thru 5 & ":" & text 6 thru 7 & "." & text 2 thru 4 of ((1000 + ti mod rate * 1000 / rate) as text)
end framesToMP4Time
--Header and footer subroutines
--Subroutine to write XML header for Flash captions
on setXMLHeader()
set xmlHeader to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" & return
set xmlHeader to xmlHeader & "<tt xml:lang=\"en\" xmlns=\"http://www.w3.org/2006/04/ttaf1\" xmlns:tts=\"http://www.w3.org/2006/04/ttaf1#styling\">" & return & return
set xmlHeader to xmlHeader & "<head>" & return
set xmlHeader to xmlHeader & "<styling>" & return
set xmlHeader to xmlHeader & "<style id=\"1\"" & return
set xmlHeader to xmlHeader & tab & "tts:fontFamily=\"_sans\"" & return
set xmlHeader to xmlHeader & tab & "tts:color=\"#FFFFFF\"" & return
set xmlHeader to xmlHeader & tab & "tts:fontWeight=\"bold\"" & return
set xmlHeader to xmlHeader & tab & "tts:fontSize=\"16\"" & return
set xmlHeader to xmlHeader & tab & "tts:backgroundColor=\"transparent\" />" & return
set xmlHeader to xmlHeader & "</styling>" & return
set xmlHeader to xmlHeader & "</head>" & return & return
set xmlHeader to xmlHeader & "<body>" & return
set xmlHeader to xmlHeader & "<div xml:lang=\"en\">"
end setXMLHeader
--Subroutine to write XML footer for Flash captions
on setXMLFooter()
set xmlFooter to "</div>" & return
set xmlFooter to xmlFooter & "</body>" & return
set xmlFooter to xmlFooter & return & "</tt>"
end setXMLFooter
--Subroutine to write STL header for DVD Subtitles
on setSTLheader()
set user_short_name to (do shell script "whoami")
set userName to (do shell script "finger " & user_short_name & " | grep Login | colrm 1 46")
set theDate to short date string of (the current date)
set STLheader to "$FontName = Arial" & return
set STLheader to STLheader & "$FontSize = 20" & return
set STLheader to STLheader & "$TapeOffset = False" & return
set STLheader to STLheader & "$YOffset = 0" & return
set STLheader to STLheader & "//The following subtitles were generated by XML Captions Application on " & theDate & " by " & userName & "."
end setSTLheader
--Subroutine to write TTXT header for MP4 captions
on setMP4header()
set MP4header to "<?xml version==\"1.0\" encoding=\"UTF-8\"?>" & return
set MP4header to MP4header & "<!-- GPAC 3GPP Text Stream -->" & return
set MP4header to MP4header & "<TextStream version=\"1.1\">" & return
set MP4header to MP4header & "<TextStreamHeader width=\"1000\" height=\"60\" layer=\"0\" translation_x=\"140\" translation_y=\"660\">" & return
set MP4header to MP4header & "<TextSampleDescription horizontalJustification=\"center\" verticalJustification=\"bottom\" backColor=\"0 0 0 0\" verticalText=\"no\" fillTextRegion=\"no\" continuousKaraoke=\"no\" scroll=\"None\">" & return
set MP4header to MP4header & "<FontTable>" & return
set MP4header to MP4header & "<FontTableEntry fontName=\"Serif\" fontID=\"1\"/>" & return
set MP4header to MP4header & "</FontTable>" & return
set MP4header to MP4header & "<TextBox top=\"0\" left=\"0\" bottom=\"60\" right=\"400\"/>" & return
set MP4header to MP4header & "<Style styles=\"Normal\" fontID=\"1\" fontSize=\"18\" color=\"ff ff ff ff\"/>" & return
set MP4header to MP4header & "</TextSampleDescription>" & return
set MP4header to MP4header & "</TextStreamHeader>"
end setMP4header
--Subroutine to write XML footer for Flash captions
on setMP4Footer(outMP4)
--this first line sets a final TextSample line with empty text; otherwise the last line of text stays up through the end of the video file.
set MP4footer to "<TextSample sampleTime=\"" & outMP4 & "\" text=\"' '\">" & return
set MP4footer to MP4footer & "</TextSample>" & return
set MP4footer to MP4footer & "</TextStream>" & return
end setMP4Footer