Question

I am trying to adapt the below Applescript code to change the audio channel assignment of a multichannel Quicktime file consisting of video and 8 audio channels from the default 'Mono' to 'Left, Right, Front Left, Front Right, LFE', etc, which can be done manually from 'Show Movie Properties/Audio Settings. The below script successfully changes the audio channels 'name' but I want it to change the 'channels' assignment, but I can't figure out how to get it working. I am on Mavericks with Quicktime Pro 7.

on run
    open (choose file with prompt "Choose source file(s)" with multiple selections allowed)
end run

on open ff
    repeat with f in ff
        remap_sound_tracks_name(f's POSIX path)
    end repeat
end open

on remap_sound_tracks_name(f)
    (*
        string f : POSIX path of source movie file
    *)
    script o
        on map(n)
            set mm to {¬
                {"Sound Track 1", "Left"}, ¬
                {"Sound Track 2", "Right"}, ¬
                {"Sound Track 3", "Center"}, ¬
                {"Sound Track 4", "LFE Screen"}, ¬
                {"Sound Track 5", "Left Surround"}, ¬
                {"Sound Track 6", "Right Surround"}, ¬
                {"Sound Track 7", "Left Total"}, ¬
                {"Sound Track 8", "Right Total"} ¬
                    }
            repeat with m in mm
                if m's item 1 = n then return m's item 2
            end repeat
            return n
        end map

        set f to f as POSIX file
        tell application id "com.apple.quicktimeplayer" -- QuickTime Player 7
            set dc to count documents
            open f
            repeat until (count documents) > dc
                delay 0.2
            end repeat
            tell document 1
                repeat with t in (get tracks whose audio channel count > 0)
                    set t to t's contents
                    set n to t's name
                    set n1 to my map(n)
                    if n1 ≠ n then set t's name to n1
                end repeat
                if modified then save
                close
            end tell
        end tell
    end script
    tell o to run
end remap_sound_tracks_name
Was it helpful?

Solution

This was answered by Hiroto on the apple forums. It runs and works, but is quite slow:

(*
    remap audio channel layouts.applescript
    v0.1
*)
on run
    open (choose file with prompt ("Choose movie file(s)") ¬
        with multiple selections allowed)
end run

on open aa
    set channel_layouts_map1 to {¬
        {"Sound Track 1", "Sound Track 1", {"Left"}}, ¬
        {"Sound Track 2", "Sound Track 2", {"Right"}}, ¬
        {"Sound Track 3", "Sound Track 3", {"Center"}}, ¬
        {"Sound Track 4", "Sound Track 4", {"LFE Screen"}}, ¬
        {"Sound Track 5", "Sound Track 5", {"Left Surround"}}, ¬
        {"Sound Track 6", "Sound Track 6", {"Right Surround"}}, ¬
        {"Sound Track 7", "Sound Track 7", {"Left Total"}}, ¬
        {"Sound Track 8", "Sound Track 8", {"Right Total"}} ¬
            }
    set channel_layouts_map2 to {¬
        {"Sound Track 1", "Sound Track 1", {"Left"}}, ¬
        {"Sound Track 2", "Sound Track 2", {"Right"}}, ¬
        {"Sound Track 3", "Sound Track 3", {"Center"}}, ¬
        {"Sound Track 4", "Sound Track 4", {"LFE Screen"}}, ¬
        {"Sound Track 5", "Sound Track 5", {"Left Surround"}}, ¬
        {"Sound Track 6", "Sound Track 6", {"Right Surround"}}, ¬
        {"Sound Track 7", "Sound Track 7", {"Left Total", "Right Total"}} ¬
            }
    set channel_layouts_map3 to {¬
        {"Sound Track 1", "Sound Track 7", {"Left"}}, ¬
        {"Sound Track 2", "Sound Track 8", {"Right"}} ¬
            }
    set channel_layouts_map4 to {¬
        {"Sound Track", "Sound Track", {"Left", "Right"}} ¬
            }

    repeat with a in aa
        set f to a's POSIX path
        set k to count_sound_tracks(f, {_close:false})
        if k = 8 then
            remap_audio_channels(f, channel_layouts_map1)
        else if k = 7 then
            remap_audio_channels(f, channel_layouts_map2)
        else if k = 2 then
            remap_audio_channels(f, channel_layouts_map3)
        else if k = 1 then
            remap_audio_channels(f, channel_layouts_map4)
        else
            -- ignore it (just close it)
            close_document(f, {_save:false})
        end if
    end repeat
end open

on count_sound_tracks(f, {_close:_close})
    (*
        string f : POSIX path of QT movie
        boolean _close: true to close document, false othewise
    *)
    tell application id "com.apple.quicktimeplayer" -- QuickTime Player 7 Pro
        open (f as POSIX file)
        tell (document 1 whose path = f)
            repeat until exists
                delay 0.2
            end repeat
            set k to count (tracks whose audio channel count > 0)
            if _close then close
        end tell
    end tell
    return k
end count_sound_tracks

on close_document(f, {_save:_save})
    (*
        string f : POSIX path of QT movie
        boolean _save: true to save document (if modified), false othewise
    *)
    tell application id "com.apple.quicktimeplayer" -- QuickTime Player 7 Pro
        tell (document 1 whose path = f)
            if exists then
                if _save and modified then save
                close
            end if
        end tell
    end tell
end close_document

on remap_audio_channels(f, channel_layouts_map)
    (*
        string f : POSIX path of source movie
        list channel_layouts_map : list of {trk, trk_new, layouts}
            trk = (string or integer) name or index of source sound track
            trk_new = (string or integer) new name for source track (integer i denotes original name of sound track i)
            layouts = list of audio channel layout for channel(s) in source sound track
                Mono
                Left
                Right
                Center
                LFE Screen
                Left Surround
                Right Surround
                Left Center
                Right Center
                Center Surround
                Rear Surround Left
                Rear Surround Right
                Left Total
                Right Total
                Discrete-0
                Discrete-1
                Unused

            e.g. 1
               {{"Sound Track 1", "Left", {"Left"}}, ¬
                {"Sound Track 2", "Right", {"Right"}}, ¬
                {"Sound Track 3", "Center", {"Center"}}, ¬
                {"Sound Track 4", "LFE Screen", {"LFE Screen"}}, ¬
                {"Sound Track 5", "Left Surround", {"Left Surround"}}, ¬
                {"Sound Track 6", "Right Surround", {"Right Surround"}}, ¬
                {"Sound Track 7", "Left Total", {"Left Total"}}, ¬
                {"Sound Track 8", "Right Total", {"Right Total"}}}

            e.g. 2
               {{1, 1, {"Left", "Right"}}, ¬
                {2, 2, {"Center", "LFE, Screen"}}, ¬
                {3, 3, {"Left Surround", "Right Surround"}}, ¬
                {4, 4, {"Left Total", "Right Total"}}}

        * this handler behaves as follows:
            1) open f
            2) scan sound tracks of document 1 for each trk and remap the track's audio channel layouts as specified
            3) scan sound tracks of document 1 for each trk and rename the track as specified
            4) save and close document 1

            * if specified trk is not found, it is ignored and no remapping is performed on the track.
            * if specified layout is not found, it is ignored and no remapping is performed on the layout.
            * if specified layout count is greater than channel count of the target track, excessive layouts are ignored.
            * if specified layout count is smaller than channel count of target track, excessive channels are ignored.
            * if trk and trk_new denotes the same track, renaming is not performed on the track.
    *)
    script o
        property map : channel_layouts_map
        property pp : {}
        property qq : {}

        -- get name and id of sound tracks
        tell application id "com.apple.quicktimeplayer" -- QuickTime Player 7 Pro
            activate
            open (f as POSIX file)
            tell (document 1 whose path = f)
                repeat until exists
                    delay 0.2
                end repeat
                tell (tracks whose audio channel count > 0)
                    set {pp, qq} to {name, id} -- name and id of sound tracks
                end tell
            end tell
        end tell

        -- remap audio channel layouts as specified
        tell application "System Events"
            tell (process 1 whose bundle identifier = "com.apple.quicktimeplayer")
                -- open movie properties window
                keystroke "j" using {command down}

                tell (window 1 whose subrole = "AXDialog") -- properties for movie
                    repeat until exists
                        delay 0.2
                    end repeat
                    repeat with m in my map
                        set {trk, undef, layouts} to m
                        -- [TRK:
                        repeat 1 times
                            if trk's class = integer then
                                if trk < 1 or trk > (count my pp) then exit repeat -- TRK:
                                set trk to my pp's item trk
                            end if
                            tell scroll area 1
                                tell table 1
                                    tell (row 1 whose text field 1's value = trk) -- target sound track whose name = trk
                                        if not (exists) then exit repeat -- TRK:
                                        select
                                    end tell
                                end tell
                            end tell
                            tell tab group 1
                                click radio button 3 -- audio settings
                                tell scroll area 1
                                    tell table 1 -- channel assignment table
                                        set ix to count layouts
                                        repeat with i from 1 to count rows
                                            if i > ix then exit repeat
                                            tell row i -- channel i
                                                tell pop up button 1
                                                    click
                                                    tell menu 1 -- channel assignment menu
                                                        tell (menu item 1 whose title = layouts's item i)
                                                            if exists then click
                                                        end tell
                                                    end tell
                                                end tell
                                            end tell
                                        end repeat
                                    end tell
                                end tell
                            end tell
                        end repeat
                        -- /TRK:]
                    end repeat

                    -- close movie properties window
                    click (button 1 whose subrole = "AXCloseButton")
                end tell
            end tell
        end tell

        -- rename sound tracks as specified
        tell application id "com.apple.quicktimeplayer"
            tell document 1
                repeat with m in my map
                    -- [RENAME:
                    repeat 1 times
                        set {x, y} to m's items 1 thru 2 -- {old name or index, new name or index}
                        if x's class = integer then
                            if x < 1 or x > (count my pp) then exit repeat -- RENAME:
                        else
                            set x to my _index_of(pp, x)
                            if x = 0 then exit repeat -- RENAME:
                        end if
                        if y's class = integer then
                            if y < 1 or y > (count my pp) then exit repeat -- RENAME:
                            set y to my pp's item y
                        end if
                        set p to my pp's item x
                        set q to my qq's item x
                        if p ≠ y then set track id q's name to y
                    end repeat
                    -- /RENAME:]
                end repeat
                if modified then save
                close
            end tell
        end tell

    end script
    tell o to run
end remap_audio_channels

on _index_of(xx, x) -- renamed _bsearch() v0.1
    (*
        list xx : source list
        anything x : item to be searched in xx
        return integer : the first index of x in xx if {x} is in xx, or 0 if not.
    *)
    script o
        property aa : xx
        local i, j, k
        if {x} is not in my aa then return 0
        set i to 1
        set j to count my aa
        repeat while j > i
            set k to (i + j) div 2
            if {x} is in my aa's items i thru k then
                set j to k
            else
                set i to k + 1
            end if
        end repeat
        return i
    end script
    tell o to run
end _index_of
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top