Actually fixes #11  :)

Actually fixes #11  :)

--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value
    property radioType : missing value
    property progressField : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""
    property missingPackages : ""
    property mediaTypeText : ""

    -- This set is for the tags
    property fcatName : ""
    property fcatArtist : ""
    property fcatAlbum : ""
    property fcatComposer : ""
    property fcatGenre : ""
    property fcatTrack : ""
    property fcatTracks : ""
    property fcatDisc : ""
    property fcatDiscs : ""
    property fcatAlbumArtist : ""
    property fcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        -- Check for FFMPEG in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            set missingPackages to "FFMPEG "
            set ffmpegmissing to 1
        end try

        -- Check for MP4v2 in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            if ffmpegmissing is 1 then
                set missingPackages to "FFMPEG MP4v2"
            else
                set missingPackages to "MP4v2 "
            end if
        end try

        if missingPackages is not "" then
            display dialog "You must install the following programs to continue: \n\t" & missingPackages & " \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            if result = {button returned:"Install"} then
                tell application "Terminal"
                    set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew install ffmpeg mp4v2 && exit 0;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"; brew install ffmpeg mp4v2 && exit 0;fi"
                    delay 1
                    activate
                    -- Check for when the Terminal is done
                    try
                        repeat
                            delay 0.2
                            if not busy of newTab then exit repeat
                        end repeat
                    end try
                end tell
                -- Check if installation was successful
                try
                    do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" -a -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
                    tell application "Terminal" to quit
                    activate
                    display dialog "Installation was successful!" buttons {"OK"} default button "OK"
                    on error error_number
                    activate
                    display dialog "Homebrew, FFMPEG and/or MP4v2 could not be installed."
                end try
                else if result = {button returned:"Quit"} then
                tell me to quit
            end if
        end if
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
        -- Reset the name and track fields
        catName's setStringValue_("")
        catTrack's setStringValue_("")
        catTracks's setStringValue_("")
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        if catName's stringValue() is not "" then set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        set mediaTypeText to (radioType's titleOfSelectedItem()) as string

        try
            do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4* /private/tmp/cat.mp4"
        end try
        set errorHappened to false
        -- Create the intermediate files
        try
            repeat with theIndex in the_index
                progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -i \"" & (item theIndex of these_files as text) & "\" -c copy -f mpegts -loglevel fatal -vn /private/tmp/concat" & theIndex & ".ts" as text)
                set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
            end repeat
        on error error_number
            set errorHappened to true
            do shell script "/bin/rm -f /private/tmp/concat*"
            progressField's setStringValue_("")
            display dialog "The tracks you selected could not be joined. Only mp4 files encoded as AAC can be joined presently."
        end try
        -- Run the actual concatenation command in ffmpeg (for mp4/AAC files only!)
        -- via https://trac.ffmpeg.org/wiki/How%20to%20concatenate%20(join,%20merge)%20media%20files
        if not errorHappened then
            try
                set olddelimeters to AppleScript's text item delimiters
                set AppleScript's text item delimiters to "|"
                set disp_thepipes to the_pipes as string
                progressField's setStringValue_("Concatenating tracks...")
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc -loglevel fatal /private/tmp/cat.mp4" as text)
                set AppleScript's text item delimiters to olddelimeters
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4"
                progressField's setStringValue_("")
                display dialog "The tracks could not be joined."
            end try
        end if
        -- Now let's create the chapter file
        if not errorHappened then
            progressField's setStringValue_("Preparing chapters...")
            delay 0.2
            try
                repeat with theIndex in the_index
                    if theIndex < 2 then
                        do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                        set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
                    else
                        set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                        do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                        set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                        set theCounter to (theCounter + theNewCounter)
                    end if
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be read from the tracks you had selected."
            end try
        end if
        -- Chapterize cat.mp4
        if not errorHappened then
            try
                progressField's setStringValue_("Chapterizing...")
                delay 0.2
                do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be added to concatenated file."
            end try
        end if
        -- Prepare tags
        if pcatName is not "" then set fcatName to (" -song \"" & pcatName & "\" ")
        if fcatName contains "\"\"" then set fcatName to ""
        if pcatAlbum is not "" then set fcatAlbum to (" -album \"" & pcatAlbum & "\" ")
        if fcatAlbum contains "\"\"" then set fcatAlbum to ""
        if pcatArtist is not "" then set fcatArtist to (" -artist \"" & pcatArtist & "\" ")
        if fcatArtist contains "\"\"" then set fcatArtist to ""
        if pcatComposer is not "" then set fcatComposer to (" -writer \"" & pcatComposer & "\" ")
        if fcatComposer contains "\"\"" then set fcatComposer to ""
        if pcatGenre is not "" then set fcatGenre to (" -genre \"" & pcatGenre & "\" ")
        if fcatGenre contains "\"\"" then set fcatGenre to ""
        if pcatTrack is not "" then set fcatTrack to (" -track \"" & pcatTrack & "\" ")
        if fcatTrack contains "\"\"" then set fcatTrack to ""
        if pcatTracks is not "" then set fcatTracks to (" -tracks \"" & pcatTracks & "\" ")
        if fcatTracks contains "\"\"" then set fcatTracks to ""
        if pcatDisc is not "" then set fcatDisc to (" -disk \"" & pcatDisc & "\" ")
        if fcatDisc contains "\"\"" then set fcatDisc to ""
        if pcatDiscs is not "" then set fcatDiscs to (" -disks \"" & pcatDiscs & "\" ")
        if fcatDiscs contains "\"\"" then set fcatDiscs to ""
        if pcatAlbumArtist is not "" then set fcatAlbumArtist to (" -albumartist \"" & pcatAlbumArtist & "\" ")
        if fcatAlbumArtist contains "\"\"" then set fcatAlbumArtist to ""
        if pcatYear is not "" then set fcatYear to (" -year \"" & pcatYear & "\" ")
        if fcatYear contains "\"\"" then set fcatYear to ""
        -- Add tags
        if not errorHappened then
            try
                progressField's setStringValue_("Adding tags...")
                delay 0.2
                do shell script (cmdPrefix & "mp4tags " & fcatName & fcatAlbum & fcatArtist & fcatComposer & fcatGenre & fcatTrack & fcatTracks & fcatDisc & fcatDiscs & fcatAlbumArtist & fcatYear & " /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The tags could not be added to the concatenated audio file."
            end try
        end if
        -- Add the finished track to iTunes
        if not errorHappened then
            progressField's setStringValue_("Adding to iTunes...")
            delay 0.2
            try
                if mediaTypeText is "Music track" then
                    set mediaType to "m4a"
                else if mediaTypeText is "Audiobook track" then
                    set mediaType to "m4b"
                end if
                do shell script ("/bin/mv /private/tmp/cat.mp4 /private/tmp/cat." & mediaType as text)
                tell application "iTunes"
                    add file (":private:tmp:cat." & mediaType as text)
                end tell
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt /private/tmp/cat." & mediaType
                progressField's setStringValue_("")
                display dialog "The concatenated file could not be added to iTunes."
            end try
        end if
        -- Clean up
        do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4*"
        set theCounter to ""
        progressField's setStringValue_("")
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
        -- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script

--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value
    property radioType : missing value
    property progressField : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""
    property missingPackages : ""
    property mediaTypeText : ""

    -- This set is for the tags
    property fcatName : ""
    property fcatArtist : ""
    property fcatAlbum : ""
    property fcatComposer : ""
    property fcatGenre : ""
    property fcatTrack : ""
    property fcatTracks : ""
    property fcatDisc : ""
    property fcatDiscs : ""
    property fcatAlbumArtist : ""
    property fcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        -- Check for FFMPEG in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            set missingPackages to "FFMPEG "
        end try

        -- Check for MP4v2 in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            if missingPackages is "FFMPEG" then
                set the end of missingPackages to "FFMPEG "
            else
                set missingPackages to "MP4v2 "
            end if
        end try

        if missingPackages is not "" then
            display dialog "You must install the following programs to continue: \n\t" & missingPackages & " \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            if result = {button returned:"Install"} then
                tell application "Terminal"
                    set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew install ffmpeg mp4v2 && exit 0;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"; brew install ffmpeg mp4v2 && exit 0;fi"
                    delay 1
                    activate
                    -- Check for when the Terminal is done
                    try
                        repeat
                            delay 0.2
                            if not busy of newTab then exit repeat
                        end repeat
                    end try
                end tell
                -- Check if installation was successful
                try
                    do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" -a -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
                    tell application "Terminal" to quit
                    activate
                    display dialog "Installation was successful!" buttons {"OK"} default button "OK"
                    on error error_number
                    activate
                    display dialog "Homebrew, FFMPEG and/or MP4v2 could not be installed."
                end try
                else if result = {button returned:"Quit"} then
                tell me to quit
            end if
        end if
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
        -- Reset the name and track fields
        catName's setStringValue_("")
        catTrack's setStringValue_("")
        catTracks's setStringValue_("")
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        if catName's stringValue() is not "" then set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        set mediaTypeText to (radioType's titleOfSelectedItem()) as string

        try
            do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4* /private/tmp/cat.mp4"
        end try
        set errorHappened to false
        -- Create the intermediate files
        try
            repeat with theIndex in the_index
                progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -i \"" & (item theIndex of these_files as text) & "\" -c copy -f mpegts -loglevel fatal -vn /private/tmp/concat" & theIndex & ".ts" as text)
                set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
            end repeat
        on error error_number
            set errorHappened to true
            do shell script "/bin/rm -f /private/tmp/concat*"
            progressField's setStringValue_("")
            display dialog "The tracks you selected could not be joined. Only mp4 files encoded as AAC can be joined presently."
        end try
        -- Run the actual concatenation command in ffmpeg (for mp4/AAC files only!)
        -- via https://trac.ffmpeg.org/wiki/How%20to%20concatenate%20(join,%20merge)%20media%20files
        if not errorHappened then
            try
                set olddelimeters to AppleScript's text item delimiters
                set AppleScript's text item delimiters to "|"
                set disp_thepipes to the_pipes as string
                progressField's setStringValue_("Concatenating tracks...")
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc -loglevel fatal /private/tmp/cat.mp4" as text)
                set AppleScript's text item delimiters to olddelimeters
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4"
                progressField's setStringValue_("")
                display dialog "The tracks could not be joined."
            end try
        end if
        -- Now let's create the chapter file
        if not errorHappened then
            progressField's setStringValue_("Preparing chapters...")
            delay 0.2
            try
                repeat with theIndex in the_index
                    if theIndex < 2 then
                        do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                        set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
                    else
                        set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                        do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                        set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                        set theCounter to (theCounter + theNewCounter)
                    end if
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be read from the tracks you had selected."
            end try
        end if
        -- Chapterize cat.mp4
        if not errorHappened then
            try
                progressField's setStringValue_("Chapterizing...")
                delay 0.2
                do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be added to concatenated file."
            end try
        end if
        -- Prepare tags
        if pcatName is not "" then set fcatName to (" -song \"" & pcatName & "\" ")
        if fcatName contains "\"\"" then set fcatName to ""
        if pcatAlbum is not "" then set fcatAlbum to (" -album \"" & pcatAlbum & "\" ")
        if fcatAlbum contains "\"\"" then set fcatAlbum to ""
        if pcatArtist is not "" then set fcatArtist to (" -artist \"" & pcatArtist & "\" ")
        if fcatArtist contains "\"\"" then set fcatArtist to ""
        if pcatComposer is not "" then set fcatComposer to (" -writer \"" & pcatComposer & "\" ")
        if fcatComposer contains "\"\"" then set fcatComposer to ""
        if pcatGenre is not "" then set fcatGenre to (" -genre \"" & pcatGenre & "\" ")
        if fcatGenre contains "\"\"" then set fcatGenre to ""
        if pcatTrack is not "" then set fcatTrack to (" -track \"" & pcatTrack & "\" ")
        if fcatTrack contains "\"\"" then set fcatTrack to ""
        if pcatTracks is not "" then set fcatTracks to (" -tracks \"" & pcatTracks & "\" ")
        if fcatTracks contains "\"\"" then set fcatTracks to ""
        if pcatDisc is not "" then set fcatDisc to (" -disk \"" & pcatDisc & "\" ")
        if fcatDisc contains "\"\"" then set fcatDisc to ""
        if pcatDiscs is not "" then set fcatDiscs to (" -disks \"" & pcatDiscs & "\" ")
        if fcatDiscs contains "\"\"" then set fcatDiscs to ""
        if pcatAlbumArtist is not "" then set fcatAlbumArtist to (" -albumartist \"" & pcatAlbumArtist & "\" ")
        if fcatAlbumArtist contains "\"\"" then set fcatAlbumArtist to ""
        if pcatYear is not "" then set fcatYear to (" -year \"" & pcatYear & "\" ")
        if fcatYear contains "\"\"" then set fcatYear to ""
        -- Add tags
        if not errorHappened then
            try
                progressField's setStringValue_("Adding tags...")
                delay 0.2
                do shell script (cmdPrefix & "mp4tags " & fcatName & fcatAlbum & fcatArtist & fcatComposer & fcatGenre & fcatTrack & fcatTracks & fcatDisc & fcatDiscs & fcatAlbumArtist & fcatYear & " /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The tags could not be added to the concatenated audio file."
            end try
        end if
        -- Add the finished track to iTunes
        if not errorHappened then
            progressField's setStringValue_("Adding to iTunes...")
            delay 0.2
            try
                if mediaTypeText is "Music track" then
                    set mediaType to "m4a"
                else if mediaTypeText is "Audiobook track" then
                    set mediaType to "m4b"
                end if
                do shell script ("/bin/mv /private/tmp/cat.mp4 /private/tmp/cat." & mediaType as text)
                tell application "iTunes"
                    add file (":private:tmp:cat." & mediaType as text)
                end tell
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt /private/tmp/cat." & mediaType
                progressField's setStringValue_("")
                display dialog "The concatenated file could not be added to iTunes."
            end try
        end if
        -- Clean up
        do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4*"
        set theCounter to ""
        progressField's setStringValue_("")
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
        -- Insert code here to initialize your application before any files are opened
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script


- convert to unix newlines to that I can edit it and valid patches can be made   against it.  It was appearing as one gigantic line.  I hope this doesn't   break anything.

property bochs_path : "bochs.app/Contents/MacOS/bochs"

set script_name to name of (info for (path to me))
set script_path to POSIX path of (path to me)

-- replace target string using delimiters
set AppleScript's text item delimiters to the script_name
set the text_item_list to every text item of the script_path
set AppleScript's text item delimiters to ""
set the script_path to the text_item_list as string

tell application "Terminal"
	activate
	do script "cd " & script_path & ";" & bochs_path
	-- Wait for Terminal to change the name first, then change it to ours
	delay 1
	set AppleScript's text item delimiters to "/"
	set the text_item_list to every text item of the script_path
	set AppleScript's text item delimiters to ""
	set next_to_last to ((count of text_item_list) - 1)
	set the folder_name to item next_to_last of text_item_list
	set name of front window to "Running bochs in ../" & folder_name & "/"
end tell


Remove my $PATH setting from default apple script

# AppleScript folder action for the pdfmatch command
#
# Open with script editor, compile and save to
# ~/Library/Workflows/Applications/Folder\ Actions/
#
# Then open the "Folder Actions Setup" application and add the work folder
# where your pdfmatch.json config lives and attach this script.
#
on adding folder items to this_folder after receiving these_files
	try
		repeat with each_file in these_files
			tell application "System Events"
				if name extension of each_file is "pdf" or "tif" or "tiff" or "jpeg" or "jpg" then
					# You might need to add your node binary to your $PATH. For example:
					# export PATH=/usr/local/bin:/usr/local/opt/node@6/bin:$PATH
					set output to (do shell script "cd '" & POSIX path of this_folder & "' && pdfmatch '" & POSIX path of each_file & "' --delete 2>&1")
					#display alert output
				end if
			end tell
		end repeat
	on error err_string number error_number
		display alert "Error " & error_number & ": " & err_string
	end try
end adding folder items to

# AppleScript folder action for the pdfmatch command
#
# Open with script editor, compile and save to
# ~/Library/Workflows/Applications/Folder\ Actions/
#
# Then open the "Folder Actions Setup" application and add the work folder
# where your pdfmatch.json config lives and attach this script.
#
on adding folder items to this_folder after receiving these_files
	try
		repeat with each_file in these_files
			tell application "System Events"
				if name extension of each_file is "pdf" or "tif" or "tiff" or "jpeg" or "jpg" then
					# You might need to add your node binary to your $PATH. For example:
					# export PATH=/usr/local/bin:/usr/local/opt/node@6/bin:$PATH
					set output to (do shell script "export PATH=/usr/local/bin:/usr/local/opt/node@6/bin:$PATH && cd '" & POSIX path of this_folder & "' && pdfmatch '" & POSIX path of each_file & "' --delete 2>&1")
					#display alert output
				end if
			end tell
		end repeat
	on error err_string number error_number
		display alert "Error " & error_number & ": " & err_string
	end try
end adding folder items to


remove the return value so it doesnt get into the stream

-- thumbscrew.scpt
-- usage: thumbscript.scpt <path_to_root_dir> <path_to_keynotePresentation> <presentation_name>
--
-- Will create scaled thumbnails of length `thumbSize` in the directory
-- <path_to_root_dir>/.keynote/<presentation>
property thumbSize : 480
property thumbnailDir: "keynotes"

on getImages(f)
  tell application "Finder" to return (files of folder f) as alias list
end getImages

on run argv
  set gitRoot to item 1 of argv
  set tmpFile to item 2 of argv
  set documentName to item 3 of argv
  if documentName ends with ".key" then set documentName to text 1 thru -5 of documentName

  set gitRoot to posix file (POSIX path of (gitRoot as text) & "/" & thumbnailDir) as alias
  set tmpFile to (POSIX file tmpFile) as alias

  tell application "Keynote"
    activate
    open tmpFile

    if playing is true then stop the front document

    tell application "Finder"
      if not (exists folder documentName of folder gitRoot)
        make new folder at gitRoot with properties {name:documentName}
      end if
      set the targetFolder to folder documentName of folder gitRoot
      set the targetFolderHFSPath to targetFolder as string
    end tell

    export front document as slide images to file targetFolderHFSPath with properties {image format: JPEG}
    set jpegs to my getImages(targetFolderHFSPath)
    repeat with thisJPEG in jpegs
      try
        tell application "Image Events"
          launch
          set this_image to open thisJPEG
          scale this_image to size thumbSize
          save this_image with icon
          close this_image
        end tell
        on error error_message
          display dialog error_message
      end try
    end repeat

    close front document without saving
  end tell
end run

-- thumbscrew.scpt
-- usage: thumbscript.scpt <path_to_root_dir> <path_to_keynotePresentation> <presentation_name>
--
-- Will create scaled thumbnails of length `thumbSize` in the directory
-- <path_to_root_dir>/.keynote/<presentation>
property thumbSize : 480
property thumbnailDir: "keynotes"

on getImages(f)
  tell application "Finder" to return (files of folder f) as alias list
end getImages

on run argv
  set gitRoot to item 1 of argv
  set tmpFile to item 2 of argv
  set documentName to item 3 of argv
  if documentName ends with ".key" then set documentName to text 1 thru -5 of documentName

  set gitRoot to posix file (POSIX path of (gitRoot as text) & "/" & thumbnailDir) as alias
  set tmpFile to (POSIX file tmpFile) as alias

  tell application "Keynote"
    activate
    open tmpFile

    if playing is true then stop the front document

    tell application "Finder"
      if not (exists folder documentName of folder gitRoot)
        make new folder at gitRoot with properties {name:documentName}
      end if
      set the targetFolder to folder documentName of folder gitRoot
      set the targetFolderHFSPath to targetFolder as string
    end tell

    export front document as slide images to file targetFolderHFSPath with properties {image format: JPEG}
    set jpegs to my getImages(targetFolderHFSPath)
    repeat with thisJPEG in jpegs
      try
        tell application "Image Events"
          launch
          set this_image to open thisJPEG
          scale this_image to size thumbSize
          save this_image with icon
          close this_image
        end tell
        on error error_message
          display dialog error_message
      end try
    end repeat

    close front document without saving
  end tell
  return POSIX path of gitRoot
end run


Delete Alfred Play Song playlist when clearing cache

This is becoming a helpful step when troubleshooting any issues.

-- clears workflow cache, including album artwork and compiled scripts --

on loadConfig()
	return (load script POSIX file (do shell script "./resources/compile-config.sh"))
end loadConfig

on run query
	set config to loadConfig()
	try
		tell application "Finder"
			delete folder (workflowCacheFolder of config)
		end tell
		tell application "Music"
			delete user playlist (workflowPlaylistName of config)
		end tell
	end try
end run

-- clears workflow cache, including album artwork and compiled scripts --

on loadConfig()
	return (load script POSIX file (do shell script "./resources/compile-config.sh"))
end loadConfig

on run query
	set config to loadConfig()
	try
		tell application "Finder"
			delete folder (workflowCacheFolder of config)
		end tell
	end try
end run


More robust paths, removed debug dialog

More robust paths, removed debug dialog

--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value
    property radioType : missing value
    property progressField : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""
    property missingPackages : ""
    property mediaTypeText : ""

    -- This set is for the tags
    property fcatName : ""
    property fcatArtist : ""
    property fcatAlbum : ""
    property fcatComposer : ""
    property fcatGenre : ""
    property fcatTrack : ""
    property fcatTracks : ""
    property fcatDisc : ""
    property fcatDiscs : ""
    property fcatAlbumArtist : ""
    property fcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property quitme : 0

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        -- Check for FFMPEG in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            set missingPackages to "FFMPEG "
            set ffmpegmissing to 1
        end try

        -- Check for MP4v2 in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            if ffmpegmissing is 1 then
                set missingPackages to "FFMPEG MP4v2"
            else
                set missingPackages to "MP4v2 "
            end if
        end try

        if missingPackages is not "" then
            display dialog "You must install the following programs to continue: \n\t" & missingPackages & " \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            if result = {button returned:"Install"} then
                tell application "Terminal"
                    set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew update;brew prune;brew install ffmpeg mp4v2 && exit 0;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\";brew update;brew prune;brew install ffmpeg mp4v2 && exit 0;fi"
                    delay 1
                    activate
                    -- Check for when the Terminal is done
                    try
                        repeat
                            delay 0.2
                            if not busy of newTab then exit repeat
                        end repeat
                    end try
                end tell
                -- Check if installation was successful
                try
                    do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" -a -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
                    tell application "Terminal" to quit
                    activate
                    display dialog "Installation was successful!" buttons {"OK"} default button "OK"
                    on error error_number
                    activate
                    display dialog "Homebrew, FFMPEG and/or MP4v2 could not be installed."
                    set quitme to 1 -- Exit if we couldn't install!
                end try
                else if result = {button returned:"Quit"} then
                    set quitme to 1
                    return current application's NSTerminateNow
            end if
        end if
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
        -- Reset the name and track fields
        catName's setStringValue_("")
        catTrack's setStringValue_("")
        catTracks's setStringValue_("")
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        if catName's stringValue() is not "" then set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        set mediaTypeText to (radioType's titleOfSelectedItem()) as string

        try
            do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4* /private/tmp/cat.mp4"
        end try
        -- Initialize the error variables
        set errorHappened to false
        set notaac to false
         -- Check if the audio files are all aac / mp4a
        repeat with theIndex in the_index
            try
                do shell script (cmdPrefix & "if [ `ffprobe -show_streams -select_streams a " & (quoted form of POSIX path of (item theIndex of these_files as text)) & "  2>/dev/null | grep -c \"mp4a\\|aac\"` -gt 0 ]; then exit 0; else exit 1; fi")
            on error number error_number
                set notaac to true
            end try
        end repeat
        -- Create the concatenated intermediate file
        if not notaac then
            -- Concatenation routine for mp4/aac files
            try
                repeat with theIndex in the_index
                    progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                    delay 0.2
                    do shell script (cmdPrefix & "ffmpeg -i " & (quoted form of POSIX path of (item theIndex of these_files as text)) & " -c copy -f mpegts -loglevel fatal -vn /private/tmp/concat" & theIndex & ".ts" as text)
                    set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat*"
                progressField's setStringValue_("")
                display dialog "The tracks you selected could not be joined. An error occured when preparing the intermediate files."
            end try
            try
                set olddelimeters to AppleScript's text item delimiters
                set AppleScript's text item delimiters to "|"
                set disp_thepipes to the_pipes as string
                progressField's setStringValue_("Concatenating tracks...")
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc -loglevel fatal /private/tmp/cat.mp4" as text)
                set AppleScript's text item delimiters to olddelimeters
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4"
                progressField's setStringValue_("")
                display dialog "The tracks could not be joined."
            end try
            else
            -- Concatenation routine for non-mp4/aac audio files
            try
                repeat with theIndex in the_index
                    progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                    delay 0.2
                    -- No spaces allowed in paths for the script...
                    do shell script ("/bin/cp " & (quoted form of POSIX path of (item theIndex of these_files as text)) & " /private/tmp/concat" & theIndex & ".ts" as text)
                    set end of the_pipes to ("concat" & theIndex & ".ts" as text)
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat*"
                progressField's setStringValue_("")
                display dialog "The tracks you selected could not be joined."
            end try
            set olddelimeters to AppleScript's text item delimiters
            set AppleScript's text item delimiters to " "
            set disp_thepipes to the_pipes as string
            progressField's setStringValue_("Concatenating tracks...")
            delay 0.2
            try
                set scriptpath to (quoted form of POSIX path of (current application's NSBundle's mainBundle()'s bundlePath() as text & "/Contents/Resources/mmcat.sh")) & " "
                do shell script ("cd /private/tmp && " & scriptpath & (disp_thepipes as text) & " cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4"
                progressField's setStringValue_("")
                display dialog "The tracks could not be joined. An error occured during the reencoding."
            end try
            set AppleScript's text item delimiters to olddelimeters
        end if
        -- Now let's create the chapter file
        if not errorHappened then
            progressField's setStringValue_("Preparing chapters...")
            delay 0.2
            try
                repeat with theIndex in the_index
                    if theIndex < 2 then
                        do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                        set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
                    else
                        set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                        do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                        set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                        set theCounter to (theCounter + theNewCounter)
                    end if
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be read from the tracks you had selected."
            end try
        end if
        -- Chapterize cat.mp4
        if not errorHappened then
            try
                progressField's setStringValue_("Chapterizing...")
                delay 0.2
                do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be added to concatenated file."
            end try
        end if
        -- Prepare tags
        if pcatName is not "" then set fcatName to (" -song " & quoted form of (pcatName as text) & " ")
        if fcatName contains "\"\"" then set fcatName to ""
        if pcatAlbum is not "" then set fcatAlbum to (" -album " & quoted form of (pcatAlbum as text) & " ")
        if fcatAlbum contains "\"\"" then set fcatAlbum to ""
        if pcatArtist is not "" then set fcatArtist to (" -artist " & quoted form of (pcatArtist as text) & " ")
        if fcatArtist contains "\"\"" then set fcatArtist to ""
        if pcatComposer is not "" then set fcatComposer to (" -writer " & quoted form of (pcatComposer as text) & " ")
        if fcatComposer contains "\"\"" then set fcatComposer to ""
        if pcatGenre is not "" then set fcatGenre to (" -genre " & quoted form of (pcatGenre as text) & " ")
        if fcatGenre contains "\"\"" then set fcatGenre to ""
        if pcatTrack is not "" then set fcatTrack to (" -track \"" & pcatTrack & "\" ")
        if fcatTrack contains "\"\"" then set fcatTrack to ""
        if pcatTracks is not "" then set fcatTracks to (" -tracks \"" & pcatTracks & "\" ")
        if fcatTracks contains "\"\"" then set fcatTracks to ""
        if pcatDisc is not "" then set fcatDisc to (" -disk \"" & pcatDisc & "\" ")
        if fcatDisc contains "\"\"" then set fcatDisc to ""
        if pcatDiscs is not "" then set fcatDiscs to (" -disks \"" & pcatDiscs & "\" ")
        if fcatDiscs contains "\"\"" then set fcatDiscs to ""
        if pcatAlbumArtist is not "" then set fcatAlbumArtist to (" -albumartist " & quoted form of (pcatAlbumArtist as text) & " ")
        if fcatAlbumArtist contains "\"\"" then set fcatAlbumArtist to ""
        if pcatYear is not "" then set fcatYear to (" -year \"" & pcatYear & "\" ")
        if fcatYear contains "\"\"" then set fcatYear to ""
        -- Add tags
        if not errorHappened then
            try
                progressField's setStringValue_("Adding tags...")
                delay 0.2
                do shell script (cmdPrefix & "mp4tags " & fcatName & fcatAlbum & fcatArtist & fcatComposer & fcatGenre & fcatTrack & fcatTracks & fcatDisc & fcatDiscs & fcatAlbumArtist & fcatYear & " /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The tags could not be added to the concatenated audio file."
            end try
        end if
        -- Add the finished track to iTunes
        if not errorHappened then
            progressField's setStringValue_("Adding to iTunes...")
            delay 0.2
            try
                if mediaTypeText is "Music track" then
                    set mediaType to "m4a"
                else if mediaTypeText is "Audiobook track" then
                    set mediaType to "m4b"
                end if
                do shell script ("/bin/mv /private/tmp/cat.mp4 /private/tmp/cat." & mediaType as text)
                tell application "iTunes"
                    add file (":private:tmp:cat." & mediaType as text)
                end tell
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt /private/tmp/cat." & mediaType
                progressField's setStringValue_("")
                display dialog "The concatenated file could not be added to iTunes."
            end try
        end if
        -- Clean up
        do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4*"
        set theCounter to ""
        progressField's setStringValue_("")
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
        -- Insert code here to initialize your application before any files are opened
        if quitme is 1 then
            tell me to quit
        end if
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script

--
--  DASAppDelegate.applescript
--  itunes-concatenator
--
--  Created by David Schlachter on 2014-08-26.
--  Copyright (c) 2014 Red Eft Software. All rights reserved.
--

-- via http://macscripter.net/viewtopic.php?pid=173787 ; apparently needed for using arrays

script DASAppDelegate
	property parent : class "NSObject"

    global these_files, these_times, these_titles, the_index, the_pipes, theCounter, cmdPrefix

	-- IBOutlets
	property window : missing value
    property trackTable : missing value
    property catName : missing value
    property catArtist : missing value
    property catAlbum : missing value
    property catComposer : missing value
    property catGenre : missing value
    property catTrack : missing value
    property catTracks : missing value
    property catDisc : missing value
    property catDiscs : missing value
    property catAlbumArtist : missing value
    property catYear : missing value
    property radioType : missing value
    property progressField : missing value

    -- Again, per macscripter, we'll set up bindings for the options
    property pcatName : ""
    property pcatArtist : ""
    property pcatAlbum : ""
    property pcatComposer : ""
    property pcatGenre : ""
    property pcatTrack : ""
    property pcatTracks : ""
    property pcatDisc : ""
    property pcatDiscs : ""
    property pcatAlbumArtist : ""
    property pcatYear : ""
    property missingPackages : ""
    property mediaTypeText : ""

    -- This set is for the tags
    property fcatName : ""
    property fcatArtist : ""
    property fcatAlbum : ""
    property fcatComposer : ""
    property fcatGenre : ""
    property fcatTrack : ""
    property fcatTracks : ""
    property fcatDisc : ""
    property fcatDiscs : ""
    property fcatAlbumArtist : ""
    property fcatYear : ""

    -- Empty strings for each file name and location
    property pEachName : ""
    property pEachLocation : ""

    property these_titles : {}
    property these_files : {}
    property these_times: {}
    property the_index: {}
    property the_pipes: {}

    property quitme : 0

    property theCounter : ""
    property cmdPrefix : "if [[ -r /etc/profile ]];then . /etc/profile;fi;if [[ -r ~/.bashrc ]];then . ~/.bashrc;fi;if [[ -r ~/.bash_profile ]];then . ~/.bash_profile;fi;"

    on awakeFromNib()
        -- Check for FFMPEG in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            set missingPackages to "FFMPEG "
            set ffmpegmissing to 1
        end try

        -- Check for MP4v2 in the path
        try
            do shell script cmdPrefix & " if [ -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
            on error number error_number
            if ffmpegmissing is 1 then
                set missingPackages to "FFMPEG MP4v2"
            else
                set missingPackages to "MP4v2 "
            end if
        end try

        if missingPackages is not "" then
            display dialog "You must install the following programs to continue: \n\t" & missingPackages & " \n\nYou may have to install Xcode Command Line Tools and Homebrew first. If you continue, we'll attempt to install them for you if they are not already present. \n\nIf you have already installed FFMPEG and MP4v2, ensure that they are in your bash path." buttons {"Quit","Install"} default button 2
            if result = {button returned:"Install"} then
                tell application "Terminal"
                    set newTab to do script cmdPrefix & "if [[ -x `which brew` ]];then brew update;brew prune;brew install ffmpeg mp4v2 && exit 0;else /usr/bin/ruby -e \"$(/usr/bin/curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\";brew update;brew prune;brew install ffmpeg mp4v2 && exit 0;fi"
                    delay 1
                    activate
                    -- Check for when the Terminal is done
                    try
                        repeat
                            delay 0.2
                            if not busy of newTab then exit repeat
                        end repeat
                    end try
                end tell
                -- Check if installation was successful
                try
                    do shell script cmdPrefix & " if [ -x \"`/usr/bin/which ffmpeg`\" -a -x \"`/usr/bin/which mp4chaps`\" ];then exit 0;else exit 1;fi"
                    tell application "Terminal" to quit
                    activate
                    display dialog "Installation was successful!" buttons {"OK"} default button "OK"
                    on error error_number
                    activate
                    display dialog "Homebrew, FFMPEG and/or MP4v2 could not be installed."
                    set quitme to 1 -- Exit if we couldn't install!
                end try
                else if result = {button returned:"Quit"} then
                    set quitme to 1
                    return current application's NSTerminateNow
            end if
        end if
    end awakeFromNib

    on btnGetTracks_(sender)
        -- Code to add iTunes tracks to our list
        -- via http://dougscripts.com/itunes/itinfo/info02.php and http://www.randomsequence.com/articles/applescript-to-send-selected-itunes-tracks-using-mail/
        tell application "iTunes"
            set these_titles to {}
            set these_times to {}
            set these_files to {}
            set the_index to {}
            if selection is not {} then -- there ARE tracks selected...
                set mySelection to selection
                set i to 1
                repeat with aTrack in mySelection
                    if class of aTrack is file track then
                        set end of these_titles to ((name of aTrack) as string)
                        set end of these_times to ((time of aTrack) as string)
                        set end of these_files to (posix path of (get location of aTrack))
                        set end of the_index to (count of these_titles)
                        -- Get metadata from the first track
                        if i is 1 then
                            set pcatArtist to ((artist of aTrack) as string)
                            set pcatAlbum to ((album of aTrack) as string)
                            set pcatComposer to ((composer of aTrack) as string)
                            set pcatGenre to ((genre of aTrack) as string)
                            set pcatDisc to ((disc number of aTrack) as string)
                            set pcatDiscs to ((disc count of aTrack) as string)
                            set pcatAlbumArtist to ((album artist of aTrack) as string)
                            set pcatYear to ((year of aTrack) as string)
                        end if
                        set i to (i + 1)
                    end if
                end repeat
            end if
        end tell
        -- Display the songs to be concatenated
        -- via http://stackoverflow.com/questions/25537750/setstringvalue-with-applescript-list
        set olddelimeters to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "\n"
        set disp_titles to these_titles as string
        trackTable's setStringValue_(disp_titles)
        set AppleScript's text item delimiters to olddelimeters
        -- Update the default metadata
        catArtist's setStringValue_(pcatArtist)
        catAlbum's setStringValue_(pcatAlbum)
        catComposer's setStringValue_(pcatComposer)
        catGenre's setStringValue_(pcatGenre)
        catDisc's setStringValue_(pcatDisc)
        catDiscs's setStringValue_(pcatDiscs)
        catAlbumArtist's setStringValue_(pcatAlbumArtist)
        catYear's setStringValue_(pcatYear)
        -- Reset the name and track fields
        catName's setStringValue_("")
        catTrack's setStringValue_("")
        catTracks's setStringValue_("")
    end btnGetTracks_

    on btnConcatenate_(sender)
        -- Update the metadata variables with the user's input
        if catName's stringValue() is not "" then set pcatName to catName's stringValue()
        set pcatArtist to catArtist's stringValue()
        set pcatAlbum to catAlbum's stringValue()
        set pcatComposer to catComposer's stringValue()
        set pcatGenre to catGenre's stringValue()
        set pcatTrack to catTrack's stringValue()
        set pcatTracks to catTracks's stringValue()
        set pcatDisc to catDisc's stringValue()
        set pcatDiscs to catDiscs's stringValue()
        set pcatAlbumArtist to catAlbumArtist's stringValue()
        set pcatYear to catYear's stringValue()
        set the_pipes to {}
        set mediaTypeText to (radioType's titleOfSelectedItem()) as string

        try
            do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4* /private/tmp/cat.mp4"
        end try
        -- Initialize the error variables
        set errorHappened to false
        set notaac to false
         -- Check if the audio files are all aac / mp4a
        repeat with theIndex in the_index
            try
                do shell script (cmdPrefix & "if [ `ffprobe -show_streams -select_streams a \"" & (item theIndex of these_files as text) & "\"  2>/dev/null | grep -c \"mp4a\\|aac\"` -gt 0 ]; then exit 0; else exit 1; fi")
            on error number error_number
                set notaac to true
            end try
        end repeat
        -- Create the concatenated intermediate file
        if not notaac then
            -- Concatenation routine for mp4/aac files
            try
                repeat with theIndex in the_index
                    progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                    delay 0.2
                    do shell script (cmdPrefix & "ffmpeg -i \"" & (item theIndex of these_files as text) & "\" -c copy -f mpegts -loglevel fatal -vn /private/tmp/concat" & theIndex & ".ts" as text)
                    set end of the_pipes to ("/private/tmp/concat" & theIndex & ".ts" as text)
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat*"
                progressField's setStringValue_("")
                display dialog "The tracks you selected could not be joined. An error occured when preparing the intermediate files."
            end try
            try
                set olddelimeters to AppleScript's text item delimiters
                set AppleScript's text item delimiters to "|"
                set disp_thepipes to the_pipes as string
                progressField's setStringValue_("Concatenating tracks...")
                delay 0.2
                do shell script (cmdPrefix & "ffmpeg -f mpegts -i \"concat:" & (disp_thepipes as text) & "\" -c copy -bsf:a aac_adtstoasc -loglevel fatal /private/tmp/cat.mp4" as text)
                set AppleScript's text item delimiters to olddelimeters
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4"
                progressField's setStringValue_("")
                display dialog "The tracks could not be joined."
            end try
            else
            -- Concatenation routine for non-mp4/aac audio files
            try
                repeat with theIndex in the_index
                    progressField's setStringValue_("Preparing track " & (theIndex as text) & "..." as text)
                    delay 0.2
                    -- No spaces allowed in paths for the script...
                    -- set end of the_pipes to (quoted form of POSIX path of (item theIndex of these_files as text))
                    do shell script (cmdPrefix & "cp " & (quoted form of POSIX path of (item theIndex of these_files as text)) & " /private/tmp/concat" & theIndex & ".ts" as text)
                    set end of the_pipes to ("concat" & theIndex & ".ts" as text)

                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat*"
                progressField's setStringValue_("")
                display dialog "The tracks you selected could not be joined."
            end try
            set olddelimeters to AppleScript's text item delimiters
            set AppleScript's text item delimiters to " "
            set disp_thepipes to the_pipes as string
            progressField's setStringValue_("Concatenating tracks...")
            delay 0.2

            set scriptpath to (quoted form of POSIX path of (current application's NSBundle's mainBundle()'s bundlePath() as text & "/Contents/Resources/mmcat.sh")) & " "
            -- set objectFolder to (path to me) as string
            display dialog (scriptpath & (disp_thepipes as text) & " cat.mp4" as text)
            do shell script ("cd /private/tmp && " & scriptpath & (disp_thepipes as text) & " cat.mp4" as text)

            set AppleScript's text item delimiters to olddelimeters
        end if
        -- Now let's create the chapter file
        if not errorHappened then
            progressField's setStringValue_("Preparing chapters...")
            delay 0.2
            try
                repeat with theIndex in the_index
                    if theIndex < 2 then
                        do shell script ("/bin/echo \"00:00:00.000 " & (item theIndex of these_titles as text) & "\" > /private/tmp/cat.chapters.txt" as text)
                        set theCounter to (do shell script (cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theCounter to (do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theCounter & "` * 1000\" | /usr/bin/bc))") as string)
                    else
                        set theDateStamp to do shell script (cmdPrefix & "t="& (theCounter as text) & ";((msec=t%1000, t/=1000, sec=t%60, t/=60, min=t%60, hrs=t/60));timestamp=$(printf \"%02d:%02d:%02d.%03d\" $hrs $min $sec $msec);/bin/echo $timestamp" as text)
                        do shell script ("/bin/echo \"" & (theDateStamp as text) & " " & (item theIndex of these_titles as text) & "\" >> /private/tmp/cat.chapters.txt" as text)
                        set theNewCounter to do shell script ((cmdPrefix & "ffprobe -loglevel panic -show_streams /private/tmp/concat" & (theIndex as text) & ".ts | egrep -m 1 'duration=[0-9]+\\.' | sed 's/duration=\\([0-9]*[0-9]\\.[0-9]*\\)/\\1/'" as text) as string)
                        set theNewCounter to do shell script ("/bin/echo $(/usr/bin/printf %.$2f $(/bin/echo \"`/usr/bin/printf %.3f " & theNewCounter & "` * 1000\" | /usr/bin/bc))") as string
                        set theCounter to (theCounter + theNewCounter)
                    end if
                end repeat
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be read from the tracks you had selected."
            end try
        end if
        -- Chapterize cat.mp4
        if not errorHappened then
            try
                progressField's setStringValue_("Chapterizing...")
                delay 0.2
                do shell script (cmdPrefix & "mp4chaps -i /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The chapters could not be added to concatenated file."
            end try
        end if
        -- Prepare tags
        if pcatName is not "" then set fcatName to (" -song " & quoted form of (pcatName as text) & " ")
        if fcatName contains "\"\"" then set fcatName to ""
        if pcatAlbum is not "" then set fcatAlbum to (" -album " & quoted form of (pcatAlbum as text) & " ")
        if fcatAlbum contains "\"\"" then set fcatAlbum to ""
        if pcatArtist is not "" then set fcatArtist to (" -artist " & quoted form of (pcatArtist as text) & " ")
        if fcatArtist contains "\"\"" then set fcatArtist to ""
        if pcatComposer is not "" then set fcatComposer to (" -writer " & quoted form of (pcatComposer as text) & " ")
        if fcatComposer contains "\"\"" then set fcatComposer to ""
        if pcatGenre is not "" then set fcatGenre to (" -genre " & quoted form of (pcatGenre as text) & " ")
        if fcatGenre contains "\"\"" then set fcatGenre to ""
        if pcatTrack is not "" then set fcatTrack to (" -track \"" & pcatTrack & "\" ")
        if fcatTrack contains "\"\"" then set fcatTrack to ""
        if pcatTracks is not "" then set fcatTracks to (" -tracks \"" & pcatTracks & "\" ")
        if fcatTracks contains "\"\"" then set fcatTracks to ""
        if pcatDisc is not "" then set fcatDisc to (" -disk \"" & pcatDisc & "\" ")
        if fcatDisc contains "\"\"" then set fcatDisc to ""
        if pcatDiscs is not "" then set fcatDiscs to (" -disks \"" & pcatDiscs & "\" ")
        if fcatDiscs contains "\"\"" then set fcatDiscs to ""
        if pcatAlbumArtist is not "" then set fcatAlbumArtist to (" -albumartist " & quoted form of (pcatAlbumArtist as text) & " ")
        if fcatAlbumArtist contains "\"\"" then set fcatAlbumArtist to ""
        if pcatYear is not "" then set fcatYear to (" -year \"" & pcatYear & "\" ")
        if fcatYear contains "\"\"" then set fcatYear to ""
        -- Add tags
        if not errorHappened then
            try
                progressField's setStringValue_("Adding tags...")
                delay 0.2
                do shell script (cmdPrefix & "mp4tags " & fcatName & fcatAlbum & fcatArtist & fcatComposer & fcatGenre & fcatTrack & fcatTracks & fcatDisc & fcatDiscs & fcatAlbumArtist & fcatYear & " /private/tmp/cat.mp4" as text)
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt"
                progressField's setStringValue_("")
                display dialog "The tags could not be added to the concatenated audio file."
            end try
        end if
        -- Add the finished track to iTunes
        if not errorHappened then
            progressField's setStringValue_("Adding to iTunes...")
            delay 0.2
            try
                if mediaTypeText is "Music track" then
                    set mediaType to "m4a"
                else if mediaTypeText is "Audiobook track" then
                    set mediaType to "m4b"
                end if
                do shell script ("/bin/mv /private/tmp/cat.mp4 /private/tmp/cat." & mediaType as text)
                tell application "iTunes"
                    add file (":private:tmp:cat." & mediaType as text)
                end tell
            on error error_number
                set errorHappened to true
                do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.mp4 /private/tmp/cat.chapters.txt /private/tmp/cat." & mediaType
                progressField's setStringValue_("")
                display dialog "The concatenated file could not be added to iTunes."
            end try
        end if
        -- Clean up
        do shell script "/bin/rm -f /private/tmp/concat* /private/tmp/cat.chapters.txt /private/tmp/cat.m4*"
        set theCounter to ""
        progressField's setStringValue_("")
    end btnConcatenate_

	on applicationWillFinishLaunching_(aNotification)
        -- Insert code here to initialize your application before any files are opened
        if quitme is 1 then
            tell me to quit
        end if
	end applicationWillFinishLaunching_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate_

end script


Fixed one problem with the dmg script: The Growl package is now named Growl.pkg, not Growl.mpkg as the script was expecting. This is what was causing the icon positions to not get set.

on run -- for testing in script editor
	process_disk_image("Growl", "/Users/evands/growl/Release/Artwork")
end run

on process_disk_image(volumeName, artPath)
	tell application "Finder"
		tell disk volumeName
			open
			tell container window
				set current view to icon view
				set toolbar visible to false
				set statusbar visible to false
				--set the bounds to {30, 50, 579, 600}
			end tell
			close
			set opts to the icon view options of container window
			tell opts
				set icon size to 64
				set arrangement to not arranged
			end tell
			set background picture of opts to file ".background:growlDMGBackground.png"
			set position of item "Growl.pkg" to {147, 75}
			set position of item "Extras" to {100, 320}
			--set position of item "Scripts" to {36, 153}
			set position of item "Growl Documentation.webloc" to {100, 218}
			set position of item "Growl version history.webloc" to {275, 218}
			set position of item "Get more styles.webloc" to {415, 218}
			set position of item "Uninstall Growl.app" to {415, 320}

			-- Custom icons
			my copyIconOfTo(artPath & "/GrowlIcon", "/Volumes/" & volumeName & "/Growl.mpkg")

			update without registering applications
			tell container window
				open
				set the_window_id to id
			end tell
			update without registering applications
		end tell
		set bounds of window id the_window_id to {30, 50, 575, 450}
		--give the finder some time to write the .DS_Store file
		delay 5
	end tell
end process_disk_image

on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
	tell application "Finder" to set f to POSIX file aFileOrFolderWithIcon as alias
	-- grab the file's icon
	my CopyOrPaste(f, "c")
	-- now the icon is in the clipboard
	tell application "Finder" to set c to POSIX file aFileOrFolder as alias
	my CopyOrPaste(result, "v")
end copyIconOfTo

on CopyOrPaste(i, cv)
	tell application "Finder"
		activate
		open information window of i
	end tell
	tell application "System Events" to tell process "Finder" to tell window 1
		keystroke tab -- select icon button
		keystroke (cv & "w") using command down (* (copy or paste) + close window *)
	end tell -- window 1 then process Finder then System Events
end CopyOrPaste

on run -- for testing in script editor
	process_disk_image("Growl", "/Users/evands/growl/Release/Artwork")
end run

on process_disk_image(volumeName, artPath)
	tell application "Finder"
		tell disk volumeName
			open
			tell container window
				set current view to icon view
				set toolbar visible to false
				set statusbar visible to false
				--set the bounds to {30, 50, 579, 600}
			end tell
			close
			set opts to the icon view options of container window
			tell opts
				set icon size to 64
				set arrangement to not arranged
			end tell
			set background picture of opts to file ".background:growlDMGBackground.png"
			set position of item "Growl.mpkg" to {147, 75}
			set position of item "Extras" to {100, 320}
			--set position of item "Scripts" to {36, 153}
			set position of item "Growl Documentation.webloc" to {100, 218}
			set position of item "Growl version history.webloc" to {275, 218}
			set position of item "Get more styles.webloc" to {415, 218}
			set position of item "Uninstall Growl.app" to {415, 320}

			-- Custom icons
			my copyIconOfTo(artPath & "/GrowlIcon", "/Volumes/" & volumeName & "/Growl.mpkg")

			update without registering applications
			tell container window
				open
				set the_window_id to id
			end tell
			update without registering applications
		end tell
		set bounds of window id the_window_id to {30, 50, 575, 450}
		--give the finder some time to write the .DS_Store file
		delay 5
	end tell
end process_disk_image

on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
	tell application "Finder" to set f to POSIX file aFileOrFolderWithIcon as alias
	-- grab the file's icon
	my CopyOrPaste(f, "c")
	-- now the icon is in the clipboard
	tell application "Finder" to set c to POSIX file aFileOrFolder as alias
	my CopyOrPaste(result, "v")
end copyIconOfTo

on CopyOrPaste(i, cv)
	tell application "Finder"
		activate
		open information window of i
	end tell
	tell application "System Events" to tell process "Finder" to tell window 1
		keystroke tab -- select icon button
		keystroke (cv & "w") using command down (* (copy or paste) + close window *)
	end tell -- window 1 then process Finder then System Events
end CopyOrPaste


activate htcLib so that dialog displays.

-- displayFileMakerDatabase({dbName:"", waitCycleDelaySeconds:"", waitSaveTotalSeconds:""})
-- Dan Shockley, NYHTC
-- If open, then display first window this finds and return true, else return false.

(*
HISTORY:
	1.6.3 - 2019-02-27 ( eshagdar ): throw up a dialog if there is a privSet violation.
	1.6.2 - 2018-12-07 ( eshagdar ): don't both using case, terms, or bundle ID - just talk to the application directly.
	1.6.1 - 2018-10-16 ( eshagdar ): remove remaining FMA references.
	1.6 - 2018-09-20 ( eshagdar ): FileMaker 17 has only version so talk to it by name.
	1.5.3 - 2018-01-18 ( eshagdar ): capture privSet violation error
	1.5.2 - 2017-11-20 ( eshagdar ): disable logging
	1.5.1 - 2017-10-25 ( eshagdar ): updated defaultPrefs. updated helper handlers. added delay, more debugging messages. get list of document names instead of documents - we don't need to get the name later.
	1.5 - added a time-out loop for dealing with delay in being able to get list of databases.
	1.4 - added error-handling
	1.3 -
	1.2 -
	1.1 -
	1.0 - created

REQUIRES:
	coerceToString
	logConsole
*)

property debugMode : true
property ScriptName : "displayFileMakerDatabase_TEST"

on run
	displayFileMakerDatabase({dbName:"a01_PERSON"})
end run

--------------------
-- START OF CODE
--------------------

on displayFileMakerDatabase(prefs)
	-- version 1.6.3

	try
		set defaultPrefs to {dbName:null, waitCycleDelaySeconds:5, waitSaveTotalSeconds:2 * minutes}
		set prefs to prefs & defaultPrefs

		--if debugMode then logConsole(ScriptName, "displayFileMakerDatabase prefs: " & coerceToString(prefs))

		set dbName to dbName of prefs

		set waitSaveTotalSeconds to waitSaveTotalSeconds of prefs
		set waitCycleDelaySeconds to waitCycleDelaySeconds of prefs
		set waitCycleMax to round (waitSaveTotalSeconds / waitCycleDelaySeconds) rounding down

		-- get name of all documents
		delay 0.25
		repeat waitCycleMax times
			set docNameList to null
			try
				using terms from application "FileMaker Pro Advanced"
					tell application ID "com.filemaker.client.pro12"
						set docNameList to name of every document
					end tell
				end using terms from

				if docNameList is not null then exit repeat
			on error errMsg number errNum
				if errNum is -10011 then
					-- just keep trying - this error can be caused when a database is opening and the open script takes a bit too long to finish, or something in the FM interface is slow to respond.
				else if errNum is -10004 then
					activate
					display dialog "unable to displayFileMakerDatabase becuase of privSet violation in some FM file errNum: " & errNum buttons "OK" default button "OK"
					error "privSet violation in some FM file..." & errNum number errNum
				else
					error "Error getting list of databases already open - " & errMsg number errNum
				end if
			end try

			delay waitCycleDelaySeconds
		end repeat
		--if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase docNameList: " & my coerceToString(docNameList))

		--loop through available document and bring the specified to the front
		repeat with oneDocName in docNameList
			set oneDocName to contents of oneDocName

			-- get the name WITHOUT the file extension:
			(reverse of characters of oneDocName) as string
			text ((offset of "." in result) + 1) thru -1 of result
			set oneDocName to (reverse of characters of result) as string

			-- apparently these two TEXT variables have some difference (formatting?) even when they are identical STRINGS:
			if oneDocName is equal to (dbName as string) then
				tell application "FileMaker Pro Advanced"
					--if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase about to show oneDocName: " & oneDocName)
					show document oneDocName
					if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase: " & oneDocName)
				end tell
				return true
			end if
		end repeat

		return false
	on error errMsg number errNum
		error "unable to displayFileMakerDatabase - " & errMsg number errNum
	end try
end displayFileMakerDatabase

--------------------
-- END OF CODE
--------------------

on logConsole(processName, consoleMsg)
	tell application "htcLib" to logConsole(processName, consoleMsg)
end logConsole

on coerceToString(incomingObject)
	-- 2017-07-12 ( eshagdar ): bootstrap code to bring a coerceToString into this file for the sample to run ( instead of having a copy of the handler locally ).

	tell application "Finder" to set coercePath to (container of (container of (path to me)) as text) & "text parsing:coerceToString.applescript"
	set codeCoerce to read file coercePath as text
	tell application "htcLib" to set codeCoerce to "script codeCoerce " & return & getTextBetween({sourceText:codeCoerce, beforeText:"-- START OF CODE", afterText:"-- END OF CODE"}) & return & "end script" & return & "return codeCoerce"
	set codeCoerce to run script codeCoerce
	tell codeCoerce to coerceToString(incomingObject)
end coerceToString

-- displayFileMakerDatabase({dbName:"", waitCycleDelaySeconds:"", waitSaveTotalSeconds:""})
-- Dan Shockley, NYHTC
-- If open, then display first window this finds and return true, else return false.

(*
HISTORY:
	1.6.3 - 2019-02-27 ( eshagdar ): throw up a dialog if there is a privSet violation.
	1.6.2 - 2018-12-07 ( eshagdar ): don't both using case, terms, or bundle ID - just talk to the application directly.
	1.6.1 - 2018-10-16 ( eshagdar ): remove remaining FMA references.
	1.6 - 2018-09-20 ( eshagdar ): FileMaker 17 has only version so talk to it by name.
	1.5.3 - 2018-01-18 ( eshagdar ): capture privSet violation error
	1.5.2 - 2017-11-20 ( eshagdar ): disable logging
	1.5.1 - 2017-10-25 ( eshagdar ): updated defaultPrefs. updated helper handlers. added delay, more debugging messages. get list of document names instead of documents - we don't need to get the name later.
	1.5 - added a time-out loop for dealing with delay in being able to get list of databases.
	1.4 - added error-handling
	1.3 -
	1.2 -
	1.1 -
	1.0 - created

REQUIRES:
	coerceToString
	logConsole
*)

property debugMode : true
property ScriptName : "displayFileMakerDatabase_TEST"

on run
	displayFileMakerDatabase({dbName:"a01_PERSON"})
end run

--------------------
-- START OF CODE
--------------------

on displayFileMakerDatabase(prefs)
	-- version 1.6.3

	try
		set defaultPrefs to {dbName:null, waitCycleDelaySeconds:5, waitSaveTotalSeconds:2 * minutes}
		set prefs to prefs & defaultPrefs

		--if debugMode then logConsole(ScriptName, "displayFileMakerDatabase prefs: " & coerceToString(prefs))

		set dbName to dbName of prefs

		set waitSaveTotalSeconds to waitSaveTotalSeconds of prefs
		set waitCycleDelaySeconds to waitCycleDelaySeconds of prefs
		set waitCycleMax to round (waitSaveTotalSeconds / waitCycleDelaySeconds) rounding down

		-- get name of all documents
		delay 0.25
		repeat waitCycleMax times
			set docNameList to null
			try
				using terms from application "FileMaker Pro Advanced"
					tell application ID "com.filemaker.client.pro12"
						set docNameList to name of every document
					end tell
				end using terms from

				if docNameList is not null then exit repeat
			on error errMsg number errNum
				if errNum is -10011 then
					-- just keep trying - this error can be caused when a database is opening and the open script takes a bit too long to finish, or something in the FM interface is slow to respond.
				else if errNum is -10004 then
					display dialog "unable to displayFileMakerDatabase becuase of privSet violation in some FM file errNum: " & errNum buttons "OK" default button "OK"
					error "privSet violation in some FM file..." & errNum number errNum
				else
					error "Error getting list of databases already open - " & errMsg number errNum
				end if
			end try

			delay waitCycleDelaySeconds
		end repeat
		--if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase docNameList: " & my coerceToString(docNameList))

		--loop through available document and bring the specified to the front
		repeat with oneDocName in docNameList
			set oneDocName to contents of oneDocName

			-- get the name WITHOUT the file extension:
			(reverse of characters of oneDocName) as string
			text ((offset of "." in result) + 1) thru -1 of result
			set oneDocName to (reverse of characters of result) as string

			-- apparently these two TEXT variables have some difference (formatting?) even when they are identical STRINGS:
			if oneDocName is equal to (dbName as string) then
				tell application "FileMaker Pro Advanced"
					--if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase about to show oneDocName: " & oneDocName)
					show document oneDocName
					if debugMode then my logConsole(ScriptName, "displayFileMakerDatabase: " & oneDocName)
				end tell
				return true
			end if
		end repeat

		return false
	on error errMsg number errNum
		error "unable to displayFileMakerDatabase - " & errMsg number errNum
	end try
end displayFileMakerDatabase

--------------------
-- END OF CODE
--------------------

on logConsole(processName, consoleMsg)
	tell application "htcLib" to logConsole(processName, consoleMsg)
end logConsole

on coerceToString(incomingObject)
	-- 2017-07-12 ( eshagdar ): bootstrap code to bring a coerceToString into this file for the sample to run ( instead of having a copy of the handler locally ).

	tell application "Finder" to set coercePath to (container of (container of (path to me)) as text) & "text parsing:coerceToString.applescript"
	set codeCoerce to read file coercePath as text
	tell application "htcLib" to set codeCoerce to "script codeCoerce " & return & getTextBetween({sourceText:codeCoerce, beforeText:"-- START OF CODE", afterText:"-- END OF CODE"}) & return & "end script" & return & "return codeCoerce"
	set codeCoerce to run script codeCoerce
	tell codeCoerce to coerceToString(incomingObject)
end coerceToString