Teleprompt Corner & Scrolling Panoramas

This chapter is all about controlling the rate of scroll live. In the Y axis this will be useful for teleprompter type applications, and in the X axis for scrolling panoramas.

It’s worth pointing out that if you want a teleprompter for serious conference use, as opposed to some lightweight teleprompt style content in a show, then you are far better off spending 50 bucks on a program designed to do that exclusively. This project is restricted to the maximum graphic render size within QLab (images or text about 17000 pixels high), which might limit the length of your text considerably. If your text or image is rendered as solid white your image size is too large!. It won’t scroll text as nicely as a program designed to do just that, and the text editor won’t follow the onscreen cursor position, so if a speaker wants an edit you will have to find the matching point  in the text cue manually. However for many casual uses it can produce usable results.

The method can also be adapted to control horizontal scrolling of wide panoramas.

Teleprompter-Scrolling Y

Here it is in action, controlled with a Contour Shuttle:

The Jog wheel speeds up and slows down the rate of scroll.

The Shuttle wheel Fast Forwards and Rewinds.

The buttons immediately underneath the shuttle wheel scroll at the default speed
(Left and Right handed operation).

The buttons at the bottom STOP the scroll.

The Button in the centre above the shuttle wheel resets to the top.

All controller functions can also be performed by key presses.

Key Function Controller
[5] RESET C Button Above wheel
[2] INCREASE SPEED Jog Clockwise
[3] STOP Bottom Buttons
[1] DECREASE SPEED Jog Anti-Clockwise
[4] DEFAULT SPEED Buttons under wheel
HOTKEYS or SHUTTLE wheel variables
[NUM ⇧7] -16 pixels per step Shuttle Wheel L
[NUM ⇧6] -8 pixels per step Shuttle Wheel L
[NUM ⇧5] -6 pixels per step Shuttle Wheel L
[NUM ⇧4] -4 pixels per step Shuttle Wheel L
[NUM ⇧3] -2 pixels per step Shuttle Wheel L
[NUM ⇧2] -1 pixels per step Shuttle Wheel L
[NUM ⇧1] -0.5 pixels per step Shuttle Wheel L
[NUM 0] STOP Sprung Return
[NUM 1] 0.5 pixels per step Shuttle Wheel R
[NUM 2] 1 pixels per step Shuttle Wheel R
[NUM 3] 2 pixels per step Shuttle Wheel R
[NUM 4] 4 pixels per step Shuttle Wheel R
[NUM 5] 6 pixels per step Shuttle Wheel R
[NUM 6] 8 pixels per step Shuttle Wheel R
[NUM 7] 16 pixels per step Shuttle Wheel R

How it works:

The text is in the text tab of the inspector in a standard text cue. QLab treats it as if it was a transparent still image in a video cue. It has pixel dimensions that can be seen in the text window.

textwindow

Each time a key is pressed (or the shuttle controller emulates those key presses), it triggers a cue which adds or subtracts an amount from the rate which is stored in the ScaleY variable of a cue numbered VARIABLES.

e.g every time the jog wheel rotates 1 click clockwise it triggers a network cue with the following OSC message:

/cue/VARIABLES/scaleY/+ 0.05

A Network cue with a long duration, numbered OSCsuperscroll, continuously queries the VARIABLES cue for the current value of scaleY (which we are using to store the current rate in ), and adds the value to the current Y position of the text.

/cue/PANO/translationY/+ #/cue/VARIABLES/scaleY/# #v#

This means, increment the Y position of the cue numbered PANO (our text cue) by the value stored in the X Scale (which we are using for rate) of the cue numbered VARIABLES. We set the fade to 1D. the #v# argument would normally tell QLab to insert the current value of the OSC fade, but in this case is ignored. The purpose of making the OSC cue think it is an OSC fade cue is to force it to repeat 20 times faster,  during the cues long duration, than if it was an OSC message without a fade.

Currently, we have no control over how quickly the OSC messages repeat. They are sent around 100 times per second in a network cue (in practice about 10 percent slower) with a 1D fade on the OSC argument, and So the RATE control is actually setting the number of pixels that the y position of the text is shifted, every time an OSC message is fired.

For a network cue with duration but no fade set, the data rate is around 20 messages per second.

Even at high data rates, scrolls controlled by OSC cues do not look as smooth as might be  expected. Some messages don’t get through and with those that do there is a high degree of jitter. For instance you might get a movement of 1 pixel in 2ms followed by the next 1 pixel movement 14ms later and the next 2ms then 15ms then 19ms. This is the main limitation to using this method at higher scroll speeds.

Here’s the complete cue list:

telecues

There is 1 main cue which does all the work. In addition there are the cues that are triggered to increment or decrement the rate as explained above, and a few cues which store variables.

When the ‘fire all children group cue numbered START is triggered:

It stops the OSC cues with duration, so they reset.

It starts Network  cues to find out the  dimensions in pixels  of our text cue, and store it in the cue’s notes field  . It also finds out the display size of the surface  that the cue is going to be sent to:

The cue numbered height
/cue/Height/notes “#/cue/PANO/cueSize#”
(sets its own notes field to the JSON record obtained from querying the cue  PANO to obtain image size)

The cue numbered SCREEN
/cue/SCREEN/notes “#/cue/PANO/surfaceSize#”
(sets its own notes field to the JSON record obtained from querying the cue  PANO to obtain surface size)

We will need this info in a moment to find the top of the text and set the cursor markers to the left of the display.

It then  triggers the text cue and displays it on the chosen surface.

It displays the cursor markers and the speed indicator. (which are actually text cues)

It triggers the first cue in a ‘fire first child and go to next cue’ group cue. This sets the text to the first line. We can also get it to start at the end or in the middle by altering the order of the children in the group cue. (This is mainly so we can use the same cue list with images by substituting a video cue numbered PANO for the existing text cue.)

These cues have quite messy  scripts to extract the height of the text cue from the image size  record. It does this by throwing away everything else,  in the cueSize record which is stored in the notes field of  the cue numbered ‘height.’

This string stored in the notes of cue height is:

{

    height = 6378;

    width = 1500;

}

This script strips away everything apart from the value of height (6378) and then sets the initial y position of the text cue with this.

set translation y of cue “PANO” to – ((height / 2) * (scale y of cue “PANO”))

This takes half the height of the text in pixels multiplied by any scaling and sets the y translation of the cue (from the anchor at it’s centre)  to minus that value.

The rest of the script extracts, by brute force, the value of height. (There are many clever ways of converting from JSON records to AppleScript lists, but this get’s the job done in a simple way). As it only needs to do this once there is very little disadvantage in using this unsophisticated method.

–set translation y to top of image
tell application id “com.figure53.QLab.4” to tell front workspace
set thetext to (notes of cue “Height”)
set AppleScript’s text item delimiters to “{“
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set AppleScript’s text item delimiters to “}”
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set height to (word 3 of thetext as number) –the height of the image
set thetext to (notes of cue “SCREEN”)
set AppleScript’s text item delimiters to “{“
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set AppleScript’s text item delimiters to “}”
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set screenheight to (word 3 of thetext as number) — the screen height
set translation y of cue “PANO” to -((height / 2) * (scale y of cue “PANO”))
end tell

We do a similar thing to find the cursor position required for the screen size using:

–set translation x to left hand side of image
tell application id “com.figure53.QLab.4” to tell front workspace
set thetext to (notes of cue “SCREEN”)
set AppleScript’s text item delimiters to “{“
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set AppleScript’s text item delimiters to “}”
set theTextItems to every text item of thetext
set AppleScript’s text item delimiters to “”
set thetext to theTextItems as string
set screenwidth to (word 6 of thetext as number) — the screen width
set translation x of cue “SPEED” to -((screenwidth / 2) – 30)
set translation x of cue “CURSOR1” to -((screenwidth / 2) – 25)
set translation x of cue “CURSOR2” to -((screenwidth / 2) – 25)
end tell

Finally, we start the 2 Network cues which have a long duration so they continuously repeat, OSCsuperscroll which we looked at earlier and SPEEDO which displays the rate (actually number of pixels moved per OSC message) on the screen.

/cue/SPEED/text “#/cue/VARIABLES/scaleY#”

You can download the workspace here

and the Shuttle Controller setting here

Panoramas-Scrolling X

pass

Generally, the smoothest way of scrolling  between 2 points of a video that is wider than the output display is to use a fade cue. But this is only useful if we want to end up at defined positions, and at set speeds. Once a fade is initiated we have no control over the rate, or the ability to slow down to stop at a completely arbitrary point, something we might want to do with a scrolling background for an actor who is jogging on the spot for instance.

One solution is very similar to the previous teleprompter example  but working horizontally instead of vertically We can now modify the workspace to use the same controls to achieve this:

The structure of the cue list is almost identical.

Here are the major changes

We are storing the rate in translation Y of the VARIABLES cue.

The AppleScript that throws away superfluous information from the screen size and video cue size records is modified to extract the width instead of the height.

The starting point cues, set to the left, centre, or right of the image, and take account of the screen width so that the screen is filled. e.g

set translation x of cue “PANO” to -((width / 2) * (scale x of cue “PANO”) – (screenwidth / 2))

The cue numbered “OSCsuperscroll now increments or decrements the X translation of the video cue.

All other controls remain broadly the same.

This method is only really suitable for very slow moving scrolls, as we are increasing the size of each movement rather than speeding up the rate the movements happen. It is very good for imperceptible movements, where the audience only realise after half an hour that they re looking at something completely different.

You can download the workspace with a placeholder grid here

You can download the workspace with the example image here

If your interested in the slitscan technique.  here is the rendering:

pass and here is the original video it was made from:

keep it rollin from Jan Goldfuß on Vimeo.

Cover Image Credit: Original Image Karl Gruber / Wikimedia Commons / CC BY-SA 4.0
Modified Image by Mic Pool, distributed under the same license

Shuttle Controllers are  products of Contour Design. All trademarks acknowledged.

Slitscan processing of image used in panorama example, by Mic Pool
from an original video by Jan Goldfuß . All rights reserved.

MenuGraphic