No internet connection
  1. Home
  2. How to

Script to grab name data from a marker and rename clip

By Kyrre Laastad @Kyrre_Laastad
    2022-06-28 11:16:27.737Z2022-11-01 21:20:34.261Z

    Hi all,

    I do a lot of jazz sessions where we usually just put every take in the same session, so that the band can cycle from song to song on a whim rather than saying "Um, we're going to do such and such now" and then they have to wait while I have to close this session and open another, make sure that all the aux sends for monitoring are the same, etc. So my workflow is that I always print through our console on a seperate track that I just call "Print". When the band starts going I hit record and I make a marker where I put in take number ("T1", "T2", etc.) and song title (so it hypothetically becomes "T2 Someday My Prince Will Come"). When the session is over I manually rename all the clips on my print track and export them as files. This is tedious when the band does 80 takes over the course of a couple of days.

    I found this script that works pretty well by @samuel_henriques, but if I make a larger selection it starts to mess up and suddenly T4 has the name of T5 etc. It would be so beautiful if I could just mark every region on my print track and hit a button on my streamdeck and it renames them all, and it works correctly. Would make me VERY happy. :)

    Here's the script (copied from Rename clips by markers in Pro Tools, for whatever reason it doesn't want to format correctly in the forum post, but it is a direct copy/paste from that thread):

    function getMemLoc() {
    
        // Functions to grab start and end time on any counter
        //( because its runnign on clipDoForEachSelectedClip it should be Samples, but will work on any)
        const getSelectionStart = () => sf.ui.proTools.selectionGet().selectionStart.replace(/[:.+| ]/g, '');
        const getSelectionEnd = () => sf.ui.proTools.selectionGet().selectionEnd.replace(/[:.+| ]/g, '');
    
        // filter mem locs within selection
        const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m =>
            m.mainCounterValue.replace(/[:.+| ]/g, '') >= getSelectionStart() &&
            m.mainCounterValue.replace(/[:.+| ]/g, '') <= getSelectionEnd()
        );
    
        // return first memory location within selection
        return memLocFromSelection
    }
    
    
    
    let index = 0
    /**
    * @param {array} memLocs
    */
    function renameClip(memLocs) {
    
        if (memLocs[index]) {
    
            //Open Rename window
            sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] });
    
            //Reference for Rename Window
            const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element
    
            const nameClipOnlyButton = renameWin.groups.first.radioButtons.first
    
            ///  Set Clip Name Only
            if (nameClipOnlyButton.exists)
                renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" });
    
            //  Set the clip name to Track name
            renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocs[index].name });
    
            // Click OK
            renameWin.buttons.whoseTitle.is('OK').first.elementClick()
            //  Wait for window to cloce
            renameWin.elementWaitFor({ waitType: "Disappear" })
    
            index++
        }
    }
    
    
    function main() {
    
        //  Acivate Pro Tools
        sf.ui.proTools.appActivateMainWindow()
    
        // Get Locations from selection
        const memLocFromSelection = getMemLoc()
    
        //  Do For Each 
        sf.ui.proTools.clipDoForEachSelectedClip({
            action: () => renameClip(memLocFromSelection),
            onError: "Continue"
        })
    }
    
    
    main()
    

    Here's a video of what happens.

    Would appreciate any help. :)

    • 8 replies
    1. samuel henriques @samuel_henriques
        2022-06-28 15:43:23.525Z2022-11-01 15:00:57.014Z

        Hello Kyrre,
        I'm sorry, I can see now how this script is not great. Hopefully it's better now.
        Let me know if its working well for you

        
        
        /**
        * @param {string} name
        */
        function renameClip(name) {
        
            if (name) {
                //Open Rename window
                sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] });
        
                //Reference for Rename Window
                const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element
        
                const nameClipOnlyButton = renameWin.groups.first.radioButtons.whoseTitle.is("name clip only").first
        
                ///  Set Clip Name Only
                if (nameClipOnlyButton.exists)
                    renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" });
        
                //  Set the clip name to Track name
                renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: name });
        
                // Click OK
                renameWin.buttons.whoseTitle.is('OK').first.elementClick()
                
                //  Wait for window to cloce
                renameWin.elementWaitFor({ waitType: "Disappear" })
            };
        };
        
        function getMemLocNameFromSelection() {
        
        
            // Grab start and end time on any counter - (.replace(/[:.+| ]/g, '') - works on any couter
            const selection = sf.ui.proTools.selectionGet();
            const selectionStart = +selection.selectionStart.replace(/[:.+| ]/g, '')
            const selectionEnd = +selection.selectionEnd.replace(/[:.+| ]/g, '')
        
        
            // Filter mem locs within selection
            //(.replace(/[:.+| ]/g, '') - to work on any couter
            const memLocFromSelection = sf.proTools.memoryLocationsFetchFromGui().collection['list'].filter(m =>
                +m.mainCounterValue.replace(/[:.+| ]/g, '') >= selectionStart &&
                +m.mainCounterValue.replace(/[:.+| ]/g, '') <= selectionEnd
            );
        
            // return first memory location name within selection
            return memLocFromSelection[0].name
        
        }
        
        
        function main() {
        
            //  Acivate Pro Tools
            sf.ui.proTools.appActivateMainWindow();
            sf.ui.proTools.invalidate();
        
            const isMemLocWinOpen = sf.ui.proTools.getMenuItem("Window", "Memory Locations").isMenuChecked
            sf.ui.proTools.menuClick({ menuPath: ["Window", "Memory Locations"], targetValue: "Enable" })
        
            //  Do For Each 
            sf.ui.proTools.clipDoForEachSelectedClip({
                action: () => renameClip(getMemLocNameFromSelection()),
                onError: "Continue"
            })
        
            if (!isMemLocWinOpen) {
                sf.ui.proTools.menuClick({ menuPath: ["Window", "Memory Locations"], targetValue: "Disable" })
            }
        }
        
        
        main()
        
        
        
        1. KKyrre Laastad @Kyrre_Laastad
            2022-06-29 13:00:36.406Z

            Hi Samuel,

            Thank you so much! This appears to be working perfectly. What a joy! Will try to get time to test it more thoroughly with more sessions tomorrow, but it appears that it does work as intended. Thanks again!

            Best
            Kyrre

            1. SStudioA StudioA @StudioA_StudioA
                2022-08-24 09:48:26.287Z

                This is super useful. Is there a way to alter it to rename the clips based on the markers comments? This would be amazing!

                1. samuel henriques @samuel_henriques
                    2022-08-24 21:36:50.791Z2022-08-25 15:01:59.835Z

                    Here you go StudioA,
                    It's much slower because reading the comments is more complicated. Until I figure a better way...

                    Hope this helps:

                    
                    function getMemLocNumberFromSelection() {
                    
                    
                        const selection = sf.ui.proTools.selectionGet()
                    
                        // Grab start and end time on any counter - (.replace(/[:.+| ]/g, '') - works on any counter
                        const selectionStart = +selection.selectionStart.replace(/[:.+| ]/g, '')
                        const selectionEnd = +selection.selectionEnd.replace(/[:.+| ]/g, '')
                    
                    
                        // Filter mem locs within selection
                        //(.replace(/[:.+| ]/g, '') - to work on any counter
                        const memLocFromSelection = sf.proTools.memoryLocationsFetchFromGui().collection['list'].filter(m =>
                            +m.mainCounterValue.replace(/[:.+| ]/g, '') >= selectionStart &&
                            +m.mainCounterValue.replace(/[:.+| ]/g, '') <= selectionEnd
                        );
                    
                        // return first memory location number within selection
                        return memLocFromSelection[0].number
                    };
                    
                    
                    /**
                    * @param {string | number} memLocNumber
                    */
                    function getCommentsFromMemLocByNumber(memLocNumber) {
                    
                        sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: +memLocNumber });
                        sf.ui.proTools.memoryLocationsWindow.popupButtons.first.popupMenuSelect({ menuSelector: items => items.filter(el => el.names[0].startsWith("Edit "))[0] });
                        const memLocWin = sf.ui.proTools.newMemoryLocationDialog.elementWaitFor({}, "Memory Location Win Didn\'t Open.").element;
                        const comments = memLocWin.textFields.first.value.invalidate().value;
                        memLocWin.buttons.whoseTitle.is("Cancel").first.elementClick();
                        memLocWin.elementWaitFor({ waitType: "Disappear" }, "Memory Location Win Didn\'t Close.");
                    
                        return comments
                    };
                    
                    
                    
                    /**
                    * @param {string} name
                    */
                    function renameClip(name) {
                    
                        // If no new name, return (leave function)
                        if (!name) return
                    
                        //Open Rename window
                        sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] });
                    
                        //Reference for Rename Window
                        const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element
                    
                        const nameClipOnlyButton = renameWin.groups.first.radioButtons.whoseTitle.is("name clip only").first
                    
                        ///  Set Clip Name Only
                        if (nameClipOnlyButton.exists)
                            renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" });
                    
                        //  Set the clip name to Track name
                        renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: name });
                    
                        // Click OK
                        renameWin.buttons.whoseTitle.is('OK').first.elementClick()
                    
                        //  Wait for window to cloce
                        renameWin.elementWaitFor({ waitType: "Disappear" })
                    
                    };
                    
                    
                    function main() {
                    
                        //  Acivate Pro Tools
                        sf.ui.proTools.appActivateMainWindow();
                        sf.ui.proTools.invalidate();
                    
                        const isMemLocWinOpen = sf.ui.proTools.getMenuItem("Window", "Memory Locations").isMenuChecked
                        sf.ui.proTools.menuClick({ menuPath: ["Window", "Memory Locations"], targetValue: "Enable" })
                    
                        //  Do For Each 
                        sf.ui.proTools.clipDoForEachSelectedClip({
                    
                            action: () => {
                    
                                const comments = getCommentsFromMemLocByNumber(getMemLocNumberFromSelection());
                    
                                sf.ui.proTools.menuClick({ menuPath: ["Edit", "Restore Last Selection"] });
                    
                                renameClip(comments);
                    
                            }, onError: "Continue"
                        });
                    
                        if (!isMemLocWinOpen) {
                            sf.ui.proTools.menuClick({ menuPath: ["Window", "Memory Locations"], targetValue: "Disable" })
                        }
                    }
                    
                    
                    main();
                    
                    1. samuel henriques @samuel_henriques
                        2022-08-25 15:02:33.045Z

                        Updated above, found a faster way...

                        1. SStudioA StudioA @StudioA_StudioA
                            2022-08-26 09:19:56.953Z

                            THANK YOU THIS IS WICKED! It's great for ADR workflows.

                            1. samuel henriques @samuel_henriques
                                2022-08-26 11:11:48.693Z

                                Cool! Just be aware of forbidden symbols you can write on comments but you can't write on clip names. @#"* for example, will fail to be accepted by pro tools and stop the script. If you start getting this problem, I have a script I can easily add to this that will clean forbidden symbols and it should help.

                                1. SStudioA StudioA @StudioA_StudioA
                                    2022-09-12 10:56:27.276Z

                                    Thanks again I will bare that in mind. It works a treat so far.