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.
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.
|||RESET||C Button Above wheel|
|||INCREASE SPEED||Jog Clockwise|
|||DECREASE SPEED||Jog Anti-Clockwise|
|||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.
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:
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:
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
(sets its own notes field to the JSON record obtained from querying the cue PANO to obtain image size)
The cue numbered SCREEN
(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.
We do a similar thing to find the cursor position required for the screen size using:
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.
You can download the workspace here
and the Shuttle Controller setting here
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:
and here is the original video it was made from:
Cover Image Credit: Original Image Karl Gruber / Wikimedia Commons /
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.