PT Bounce Script / Set output stuck
Desired Workflow
I try to adapt Kitch script "stem bouncing" to get it to work with a whole movie in reels.
"My" script is working ok except when I want to add the Set output command ...
Question
I changed "Bounce" to Bounce Mix" fro PT 2021 but something is blocking there ..
Here is the part of the script
//Set Output
if (sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first.popupButtons.first.value.invalidate().value != '5.1 bus.C (Mono)') {
sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first.popupButtons.first.popupMenuSelect({
menuPath: ["bus", "5.1 bus.C (Mono)"],
useWildcards: true,
});
}
and the log
03.09.2021 15:27:33.98 [Backend]: !! Command Error: gu PT bounce bobines Directs [user:default:ckt380su7000avj10ztd8t1id]:
Could not click popup menu item (gu PT bounce bobines Directs: Line 51)
Could not find menu item with name: bus -> 5.1 bus.C (Mono)
Thanks in advance for any help
Jean
Command Info
ID: user:default:ckt380su7000avj10ztd8t1id
Name: gu PT bounce bobines Directs
Source
sf.ui.proTools.appActivateMainWindow();
//Loop 7 times
for(let i=0; i<7; i++) {
sf.keyboard.press({
keys: "ctrl+tab",
});
sf.ui.proTools.menuClick({
menuPath: ["Clip","Rename..."],
});
sf.ui.proTools.menuClick({
menuPath: ["Edit","Copy"],
});
sf.keyboard.press({
keys: "return",
});
sf.ui.proTools.menuClick({
menuPath: ["File","Bounce Mix..."],
});
//Wait for the 'Bounce' dialog to appear and assign it to the bounceDlg variable
var bounceDlg = sf.ui.proTools.dialogWaitForManual({
dialogTitle: 'Bounce Mix'
}).dialog;
sf.ui.proTools.menuClick({
menuPath: ["Edit","Paste"],
});
sf.keyboard.type({
text: " DIRECTS",
});
let popupButtons = bounceDlg.getElements("AXChildren").filter(function (e) { return e.fullRole == "AXPopUpButton" }).slice(-4);
let fileTypeBtn = popupButtons[0];
let formatBtn = popupButtons[1];
let bitDepthBtn = popupButtons[2];
let sampleRateBtn = popupButtons[3];
//Set Output
if (sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first.popupButtons.first.value.invalidate().value != '5.1 bus.C (Mono)') {
sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first.popupButtons.first.popupMenuSelect({
menuPath: ["bus", "5.1 bus.C (Mono)"],
useWildcards: true,
});
}
//File Type
if (fileTypeBtn.value.invalidate().value != 'WAV')
fileTypeBtn.popupMenuSelect({ menuPath: ['WAV'] });
//File Format
if (formatBtn.value.value != 'Multiple mono')
formatBtn.popupMenuSelect({ menuPath: ['Multiple mono'] });
//Bit Depth
if (bitDepthBtn.value.invalidate().value != '24 Bit')
bitDepthBtn.popupMenuSelect({ menuPath: ['24 Bit'] });
//Sample Rate
if (sampleRateBtn.value.invalidate().value != '48 kHz')
sampleRateBtn.popupMenuSelect({ menuPath: ['48 kHz']
});
sf.keyboard.press({
keys: "return",
});
sf.ui.proTools.waitForNoModals();
}
second: any;
Links
User UID: e3y3S4pzUNdudPkANFsS9ZxGd8q2
Feedback Key: sffeedback:e3y3S4pzUNdudPkANFsS9ZxGd8q2:-MifrnNHMDbog1H8a9WG
- OIn reply toolafnoise⬆:olafnoise @olafnoise
Thanks Kitch
waiting till you have a moment ;-)Kitch Membery @Kitch2021-09-04 23:15:11.267Z2021-09-05 21:06:48.190Z
Hi @olafnoise,
Ignore my previous questions... I worked out what you were trying to do and adapted it to my personal 2021 bounce script.
Simply select the clips you want to bounce and then run the script. (Note if at any time you need to cancel the script use Ctrl+Shift+Esc.)
You will need to change two lines in the bounce settings object to reflect the Mix Source button title and the Mix Source Output path that you need.
Mine look like this in Pro Tools;
mixSourceButtonTitle:
mixSourcePath:
So I changed the following two lines in the
bounceSettings
object to reflect the above;mixSourceButtonTitle: 'Playback 1-2 (Stereo)', mixSourcePath: ['output', 'Playback 1-2 (Stereo) -> Playback 1-2'],
(EDITED: I edited the
mixSourcePath
above 09/05/21)Here it is;
const bounceSettings = { presetNumber: undefined, libraryPresetName: undefined, //fileName: "", // Commented out as the file name as it is being created in the clipDoForEachSelectedClip() loop. clipSuffix:'DIRECTS', fileType: "WAV (BWF)", mixSourceButtonTitle: 'Playback 1-2 (Stereo)', mixSourcePath: ['output', 'Playback 1-2 (Stereo) -> Playback 1-2'], mp3TargetValue: 'Disable', fileFormat: 'Multiple mono', bitDepth: '24 Bit', sampleRate: '48 kHz', padToFrameBoundary: 'Disable', importAfterBounce: 'Disable', fileDestination: 'Session Folder', //Options: 'Session Folder'|'Prompt For Location'|'Directory' sessionFolderPath: 'Bounced Files', onlineOffline: 'Enable', }; const bounceMixWin = sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first; function openBounceMixWindow() { //Open Bounce Mix Window sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }); bounceMixWin.elementWaitFor(); } function maximiseBounceWindow() { //Open all Bounce Mix Panels bounceMixWin.groups.forEach(group => { if (group.frame.h === 22) { if (group.buttons.whoseTitle.is('Collapser').first.exists) { group.buttons.whoseTitle.is('Collapser').first.elementClick(); } } }) } function setText(panel, text, index) { if (panel.textFields.allItems[index].value.invalidate().value !== text) { panel.textFields.allItems[index].elementSetTextFieldWithAreaValue({ value: text, }, `ERROR: ${text} ${index}`); } } function setPopupMenu(panel, path, index) { if (panel.popupButtons.allItems[index].value.invalidate().value !== path) { panel.popupButtons.allItems[index].popupMenuSelect({ menuPath: [path], }, `ERROR: ${path} ${index}`); } } function setBouncePreset(preset) { //Preset Buttons - mouseClickElement(); const presetButtons = bounceMixWin.children.filter(b => b.fullRole === "AXButton:AXToggle"); presetButtons[preset - 1].elementClick(); } function setLibraryPreset(preset) { const libraryMenu = bounceMixWin.children.whoseRole.is("AXMenuButton").whoseTitle.is("Librarian menu").first; //Librarian menu if (libraryMenu.value.invalidate().value !== preset) { libraryMenu.popupMenuSelect({ menuPath: [preset], }); } } function setTopPanel(settings) { const { fileName, fileType, mixSourceButtonTitle, mixSourcePath } = settings; //File Name - Text Field setText(bounceMixWin, fileName, 0); //File Type - Popup Menu setPopupMenu(bounceMixWin, fileType, 0); //Mix Source - Popup Menu if (bounceMixWin.popupButtons.allItems[1].value.invalidate().value !== mixSourceButtonTitle) { bounceMixWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: mixSourcePath, }); } } function setAudioPanel(settings) { const { mp3TargetValue, fileFormat, bitDepth, sampleRate, padToFrameBoundary } = settings; const audioPanel = bounceMixWin.groups.whoseTitle.is("Audio").first //MP3 - Checkbox audioPanel.checkBoxes.whoseTitle.is("Add MP3").first.checkboxSet({ targetValue: mp3TargetValue, }); //File Format - Popup Menu setPopupMenu(audioPanel, fileFormat, 1); //Bit Depth - Popup Menu setPopupMenu(audioPanel, bitDepth, 2); //Sample Rate - Popup Menu (Have not yet implementedsupport Pull up/down sample rates ) setPopupMenu(audioPanel, sampleRate, 3); //Pad To Frame Boundary - Checkbox audioPanel.checkBoxes.whoseTitle.is("Pad To Frame Boundary").first.checkboxSet({ targetValue: padToFrameBoundary, }); } function setLocationPanel(settings) { let { importAfterBounce, fileDestination, sessionFolderPath, onlineOffline } = settings; const locationPanel = bounceMixWin.groups.whoseTitle.is("Location").first //Import After Bounce - Checkbox locationPanel.checkBoxes.whoseTitle.is("Import After Bounce").first.checkboxSet({ targetValue: importAfterBounce, }); //Session Folder - Radio Button if (fileDestination === 'Session Folder') { //Session Folder - Radio Button locationPanel.radioButtons.whoseTitle.is("Session Folder:").first.elementClick(); //Session Folder - Text Field setText(locationPanel, sessionFolderPath, 0); } else if (fileDestination === 'Prompt For Location') { //Prompt For Location - Radio Button locationPanel.radioButtons.whoseTitle.is("Prompt For Location").first.elementClick(); } else if (fileDestination === 'Directory') { //Directory: - Radio Button locationPanel.radioButtons.whoseTitle.is("Directory:").first.elementClick(); //Choose... - Button locationPanel.buttons.whoseTitle.is("Choose...").first.elementClick(); } //Offline - Checkbox bounceMixWin.checkBoxes.whoseTitle.is("Offline").first.checkboxSet({ targetValue: onlineOffline, }); } function doBounce(settings) { const { presetNumber, libraryPresetName } = settings; sf.ui.proTools.appActivateMainWindow(); openBounceMixWindow(); maximiseBounceWindow(); if (presetNumber !== undefined) setBouncePreset(presetNumber); if (libraryPresetName !== undefined) setLibraryPreset(libraryPresetName); setTopPanel(settings); setAudioPanel(settings); setLocationPanel(settings); //Click Bounce bounceMixWin.buttons.whoseTitle.is('Bounce').first.elementClick(); //Wait for bounce to finish (Wait for bounce dialog to appear, then to disappear) sf.wait({ intervalMs: 4000 }); sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); //-1 is endless timeout (cancel by Ctrl+Shift+Esc) } function getSelectedClipNamesFromClipList() { const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first; const selectedClips = clipsTable.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); const clipNames = selectedClips.map(c => c.split('"')[1]); return clipNames }; function bounceClip(bounceSettings) { const selectedClipName = getSelectedClipNamesFromClipList()[0]; const newFileName = `${selectedClipName} ${bounceSettings.clipSuffix}` bounceSettings.fileName = newFileName; doBounce(bounceSettings); } function bounceClips(bounceSettings) { sf.ui.proTools.clipDoForEachSelectedClip({ action: () => bounceClip(bounceSettings) }); } bounceClips(bounceSettings);
If you are using this to bounce really short clips you may want to adjust the wait on line 180 to
sf.wait({ intervalMs: 500 });
Let me know how it goes for you, mate. :-)
- Oolafnoise @olafnoise
Wow !! thanks a lot Kitch !!!
I tested it as it is (with my own output settings) and it works fine
I'll try later to put again my loop (7 reels on the feature I'm working on at the moment to answer your former question) and naming settings and let you know
Thanks again
JeanKitch Membery @Kitch2021-09-05 09:21:31.803Z
Nice!
You shouldn’t need to re-add the loop though, as I have already set it up so all you have to do is select the clips in the guide track that you were grabbing the clip names from and it will bounce for each selected clip’s range one by one
This way you can bounce one section at a time if you want.
Also it grabs the clip name from the clips list rather than from the clip rename window which is a bit faster :-)
Enjoy.
- Oolafnoise @olafnoise
Yes! it seems to be brilliant !!
But I get an error when selecting the next clip
I tried to select all the reels guide clips (I tried normally and in object mode with the same result)here is the log
05.09.2021 19:55:40.64 [Backend]: #StreamDeck: KeyDown (5,4) -> bounce Kitch test
Validating command... user:default:ckt6xozz70000iy101sv133xl
Invoking command...user:default:ckt6xozz70000iy101sv133xl05.09.2021 19:55:40.64 [Backend]: >> Command: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]
05.09.2021 19:55:40.96 [Backend]: Clicking with mouse here: 773, 86
05.09.2021 19:55:41.05 [Backend]: Succesfully set selection to: MainCounter: Sel Start: Sel End: Sel Length: 0
05.09.2021 19:55:41.11 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
05.09.2021 19:55:42.97 [Backend]: Clicking with mouse here: 72, 30
05.09.2021 19:55:43.93 [Backend]: Clicking with mouse here: 838, 348
05.09.2021 19:55:43.98 [Backend]: PopupMenu full role:AXMenu
05.09.2021 19:55:43.98 [Backend]: Logging error in action (01) ClickPopupMenuAction: Could not find menu item with name: bus -> 5.1 bus #1 C (Mono)
05.09.2021 19:55:44.18 [Backend]: Clicking with mouse here: 820, 203
05.09.2021 19:55:44.20 [Backend]: Logging error in action (01) PopupMenuSelectAction: Could not click popup menu item
05.09.2021 19:55:44.20 [Backend]: Error running Js Callback: 'PopupMenuSelectAction' ( line 87)
05.09.2021 19:55:44.29 [Backend]: Clicking with mouse here: 773, 74
05.09.2021 19:55:50.37 [Backend]: Clicking with mouse here: 773, 74
05.09.2021 19:55:55.83 [Backend]: Clicking with mouse here: 773, 74
05.09.2021 19:56:02.76 [Backend]: Clicking with mouse here: 773, 74
05.09.2021 19:56:03.25 [Backend]: Succesfully set selection to: MainCounter: Sel Start: 517296000 Sel End: 749574000 Sel Length:
05.09.2021 19:56:03.31 [Backend]: Pressing key: kVK_LeftArrow. Flags: Zero
05.09.2021 19:56:03.42 [Backend]: Logging unknown error in action (02) DoMainCounterAction: bounce Kitch test: Line 87
Logging unknown error in action (02) DoForEachClipAction: bounce Kitch test: Line 87
Logging unknown error in action (02) DoForEachSelectedClipAction: bounce Kitch test: Line 8705.09.2021 19:56:03.42 [Backend]: JavaScript error with InnerException: Could not click popup menu item (bounce Kitch test: Line 87)
!! Command Error: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]:
Error: bounce Kitch test: Line 87
(bounce Kitch test line 204)<< Command: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]
Kitch Membery @Kitch2021-09-05 19:48:06.154Z
Hi @olafnoise,
The error seems to be something to do with selecting the output path. The bounce Mix window may have been changed again.
I'll take a look today. :-)
Rock on.
- In reply toolafnoise⬆:
Kitch Membery @Kitch2021-09-05 21:29:09.801Z
I think I worked it out... I made an adjustment to the output selector as I believe the bus that you are trying to select may be indented within the Mix Source menu where Pro Tools adds some leading spaces before the bus name.
Note: that this won't perform as expected if you are trying to use the Object grabber tool while selecting clips with unselected clips between them. It will process every clip between the start of the first selected clip and the end of the last selected clip. This could be done but It would require a little extra scripting.
I also added an alert to the end so you know when it's done.
Below is the updated script; Remember to update the
mixSourceButtonTitle
&mixSourcePath
before trying it out. :-)const bounceSettings = { presetNumber: undefined, libraryPresetName: undefined, //fileName: "", // Commented out as the file name as it is being created in the clipDoForEachSelectedClip() loop. clipSuffix: 'DIRECTS', fileType: "WAV (BWF)", mixSourceButtonTitle: 'Playback 1-2 (Stereo)', mixSourcePath: ['output', 'Playback 1-2 (Stereo) -> Playback 1-2'], mp3TargetValue: 'Disable', fileFormat: 'Multiple mono', bitDepth: '24 Bit', sampleRate: '48 kHz', padToFrameBoundary: 'Disable', importAfterBounce: 'Disable', fileDestination: 'Session Folder', //Options: 'Session Folder'|'Prompt For Location'|'Directory' sessionFolderPath: 'Bounced Files', onlineOffline: 'Enable', }; const bounceMixWin = sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first; function openBounceMixWindow() { //Open Bounce Mix Window sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }); bounceMixWin.elementWaitFor(); } function maximiseBounceWindow() { //Open all Bounce Mix Panels bounceMixWin.groups.forEach(group => { if (group.frame.h === 22) { if (group.buttons.whoseTitle.is('Collapser').first.exists) { group.buttons.whoseTitle.is('Collapser').first.elementClick(); } } }) } function setText(panel, text, index) { if (panel.textFields.allItems[index].value.invalidate().value !== text) { panel.textFields.allItems[index].elementSetTextFieldWithAreaValue({ value: text, }, `ERROR: ${text} ${index}`); } } function setPopupMenu(panel, path, index) { if (panel.popupButtons.allItems[index].value.invalidate().value !== path) { panel.popupButtons.allItems[index].popupMenuSelect({ menuPath: [path], }, `ERROR: ${path} ${index}`); } } function setBouncePreset(preset) { //Preset Buttons - mouseClickElement(); const presetButtons = bounceMixWin.children.filter(b => b.fullRole === "AXButton:AXToggle"); presetButtons[preset - 1].elementClick(); } function setLibraryPreset(preset) { const libraryMenu = bounceMixWin.children.whoseRole.is("AXMenuButton").whoseTitle.is("Librarian menu").first; //Librarian menu if (libraryMenu.value.invalidate().value !== preset) { libraryMenu.popupMenuSelect({ menuPath: [preset], }); } } function setTopPanel(settings) { const { fileName, fileType, mixSourceButtonTitle, mixSourcePath } = settings; //File Name - Text Field setText(bounceMixWin, fileName, 0); //File Type - Popup Menu setPopupMenu(bounceMixWin, fileType, 0); //Mix Source - Popup Menu if (bounceMixWin.popupButtons.allItems[1].value.invalidate().value !== mixSourceButtonTitle) { bounceMixWin.popupButtons.allItems[1].popupMenuSelect({ menuSelector: items => items.filter(item => item.path[0].endsWith(mixSourcePath[0]) && item.path[1].endsWith(mixSourcePath[1]))[0] }); } } function setAudioPanel(settings) { const { mp3TargetValue, fileFormat, bitDepth, sampleRate, padToFrameBoundary } = settings; const audioPanel = bounceMixWin.groups.whoseTitle.is("Audio").first //MP3 - Checkbox audioPanel.checkBoxes.whoseTitle.is("Add MP3").first.checkboxSet({ targetValue: mp3TargetValue, }); //File Format - Popup Menu setPopupMenu(audioPanel, fileFormat, 1); //Bit Depth - Popup Menu setPopupMenu(audioPanel, bitDepth, 2); //Sample Rate - Popup Menu (Have not yet implementedsupport Pull up/down sample rates ) setPopupMenu(audioPanel, sampleRate, 3); //Pad To Frame Boundary - Checkbox audioPanel.checkBoxes.whoseTitle.is("Pad To Frame Boundary").first.checkboxSet({ targetValue: padToFrameBoundary, }); } function setLocationPanel(settings) { let { importAfterBounce, fileDestination, sessionFolderPath, onlineOffline } = settings; const locationPanel = bounceMixWin.groups.whoseTitle.is("Location").first //Import After Bounce - Checkbox locationPanel.checkBoxes.whoseTitle.is("Import After Bounce").first.checkboxSet({ targetValue: importAfterBounce, }); //Session Folder - Radio Button if (fileDestination === 'Session Folder') { //Session Folder - Radio Button locationPanel.radioButtons.whoseTitle.is("Session Folder:").first.elementClick(); //Session Folder - Text Field setText(locationPanel, sessionFolderPath, 0); } else if (fileDestination === 'Prompt For Location') { //Prompt For Location - Radio Button locationPanel.radioButtons.whoseTitle.is("Prompt For Location").first.elementClick(); } else if (fileDestination === 'Directory') { //Directory: - Radio Button locationPanel.radioButtons.whoseTitle.is("Directory:").first.elementClick(); //Choose... - Button locationPanel.buttons.whoseTitle.is("Choose...").first.elementClick(); } //Offline - Checkbox bounceMixWin.checkBoxes.whoseTitle.is("Offline").first.checkboxSet({ targetValue: onlineOffline, }); } function doBounce(settings) { const { presetNumber, libraryPresetName } = settings; sf.ui.proTools.appActivateMainWindow(); openBounceMixWindow(); maximiseBounceWindow(); if (presetNumber !== undefined) setBouncePreset(presetNumber); if (libraryPresetName !== undefined) setLibraryPreset(libraryPresetName); setTopPanel(settings); setAudioPanel(settings); setLocationPanel(settings); //Click Bounce bounceMixWin.buttons.whoseTitle.is('Bounce').first.elementClick(); //Wait for bounce to finish (Wait for bounce dialog to appear, then to disappear) sf.wait({ intervalMs: 4000 }); sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); //-1 is endless timeout (cancel by Ctrl+Shift+Esc) } function getSelectedClipNamesFromClipList() { const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first; const selectedClips = clipsTable.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); const clipNames = selectedClips.map(c => c.split('"')[1]); return clipNames }; function bounceClip(bounceSettings) { const selectedClipName = getSelectedClipNamesFromClipList()[0]; const newFileName = `${selectedClipName} ${bounceSettings.clipSuffix}` bounceSettings.fileName = newFileName; doBounce(bounceSettings); } function bounceClips(bounceSettings) { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.clipDoForEachSelectedClip({ action: () => bounceClip(bounceSettings) }); alert('Done!'); } bounceClips(bounceSettings);
- Oolafnoise @olafnoise
Great !! Thank you so much ....
A lot of time saved now ....
all the best KitchKitch Membery @Kitch2021-09-06 07:34:09.679Z
Awesome. Have a great week. :-)
- Oolafnoise @olafnoise
Hi Kitch
I just try your script on another machine (Mac 5.1 running Mojave instead of Catalina on a Dustbin)
Same version of PT 2021.7 but HDX
And the script doesn"t work anymore
First the counters changes to samples (weird) then select the reels then get stuck OR bounce the first reel and then stop (ultra weird)
at the beginning I tought that it could be a waiting time issue (the offline bounce process is longer to start on this machine (may be due to HDX ...)here is the log:
10.09.2021 11:36:12.58 [Backend]: #StreamDeck: KeyDown (5,4) -> bounce Kitch test
Validating command... user:default:ckt6xozz70000iy101sv133xl
Invoking command...user:default:ckt6xozz70000iy101sv133xl10.09.2021 11:36:12.58 [Backend]: >> Command: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]
10.09.2021 11:36:12.68 [Backend]: Clicking with mouse here: 74, 33
10.09.2021 11:36:13.06 [Backend]: Clicking with mouse here: 775, 89
10.09.2021 11:36:13.18 [Backend]: Succesfully set selection to: MainCounter: Sel Start: Sel End: Sel Length: 0
10.09.2021 11:36:13.24 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:13.60 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:13.74 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:14.14 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:14.27 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:14.71 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:14.84 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:15.26 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:15.39 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:15.82 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:15.95 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:16.38 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:16.52 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:16.94 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:17.07 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:17.48 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:17.62 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:18.05 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: Zero
10.09.2021 11:36:18.18 [Backend]: Pressing key: kVK_ANSI_Quote. Flags: kCGEventFlagMaskShift
10.09.2021 11:36:18.60 [Backend]: Clicking with mouse here: 775, 65
10.09.2021 11:36:18.88 [Backend]: Clicking with mouse here: 775, 77
10.09.2021 11:36:19.08 [Backend]: Succesfully set selection to: MainCounter: Sel Start: 172704000 Sel End: 924772000 Sel Length:
10.09.2021 11:36:19.14 [Backend]: Pressing key: kVK_LeftArrow. Flags: Zero
10.09.2021 11:36:19.29 [Backend]: Logging error in action (01) DoMainCounterAction: Selecting a full clip failed
Error in action (00) DoForEachClipAction: DoMainCounterAction
Error in action (00) DoForEachSelectedClipAction: DoMainCounterAction10.09.2021 11:36:19.29 [Backend]: !! Command Error: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]:
Selecting a full clip failed (bounce Kitch test: Line 207)<< Command: bounce Kitch test [user:default:ckt6xozz70000iy101sv133xl]
10.09.2021 11:36:23.92 [Backend]: [SF_FIREBASE_WS]: Sending keep-alive
10.09.2021 11:36:29.36 [Backend]: #Key: mouse button 3 (-4) -> Show/Hide Track Volume For Selected Track [proTools_track_volume_toggle_selectedTrack:1]
Validating command... proTools.track.volume.toggle.selectedTrack
Invoking command...proTools.track.volume.toggle.selectedTrackCommand: Show/Hide Track Volume For Selected Track [proTools.track.volume.toggle.selectedTrack]
10.09.2021 11:36:29.41 [Backend]: Pressing key: kClearCharCode. Flags: Zero
10.09.2021 11:36:29.65 [Backend]: << Command: Show/Hide Track Volume For Selected Track [proTools.track.volume.toggle.selectedTrack]
- Oolafnoise @olafnoise
When the first reel bounce is working ok here is the message I get in the middle of bounce:
"counld not restore selection bounce Kitch test line 207" - In reply toolafnoise⬆:
Kitch Membery @Kitch2021-09-10 19:18:46.073Z
Hi @olafnoise,
Sorry it's not working. I think you may be right about the bounce wait time. I'll have to trouble shoot it over the weekend and see if I can make it break.
If you could upload a screen recording of it failing it may give me some insight into where/why the script is not behaving as expected.
Note: Regarding the switching to samples weirdness. This is expected behavior as it it inbuilt into the
clipDoForEachSelectedClip()
method.Rock on!
- Oolafnoise @olafnoise
Hi Kitch
sorry I didn't reply earlier ...too busy
Actually, today I tried your script on my little test sesssion I was using earlier (20 tracks or something)
..... and it still work fine ... so, it's not machine nor OS issue
But when I run it on a whole feature editing session (about 200 tracks and complex routings) I'm getting the "could not restore selection bounce Kitch test line 207" error
With a big session, the offline bounce takes a much longer time to start
I'll try to make a screen capture asapmany thanks for your time
all the best
Jean- Oolafnoise @olafnoise
You will find a screencap there:
https://u.pcloud.link/publink/show?code=XZn2SqXZVJnctzrVyIb3ALfYeszDnSUz9Oak
Kitch Membery @Kitch2021-09-11 21:15:07.732Z
Thanks for the Screen recording @olafnoise.
Due to the nature of the issue (ie. attempting it on my system, the bounce runs too fast to replicate what is happening on yours), I have added a few lines, to wait for Pro Tools main window before continuing.
Here is the new script. Hopefully it works. (Oh... and remember to customize your
bounceSettings
in the code :-)const bounceSettings = { presetNumber: undefined, libraryPresetName: undefined, //fileName: "", // Commented out as the file name as it is being created in the clipDoForEachSelectedClip() loop. clipSuffix: 'DIRECTS', fileType: "WAV (BWF)", mixSourceButtonTitle: 'Playback 1-2 (Stereo)', mixSourcePath: ['output', 'Playback 1-2 (Stereo) -> Playback 1-2'], mp3TargetValue: 'Disable', fileFormat: 'Multiple mono', bitDepth: '24 Bit', sampleRate: '48 kHz', padToFrameBoundary: 'Disable', importAfterBounce: 'Disable', fileDestination: 'Session Folder', //Options: 'Session Folder'|'Prompt For Location'|'Directory' sessionFolderPath: 'Bounced Files', onlineOffline: 'Enable', }; const bounceMixWin = sf.ui.proTools.windows.whoseTitle.is('Bounce Mix').first; function openBounceMixWindow() { //Open Bounce Mix Window sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }); bounceMixWin.elementWaitFor(); } function maximiseBounceWindow() { //Open all Bounce Mix Panels bounceMixWin.groups.forEach(group => { if (group.frame.h === 22) { if (group.buttons.whoseTitle.is('Collapser').first.exists) { group.buttons.whoseTitle.is('Collapser').first.elementClick(); } } }) } function setText(panel, text, index) { if (panel.textFields.allItems[index].value.invalidate().value !== text) { panel.textFields.allItems[index].elementSetTextFieldWithAreaValue({ value: text, }, `ERROR: ${text} ${index}`); } } function setPopupMenu(panel, path, index) { if (panel.popupButtons.allItems[index].value.invalidate().value !== path) { panel.popupButtons.allItems[index].popupMenuSelect({ menuPath: [path], }, `ERROR: ${path} ${index}`); } } function setBouncePreset(preset) { //Preset Buttons - mouseClickElement(); const presetButtons = bounceMixWin.children.filter(b => b.fullRole === "AXButton:AXToggle"); presetButtons[preset - 1].elementClick(); } function setLibraryPreset(preset) { const libraryMenu = bounceMixWin.children.whoseRole.is("AXMenuButton").whoseTitle.is("Librarian menu").first; //Librarian menu if (libraryMenu.value.invalidate().value !== preset) { libraryMenu.popupMenuSelect({ menuPath: [preset], }); } } function setTopPanel(settings) { const { fileName, fileType, mixSourceButtonTitle, mixSourcePath } = settings; //File Name - Text Field setText(bounceMixWin, fileName, 0); //File Type - Popup Menu setPopupMenu(bounceMixWin, fileType, 0); //Mix Source - Popup Menu if (bounceMixWin.popupButtons.allItems[1].value.invalidate().value !== mixSourceButtonTitle) { bounceMixWin.popupButtons.allItems[1].popupMenuSelect({ menuSelector: items => items.filter(item => item.path[0].endsWith(mixSourcePath[0]) && item.path[1].endsWith(mixSourcePath[1]))[0] }); } } function setAudioPanel(settings) { const { mp3TargetValue, fileFormat, bitDepth, sampleRate, padToFrameBoundary } = settings; const audioPanel = bounceMixWin.groups.whoseTitle.is("Audio").first //MP3 - Checkbox audioPanel.checkBoxes.whoseTitle.is("Add MP3").first.checkboxSet({ targetValue: mp3TargetValue, }); //File Format - Popup Menu setPopupMenu(audioPanel, fileFormat, 1); //Bit Depth - Popup Menu setPopupMenu(audioPanel, bitDepth, 2); //Sample Rate - Popup Menu (Have not yet implementedsupport Pull up/down sample rates ) setPopupMenu(audioPanel, sampleRate, 3); //Pad To Frame Boundary - Checkbox audioPanel.checkBoxes.whoseTitle.is("Pad To Frame Boundary").first.checkboxSet({ targetValue: padToFrameBoundary, }); } function setLocationPanel(settings) { let { importAfterBounce, fileDestination, sessionFolderPath, onlineOffline } = settings; const locationPanel = bounceMixWin.groups.whoseTitle.is("Location").first //Import After Bounce - Checkbox locationPanel.checkBoxes.whoseTitle.is("Import After Bounce").first.checkboxSet({ targetValue: importAfterBounce, }); //Session Folder - Radio Button if (fileDestination === 'Session Folder') { //Session Folder - Radio Button locationPanel.radioButtons.whoseTitle.is("Session Folder:").first.elementClick(); //Session Folder - Text Field setText(locationPanel, sessionFolderPath, 0); } else if (fileDestination === 'Prompt For Location') { //Prompt For Location - Radio Button locationPanel.radioButtons.whoseTitle.is("Prompt For Location").first.elementClick(); } else if (fileDestination === 'Directory') { //Directory: - Radio Button locationPanel.radioButtons.whoseTitle.is("Directory:").first.elementClick(); //Choose... - Button locationPanel.buttons.whoseTitle.is("Choose...").first.elementClick(); } //Offline - Checkbox bounceMixWin.checkBoxes.whoseTitle.is("Offline").first.checkboxSet({ targetValue: onlineOffline, }); } function doBounce(settings) { const { presetNumber, libraryPresetName } = settings; sf.ui.proTools.appActivateMainWindow(); openBounceMixWindow(); maximiseBounceWindow(); if (presetNumber !== undefined) setBouncePreset(presetNumber); if (libraryPresetName !== undefined) setLibraryPreset(libraryPresetName); setTopPanel(settings); setAudioPanel(settings); setLocationPanel(settings); //Click Bounce bounceMixWin.buttons.whoseTitle.is('Bounce').first.elementClick(); //Wait for bounce to finish (Wait for bounce dialog to appear, then to disappear) sf.ui.proTools.confirmationDialog.elementWaitFor({ timeout: 100000 }); sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); //-1 is endless timeout (cancel by Ctrl+Shift+Esc) while (sf.ui.frontmostApp.title.value !== "Pro Tools") { sf.wait({ intervalMs: 500 }); } } function getSelectedClipNamesFromClipList() { const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first; const selectedClips = clipsTable.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); const clipNames = selectedClips.map(c => c.split('"')[1]); return clipNames }; function bounceClip(bounceSettings) { const selectedClipName = getSelectedClipNamesFromClipList()[0]; const newFileName = `${selectedClipName} ${bounceSettings.clipSuffix}` bounceSettings.fileName = newFileName; doBounce(bounceSettings); } function bounceClips(bounceSettings) { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.clipDoForEachSelectedClip({ action: () => bounceClip(bounceSettings) }); alert('Done!'); } bounceClips(bounceSettings);
Rock on!
- Oolafnoise @olafnoise
YES!
I gived it a quick try tonight on a heavy sesiion and it's working ok !!!
I'll try to understand the diference between the two scripts tomorrow ...
Thousands thanks again Kitch
I owe you hundred of pints when you come to Paris
all the best
Jean