Last active
March 24, 2026 12:17
-
-
Save skutov/bb4bec1b80fd4bec33fbe0a01226c9fd to your computer and use it in GitHub Desktop.
Qlab create timecode and groups for selected cues
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| tell application id "com.figure53.QLab.5" | |
| tell front workspace | |
| set selectedCues to selected as list | |
| if (count of selectedCues) is 0 then | |
| display dialog "No cues selected." buttons {"OK"} | |
| return | |
| end if | |
| ------------------------------------------------------------------ | |
| -- Set frame rate | |
| ------------------------------------------------------------------ | |
| set fps to 24 | |
| ------------------------------------------------------------------ | |
| -- Find longest duration | |
| ------------------------------------------------------------------ | |
| set longestDuration to 0 | |
| repeat with theCue in selectedCues | |
| try | |
| set d to duration of theCue | |
| if d > longestDuration then set longestDuration to d | |
| end try | |
| end repeat | |
| set roundedDuration to (round longestDuration rounding as taught in school) | |
| ------------------------------------------------------------------ | |
| -- Ask for increment | |
| ------------------------------------------------------------------ | |
| set autoIncrement to longestDuration + 2 | |
| set dialogText to "Longest cue duration is " & roundedDuration & " seconds." & return & return & "Choose timecode increment:" | |
| set choice to button returned of (display dialog dialogText buttons {"1 hour", "30 minutes", "10 minutes"} default button "1 hour") | |
| if choice is "Auto (longest + 2s)" then | |
| set incrementSeconds to autoIncrement | |
| else if choice is "1 hour" then | |
| set incrementSeconds to 3600 | |
| else if choice is "30 minutes" then | |
| set incrementSeconds to 1800 | |
| else if choice is "10 minutes" then | |
| set incrementSeconds to 600 | |
| else | |
| set userInput to text returned of (display dialog "Enter custom increment in seconds:" default answer (roundedDuration as string)) | |
| set incrementSeconds to userInput as number | |
| end if | |
| ------------------------------------------------------------------ | |
| -- Ask for first timecode | |
| ------------------------------------------------------------------ | |
| set dialogText to "Choose starting timecode:" | |
| set choice to button returned of (display dialog dialogText buttons {"1 hour", "10 minutes", "1 minute"} default button "1 hour") | |
| if choice is "1 hour" then | |
| set timeOffset to 3599 | |
| else if choice is "10 minutes" then | |
| set timeOffset to 599 | |
| else if choice is "1 minute" then | |
| set timeOffset to 59 | |
| end if | |
| ------------------------------------------------------------------ | |
| -- Build cues | |
| ------------------------------------------------------------------ | |
| set selectedCues to selected as list | |
| repeat with theCue in selectedCues | |
| set parentList to parent of theCue | |
| set cueName to q name of theCue | |
| if contents of cueName is "" | |
| set cueName to q default name of theCue | |
| end if | |
| -- Get duration safely | |
| set cueDuration to 0 | |
| try | |
| set cueDuration to duration of theCue | |
| end try | |
| set pre wait of theCue to 1 | |
| set selected to theCue | |
| make type "Group" | |
| set newGroup to last item of (selected as list) | |
| set mode of newGroup to timeline | |
| -- Build timecode strings | |
| set tcStartString to my secondsToTimecode(timeOffset, fps) | |
| set tcPlusOneString to my secondsToTimecode(timeOffset + 1, fps) | |
| -- Prefix name with (start timecode + 1s) | |
| set q name of newGroup to (tcPlusOneString & " - " & cueName) | |
| move theCue to end of newGroup | |
| -- Create timecode cue | |
| make type "timecode" | |
| set tcCue to last item of (selected as list) | |
| move tcCue to end of newGroup | |
| set pre wait of tcCue to 0 | |
| set timecode start time of tcCue to tcStartString | |
| set duration of tcCue to (cueDuration + 2) | |
| -- Increment offset | |
| set timeOffset to timeOffset + incrementSeconds | |
| end repeat | |
| end tell | |
| end tell | |
| ------------------------------------------------------------------ | |
| -- Convert seconds ? timecode using detected FPS | |
| ------------------------------------------------------------------ | |
| on secondsToTimecode(totalSeconds, fps) | |
| set totalFrames to totalSeconds * fps | |
| set tcHours to totalFrames div (fps * 3600) | |
| set remainder1 to totalFrames mod (fps * 3600) | |
| set tcMinutes to remainder1 div (fps * 60) | |
| set remainder2 to remainder1 mod (fps * 60) | |
| set tcSeconds to remainder2 div fps | |
| set frames to remainder2 mod fps | |
| return (my pad2(tcHours) & ":" & my pad2(tcMinutes) & ":" & my pad2(tcSeconds) & ":" & my pad2(frames)) | |
| end secondsToTimecode | |
| on pad2(n) | |
| if n < 10 then | |
| return "0" & n | |
| else | |
| return n as string | |
| end if | |
| end pad2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment