No internet connection
  1. Home
  2. How to

How to stop action based on playback state retriggering.

By Brandon Jiaconia @Brandon_Jiaconia
    2024-08-19 23:24:24.847Z

    I'm using a script that changes the video window in Pro Tools based on the playback state. When playback is started, the video goes full screen. When playback stops, the video goes to quarter size and moves to the top left of the window. I'm using a second script to toggle this behavior. If I don't toggle the script to "Off" The stop behavior repeats (attempting to quarter size and reposition the video window). Was wondering if there is a way to make the stop behavior only happen once after stopping. Here is the script:

    function runForever(name, action, interval, timeout) {
        var now = (new Date).valueOf();
        if (now - globalState[name] < timeout) throw 0; // Exit if we were invoked again inside the timeout
    
        globalState[name] = now;
        sf.engine.runInBackground(function () {
            try {
                while (true) {
                    sf.engine.checkForCancellation();
    
                    action();
    
                    sf.wait({ intervalMs: interval, executionMode: 'Background' });
                }
            } finally {
                globalState[name] = null;
            }
        });
    }
    
    function main() {
        // If the toggle is off, exit early.
        if (!globalState.isrunForever) return;
        if (sf.ui.proTools.mainWindow.sessionPath != null) {
            const ptIsPlaying = sf.ui.proTools.isPlaying;
    
            // Initialize the stopped flag in globalState if not already set
            if (globalState.hasStopped === undefined) {
                globalState.hasStopped = false;
            }
    
            if (globalState.playState != ptIsPlaying) {
                if (ptIsPlaying) { // If Pro Tools is playing
    
                    // Reset the flag since playback has started
                    globalState.hasStopped = false;
    
                    // Fullscreen Video Window
    
                    const videoWin = sf.ui.app("com.avid.AvidVideoEngine").windows.whoseTitle.is(" ");
    
                    if (!videoWin.first.exists) {
                        sf.ui.proTools.menuClick({
                            menuPath: ["Window", "Video"]
                        });
                        sf.wait({ intervalMs: 10 });
                    }
    
                    sf.ui.app('com.avid.AvidVideoEngine').windows.whoseTitle.is(' ').first.popupMenuOpenFromElement({
                        relativePosition: { x: 5, y: 26 },
                        isRightClick: true,
                        timeout: 1,
                        onError: "Continue"
                    });
    
                    sf.keyboard.press({ keys: "down", repetitions: 4, fast: true });
                    sf.keyboard.press({ keys: "return", fast: true });
    
                } else if (!ptIsPlaying && !globalState.hasStopped) { // If Pro Tools is stopped and this block hasn't been executed yet
    
                    // Set the flag to true to prevent this block from running again
                    globalState.hasStopped = true;
    
                    // Resize, Reposition Video Window
    
                    sf.ui.app('com.avid.AvidVideoEngine').windows.whoseTitle.is(' ').first.popupMenuOpenFromElement({
                        relativePosition: { x: 5, y: 26 },
                        isRightClick: true,
                        timeout: 1,
                        onError: "Continue"
                    });
    
                    sf.keyboard.press({ keys: "down", repetitions: 1 });
                    sf.keyboard.press({ keys: "return" });
    
                    sf.ui.app('com.avid.AvidVideoEngine').windows.first.windowMove({
                        position: { x: 0, y: 0 },
                        size: { x: 500, y: 500 }
                    });
                }
            }
            globalState.playState = ptIsPlaying;
        }
    }
    // Initialize globalState.isrunForever if it doesn't exist
    if (globalState.isrunForever === undefined) {
        globalState.isrunForever = true;
    }
    runForever("play_Stop", main, 1000, 10000);
    

    And Here is the toggle:

    // Toggle the isrunForever state
    globalState.isrunForever = !globalState.isrunForever;
    
    log(`Video Tracking is now: ${globalState.isrunForever ? 'ON' : 'OFF'}`);
    

    Anyone help would be appreciated !

    Solved in post #3, click to view
    • 12 replies
    1. B
      Brandon Jiaconia @Brandon_Jiaconia
        2024-08-21 18:15:06.789Z

        Here is the script I'm using in the meantime:

        const videoWin = sf.ui.app("com.avid.AvidVideoEngine").windows.whoseTitle.is(" ");
        
        // If the Video window is not open, open it.
        if (!videoWin.first.exists) {
            sf.ui.proTools.menuClick({
                menuPath: ["Window", "Video"]
            });
        
            sf.wait({ intervalMs: 100 });
        }
        //Select Fullscreen
        sf.ui.app('com.avid.AvidVideoEngine').windows.whoseTitle.is(' ').first.popupMenuOpenFromElement({
            relativePosition: { "x": 5, "y": 26 },
            isRightClick: true,
            timeout: 1,
            onError: "Continue"
        });
        
         sf.keyboard.press({
                keys: "down",
                repetitions: 4,
                fast: true
            });
         sf.keyboard.press({
                keys: "return",
                fast: true
            });
        
        sf.wait({ intervalMs: 50});
        // Play
        sf.keyboard.press({keys: "space"});
        sf.wait({ intervalMs: 50});
        
        
        // Wait For Playback to Finish
        while (sf.ui.proTools.isPlaying) {
            sf.wait();
        }
        //Select Quarter Size 
        sf.ui.app('com.avid.AvidVideoEngine').windows.whoseTitle.is(' ').first.popupMenuOpenFromElement({
            relativePosition: { "x": 5, "y": 26 },
            isRightClick: true,
            timeout: 1,
            onError: "Continue"
        });
        
         sf.keyboard.press({
                keys: "down",
                repetitions: 1,
                fast: true
            });
         sf.keyboard.press({
                keys: "return",
                fast: true
            });
        
        //Postion Video Window
        sf.ui.app('com.avid.AvidVideoEngine').windows.first.windowMove({
            position: {
                x: 0,
                y: 0,
            },
            size: {
                x: 500,
                y: 500,
            }
        });
        
        
        
        1. Kitch Membery @Kitch2024-08-21 23:40:43.184Z

          Hi @Brandon_Jiaconia,

          At first glance, your use of globalState looks to be correct, however, I can see a situation where using the runforever script could cause problems.

          Here is a refactored version of your workaround that may be a bit more stable. :-)

          const videoWindowSettings = {
              whenPlaying: { size: "Fullscreen", position: { x: 0, y: 0 } },
              whenStopped: { size: "Quarter Size", position: { x: 500, y: 500 } },
          }
          
          const videoEngine = sf.ui.app("com.avid.AvidVideoEngine")
          videoEngine.invalidate();
          
          // Get the Video Engine window
          const videoWin = videoEngine.windows.whoseTitle.is(" ").first
          
          /**
           * This function ensures the Video window is displayed.
           */
          function ensureVideoWindow() {
              // If the Video window is not open, open it.
              if (!videoWin.exists) {
                  sf.ui.proTools.menuClick({
                      menuPath: ["Window", "Video"]
                  });
          
              }
              videoWin.elementWaitFor();
              videoWin.elementRaise();
          }
          
          /**
           * Custom function to set the size of the video window as it's UI Elements accessibility is limited
           * @param {object} args
           * @param {"Quarter Size"|"Half Size"|"Actual Size"|"Double Size"|"Fullscreen"|string} args.size
           * @param {PointF} args.position
           */
          function setVideoSize({ size, position = { x: 0, y: 0 } }) {
              const sizeMenuIndexLookup = {
                  "Quarter Size": 0,
                  "Half Size": 1,
                  "Actual Size": 2,
                  "Double Size": 3,
                  "Fullscreen": 4
              };
          
              const relativePosition = { x: 10, y: 30 };
              const menuItemTopMargin = 4;
              const menuItemHeight = 18;
          
              videoWin.invalidate();
          
              const menuItemPosition = {
                  x: videoWin.position.x + relativePosition.x + 30,
                  y: videoWin.position.y + relativePosition.y + menuItemTopMargin + (menuItemHeight / 2) + (sizeMenuIndexLookup[size] * 20)
              };
          
              videoWin.popupMenuOpenFromElement({
                  anchor: "TopLeft",
                  relativePosition,
                  isRightClick: true,
                  onError: "Continue",
                  timeout: 1,
              });
          
              // Click the position of the menu item
              sf.mouse.click({ position: menuItemPosition });
          
              if (size !== "Fullscreen") {
                  videoWin.invalidate();
          
                  videoWin.windowMove({
                      position: {
                          x: position.x,
                          y: position.y,
                      },
                  });
              }
          }
          
          function main() {
              // Ensure the video window is open.
              ensureVideoWindow();
          
              const play = () => { if (!sf.ui.proTools.isPlaying) sf.app.proTools.invalidate().togglePlayState(); };
          
              const waitForPlayBackToStop = () => {
                  while (sf.app.proTools.invalidate().getTransportState().currentSetting !== "TransportStopped") {
                      sf.wait({ intervalMs: 100 });
                  }
              };
          
              // Press play if not already playing
              play();
          
              // Set video size and position
              setVideoSize({
                  size: videoWindowSettings.whenPlaying.size,
                  position: videoWindowSettings.whenPlaying.position,
              });
          
              // Wait for playback to stop
              waitForPlayBackToStop();
          
              // Restore video size and positions
              setVideoSize({
                  size: videoWindowSettings.whenStopped.size,
                  position: videoWindowSettings.whenStopped.position,
              });
          }
          
          main();
          
          Reply2 LikesSolution
          1. BBrandon Jiaconia @Brandon_Jiaconia
              2024-08-22 13:15:32.079Z

              Thanks Kitch! Really appreciate it - it works great and is helping me learn!!

              1. Kitch Membery @Kitch2024-08-22 17:15:32.484Z

                Wonderful. :-)

              2. In reply toKitch:

                This is cool, how are you triggering it now that it's not a run forever?

                1. Kitch Membery @Kitch2024-08-22 20:41:06.911Z

                  Hi @Owen_Granich_Young,

                  The waitForPlayBackToStop(); function waits for playback to end. :-)

                  1. I see, but you press a button to start it? Or is there a 'on playback start' trigger?

                    1. Ohhh i seee it's got 'play' built into it. hmmm hmm so doesn't just trigger on regular space bar, could would need to replace. sorry!

                      1. Kitch Membery @Kitch2024-08-22 20:53:32.351Z

                        Yeah, playback is triggered by a manual press for the new version.

                        It could be good to eventually get it working with the auto implementation.

                        1. Well I can't figure out what Ctrl+Spacebar does, so I might replace that, I could see this being really useful when I'm on my laptop. (although a portable screen also solves the issue.)

                          1. Kitch Membery @Kitch2024-08-22 20:56:09.593Z

                            Ctrl+Spacebar for the win!

                            1. BBrandon Jiaconia @Brandon_Jiaconia
                                2024-08-22 20:59:53.068Z

                                I've been using Ctrl+Space for this as well. Opt+Space for another version too !