API Quick Start Guide
Introduction
The term API stands for “Application Programming Interface” and is used by software to access data, server software or other applications. Think of the API as a translator standing in-between two people who don’t speak the same language. In our case the API functions as a bridge between the internal Pixera objects and the outside world. Thereby an external software can communicate and interact with Pixera using the API.
Documentation
The latest API documentation can be found in the settings section of Pixera.
Go to settings > help > show API Documentation files.
USAGE
UDP
The User Datagram Protocol (UDP) is a simple connectionless Internet protocol. It functions without error-checking or package recovery. Which means that data is continuously sent to the recipient, whether or not they receive it. Although it is not ideal for services where data loss can’t be tolerated (like sending an email), it is largely preferred for real-time communications like broadcast or multitask network transmission. UDP is faster, simpler and more efficient than TCP, but it is not possible to retransmission lost data packets.
Open the settings tab in PIXERA (upper right corner).
- Go to “API”.
- Herein you can choose from which device PIXERA receives data (Input Network Adapter) and to which device it should send to (Output Network Adapter). The device is specified by its IP-address. For instance, if you want to control a remote Pixera instance from a Manager device you have to connect both via a network cable and enter the IP-address of the remote device in Input Network Adapter.
- The program then offers you two API access points as well as a Heartbeat port (which sends information regarding the other available ports every second in the form of a JSON string). Choose one of the two access ports and specify the protocol to use - in this case JSON/UDP – and a port number which can be any number i.e. You can find the utilized ports in Pixera Network Usage.
- For testing out and demonstrating the UDP connection we are using the “Hercules SETUP utility” which you can download via this link.
- After opening Hercules switch to the UDP tab and enter the IP-address you chose for the “Input Network Adapter” under “Module IP”. Enter your chosen port number under “Port” and “Local Port”. Click then on “Listen” to setup the connection.
Our goal is now to remote control the PIXERA mini we connected. The most basic operation would be to start and pause the timeline. To achieve this, we enter the following command into one of the three “Send”-fields:
{"jsonrpc":"2.0", "id":18, "method":"Pixera.Compound.setTransportModeOnTimelineAtIndex", "params":{"index":0, "mode":1}}
“index” specifies which timeline is targeted and “mode” what we want the timeline to do (Play = 1, Pause = 2, Stop = 3).
Clicking now on “Send” forwards the command to the mini and the timeline is started.
If we now want to pause the timeline again, we use:
{"jsonrpc":"2.0", "id":18, "method":"Pixera.Compound.setTransportModeOnTimelineAtIndex", "params":{"index":0, "mode":2}}
A collection of useful commands can be found at the end of this document.
To end the connection again click on “Close”.
TCP(dl)
The “Transmission Control Protocol” is a connection-oriented protocol, which means, as long as a connection is held up data can be transmitted in two directions. TCP has, in contrast to UDP, a built-in system to check for errors and package loss. It is therefore ideal for transferring information like data files and still images, but also creates a large network overhead. TCP provides an ordered delivery of data from user to server but is also significantly slower compared to UDP. The TCP(dl) protocol here explained uses a delimiter after each command in the form of “0xPX”.
Open the settings tab in PIXERA (upper right corner).
Go to “API”.
Herein you can choose from which device PIXERA receives data (“Input Network Adapter”) and to which device it should send to (“Output Network Adapter”). The device is specified by its IP-address. For instance, if you want to control your PIXERA device with your laptop you connect both via a network cable and enter the IP-address of Pixera under “Input Network Adapter”.
The program then offers you two API Access points as well as a Heartbeat port (which sends information regarding the other available ports every second in the form of a JSON string). Choose one of the two access ports and specify the protocol to use – in this case JSON/TCP(dl) – and a port number which can be any number (here 4023).
For testing out and demonstrating the TCP(dl) connection we are using the “BM Pixera API Test” by Benni Müller Link to Benni's Tools.
After opening API Test enter the IP-address you chose for the “Input Network Adapter” under “IP”, set “Port” to your chosen port number and set “Protocol” to JSON/TCP(dl). Click then on “Connect” to setup the connection.
The tool gives us the possibility to load the pixera_api.json file containing all API commands. This is done by clicking “Import” and selecting the path to the file, normally:
C:\Program Files\AV Stumpfl\Pixera\build_’version’\data\api\pixera_api.json
Instead of typing the different API commands we can now select them from the drop-down menu. For starting the timeline, we chose:
{"jsonrpc": "2.0","id": 23, "method": "Pixera.Compound.startFirstTimeline"}
Clicking on “Send” will deliver the command to PIXERA and start the timeline. Since TCP allows for communication in both directions, we can now also get information back from PIXERA. If, for instance, we want to know which screens are present in our setup we can use the command:
{"jsonrpc": "2.0","id": 72, "method": "Pixera.Screens.getScreenNames"}
Which shows us that one “Generic Flat Screen is present.
For closing the connection click on “Disconnect”.
WORKING WITH IDENTIFIERS
Often a single object needs to be addressed e.g. a screen or a specific timeline. To achieve that there are two different approaches: by name or by handle. The name of the object is the string that is associated with its internal identification number, whereby the handle is the internal identification number.
Addressing by Name
These API-commands belong to the “Compound” namespace. It contains functions that can be used without first gathering additional information. If you know the name or the position on the timeline of your object you are good to go. For this example, with have two timelines (“Timeline 1” and “Timeline2”) with cues that should be played in a predefined manner.
Firstly, the nowpointer of “Timeline 1” should be set to the position of “Cue1”. To achieve this, we are sending the following command over TCP(dl):
{"jsonrpc":"2.0", "id":29, "method":"Pixera.Compound.applyCueAtIndexOnTimelineAtIndex", "params":{"cueIndex":0, "timelineIndex":0}}0xPX
We are specifying the timeline and the cue via {"cueIndex":0,"timelineIndex":0}, since the indices are zero-based, we address the first timeline and the first cue via the index 0.
Next “Timeline 1” should be played:
{"jsonrpc":"2.0", "id":19, "method":"Pixera.Compound.setTransportModeOnTimeline", "params":{"timelineName":"Timeline1", "mode":1}}0xPX
Mode specifies the transport mode of the timeline (Play = 1, Pause = 2, Stop = 3).
After playing the content “Timeline 1” will hit the first jump cue and the nowpointer is transported to “Cue2”, where it is paused. Now “Timeline 2” should play its content. Therefore, at first we have to bring its nowpointer to “Cue3” (which is the second cue on this timeline):
{"jsonrpc":"2.0", "id":29, "method":"Pixera.Compound.applyCueAtIndexOnTimelineAtIndex", "params":{"cueIndex":1, "timelineIndex":1}}0xPX
“Timeline 2” is finished, and “Timeline 1” should be resumed. This can be done with a simple command:
{"jsonrpc": "2.0", id": 23,
"method": "Pixera.Compound.startFirstTimeline"}0xPX
Addressing objects by name and index is a convenient approach and will be sufficient in most cases, nevertheless it is an “quick and dirty” solution. While doing things this way on might encounter some problems:
• If a new cue is added the indices of all following cues are changed.
• If cues or timelines are renamed the API-commands must be modified as well.
• PIXERA will not prevent you from giving different objects the same name. Addressing one of those by its name will lead to undefines behavior.
For larger projects we therefore recommend the use of Handles.
Addressing by Handle
Each object in PIXERA has an internal ID which won’t be affect by renaming or reordering it. Therefore using API-commands addressing objects via their ID (the Handle) leads to a more adaptable and overall more reliable system. To demonstrate this we are again using the previous example of two timelines that should play their content in the right order.
At first, the nowpointer of “Timeline 1” should be set to the position of “Cue1”. At first, we need to know the handle of the timeline. To safe time later we are asking PIXERA right away for the handles of all present timelines:
{"jsonrpc":"2.0", "id":196, "method":"Pixera.Timelines.getTimelines"}0xPX
For which we are getting the following response:
{"id":196,"jsonrpc":"2.0", "result":[2614036689371202,7873039446800984]}0xPX
The first number is the handle of “Timeline 1” the second that of “Timeline 2”. Next we need to know the handles of the cues on the first Timeline. Therefore we pass the handle of “Timeline 1” as a parameter:
{"jsonrpc":"2.0", "id":202, "method":"Pixera.Timelines.Timeline.getCues", "params":{"handle":2614036689371202}}0xPX
This returns the handles of all four cues in order:
{"id":203,"jsonrpc":"2.0", "result":[3761355871439605, 5132625200808416,1876884015860716,1089863230171178]}0xPX
Since we are already warmed up, we will directly proceed with also finding out the cue-handles for “Timeline 2”:
{"jsonrpc":"2.0", "id":202, "method":"Pixera.Timelines.Timeline.getCues", "params":{"handle":7873039446800984}}0xPX
Which are:
{"id":203,"jsonrpc":"2.0","result":[7379839609728518, 8901128701472954,1284816309790436]}0xPX
This leaves us with following information:
Timeline Cue Handle
Timeline 1 - 2614036689371202
Cue1 (Pause) 3761355871439605
JumpCue1 5132625200808416
Cue2 (Pause) 1876884015860716
JumpCue2 1089863230171178
Timeline 2 - 7873039446800984
Cue4 (Pause) 7379839609728518
Cue3(Play) 8901128701472954
JumpCue3 1284816309790436
We can now play with those objects however we want, as long as the object is not deleted its handle will stay the same.
Now back to our project. We still want to bring the nowpointer on “Timeline 1” to the position of “Cue1” and play the content.
At first, we jump to the next cue which is “Cue1”:
{"jsonrpc":"2.0", "id":221, "method":"Pixera.Timelines.Timeline.moveToNextCue", "params":{"handle":2614036689371202}}0xPX
Then we set the mode of “Timeline 1” to play:
{"jsonrpc":"2.0", "id":208, "method":"Pixera.Timelines.Timeline.play", "params":{"handle":2614036689371202}}0xPX
Next “Timeline 2” should start playing at “Cue3”, so we are setting the nowpointer to “Cue3”
{"jsonrpc":"2.0", "id":301, "method":"Pixera.Timelines.Cue.apply", "params":{"handle":8901128701472954}}0xPX
Since “Cue3” is a play-cue the timeline will start playing automatically.
“Timeline 2” is finished, and we return to “Timeline 1”. The nowpointer is at “Cue2” and after playing the content it will jump back to this position. “Cue2” is a pause-cue, but this time we want to play the content in a loop. To achieve that we are going to change the type of “Cue2”:
{"jsonrpc":"2.0", "id":309, "method":"Pixera.Timelines.Cue.setOperation", "params":{"handle":1876884015860716, "operation":1}}0xPX
Whereby "operation" defines the cue-type (None = 0, Play = 1, Pause = 2, Stop = 3, Jump = 4). Still a play-command needs to be passed to the timeline:
{"jsonrpc":"2.0", "id":208, "method":"Pixera.Timelines.Timeline.play", "params":{"handle":2614036689371202}}0xPX
Now to end the loop we want to set the nowpointer to 01:00. Since the following command sets the time in frames, we therefore need to jump to frame 60:
{"jsonrpc":"2.0", "id":214, "method":"Pixera.Timelines.Timeline.setCurrentTime", "params":{"handle":2614036689371202, "time":60}}0xPX
Both timelines have finished, and the show can be prepared for the next run.
Even though working with handles may seem far more complicated then working with just names and indices, it will often circumvent issues. Commands that rely on the name of an object are solely part of the “Compound” namespace, which is a small part of the whole PIXERA-API. Hence without handles the power of the API is greatly restricted. Though for small projects this namespace will be sufficient in most cases.
IMPORTANT API-COMMANDS
All API-commands can be found under
C:\Program Files\AV Stumpfl\Pixera\build_’version’\data\api\docs
The file pixera_api_examples_rev contains all commands with an example of their use.
• Start, Stop, Pause Timeline by index
Sets the transport mode of the timeline with the given (zero-based) index. Mode Parameter: Play = 1, Pause = 2, Stop = 3.
{"jsonrpc":"2.0", "id":18, "method":"Pixera.Compound.setTransportModeOnTimelineAtIndex", "params":{"index":0, "mode":1}}
• Trigger cue by index
Triggers the cue with the given (zero-based) index, on the given timeline.
{"jsonrpc":"2.0", "id":29, "method":"Pixera.Compound.applyCueAtIndexOnTimelineAtIndex", "params":{"cueIndex":0, "timelineIndex":0}}
• Start, Stop, Pause single Layer
The layer is identified by a path separated by periods (e.g. "Timeline 1.Layer 1").
Play = 1, Pause = 2, Stop = 3. It can be looped.
{"jsonrpc":"2.0", "id":33, "method":"Pixera.Compound.setTransportModeOnLayer", "params":{"layerPath":" Timeline 1.Layer 1", "mode":1, "loop":true}}
• Setting current time in seconds and the Transport mode
The timeline is specified by its name, the time is specified in seconds.
Play = 1, Pause = 2, Stop = 3.
{"jsonrpc":"2.0", "id":38, "method":"Pixera.Compound.setCurrentTimeAndTransportModeOfTimelineInSeconds", "params":{"timelineName":"Timeline 1", "time":1.0, "mode":1}}
• Getting the current time in seconds
The timeline is specified by its name.
{"jsonrpc":"2.0", "id":41, "method":"Pixera.Compound.getCurrentTimeOfTimelineInSeconds", "params":{"timelineName":"Timeline 1"}}
• Shut down the local machine
mode: Shut down = 1, Shut down and turn off = 2, Shut down and reboot = 3.
{"jsonrpc":"2.0", "id":56, "method":"Pixera.Session.shutdownSystem", "params":{"mode":1}}
• Get handle of screen with given name
{"jsonrpc":"2.0", "id":69, "method":"Pixera.Screens.getScreenWithName", "params":{"name":"Abcd"}
• Get handles of all screens
{"jsonrpc":"2.0", "id":71, "method":"Pixera.Screens.getScreens"}
• Set position and rotation of screen
The handle of the screen needs to be passed as parameter.
Position is given in meters, rotation is given in degrees.
{"jsonrpc":"2.0", "id":347, "method":"Pixera.Direct.Screen.setPosRot", "params":{"handle":123456789, "xPos":1.0, "yPos":1.0, "zPos":1.0, "xRot":1.0, "yRot":1.0, "zRot":1.0}}
• Get handle of timeline with the given name
{"jsonrpc":"2.0", "id":195, "method":"Pixera.Timelines.getTimelineFromName", "params":{"name":"Timeline 1"}}
• Get handles of all timelines
{"jsonrpc":"2.0", "id":196, "method":"Pixera.Timelines.getTimelines"}
• Remove timeline by handle
{"jsonrpc":"2.0", "id":198, "method":"Pixera.Timelines.Timeline.removeThis", "params":{"handle":123456789}}
• Get all handles of all cues on timeline in chronological order
The handle of the chosen timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":202, "method":"Pixera.Timelines.Timeline.getCues", "params":{"handle":123456789}}
• Get handle of cue by index
The handle of the timeline and the index of the cue need to be passed as parameters.
{"jsonrpc":"2.0", "id":203, "method":"Pixera.Timelines.Timeline.getCueAtIndex", "params":{"handle":123456789, "index":1}}
• Create a cue and return its handle
handle = specifies the timeline
name = the name the cue should have
time = the time in seconds at which the cue should be created
operation: None = 0, Play = 1, Pause = 2, Stop = 3, Jump = 4
{"jsonrpc":"2.0", "id":206, "method":"Pixera.Timelines.Timeline.createCue", "params":{"handle":123456789, "name":"Abcd", "time":1.0, "operation":1}}
• Remove cue
The handle of the cue needs to be passed as parameter.
{"jsonrpc":"2.0", "id":300, "method":"Pixera.Timelines.Cue.removeThis", "params":{"handle":123456789}}
• Jump to and execute cue
The handle of the cue needs to be passed as parameter.
{"jsonrpc":"2.0", "id":301, "method":"Pixera.Timelines.Cue.apply", "params":{"handle":123456789}}
• Blends to and executes cue
The handle of the cue needs to be passed as parameter.
blendDuration is in seconds
{"jsonrpc":"2.0", "id":302, "method":"Pixera.Timelines.Cue.blendToThis", "params":{"handle":123456789, "blendDuration":1.0}}
• Get the operation mode of the cue
The handle of the cue needs to be passed as parameter.
operation: None = 0, Play = 1, Pause = 2, Stop = 3, Jump = 4
{"jsonrpc":"2.0", "id":308, "method":"Pixera.Timelines.Cue.getOperation", "params":{"handle":123456789}}
• Set the operation mode of the cue
The handle of the cue needs to be passed as parameter.
operation: None = 0, Play = 1, Pause = 2, Stop = 3, Jump = 4
{"jsonrpc":"2.0", "id":309, "method":"Pixera.Timelines.Cue.setOperation", "params":{"handle":123456789, "operation":1}}
• Set the operation mode of the cue
The handle of the cue needs to be passed as parameter.
operation: None = 0, Play = 1, Pause = 2, Stop = 3, Jump = 4
{"jsonrpc":"2.0", "id":309, "method":"Pixera.Timelines.Cue.setOperation", "params":{"handle":123456789, "operation":1}}
• Start the nowpointer at the current time
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":208, "method":"Pixera.Timelines.Timeline.play", "params":{"handle":123456789}}
• Stop the nowpointer at the current time
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":210, "method":"Pixera.Timelines.Timeline.stop", "params":{"handle":123456789}}
• Pause the nowpointer at the current time
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":209, "method":"Pixera.Timelines.Timeline.pause", "params":{"handle":123456789}}
• Set the current time in frames
The handle of the timeline needs to be passed as parameter.
1s = 60 frames
{"jsonrpc":"2.0", "id":214, "method":"Pixera.Timelines.Timeline.setCurrentTime", "params":{"handle":123456789, "time":1}}
• Get the current time in frames
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":215, "method":"Pixera.Timelines.Timeline.getCurrentTime", "params":{"handle":123456789}}
• Start, Stop, Pause a timeline
The handle of the timeline needs to be passed as parameter.
Play = 1, Pause = 2, Stop = 3.
{"jsonrpc":"2.0", "id":217, "method":"Pixera.Timelines.Timeline.setTransportMode", "params":{"handle":123456789, "mode":1}}
• Move to next cue on timeline
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":221, "method":"Pixera.Timelines.Timeline.moveToNextCue", "params":{"handle":123456789}}
• Move to previous cue on timeline
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":222, "method":"Pixera.Timelines.Timeline.moveToPreviousCue", "params":{"handle":123456789}}
• Ignore the next cue on timeline
The handle of the timeline needs to be passed as parameter.
{"jsonrpc":"2.0", "id":223, "method":"Pixera.Timelines.Timeline.ignoreNextCue", "params":{"handle":123456789}}
• Fade between current and goal time
The handle of the timeline needs to be passed as parameter.
goalTime = the position where to fade to
blendDuration = how long the fade should take
{"jsonrpc":"2.0", "id":224, "method":"Pixera.Timelines.Timeline.blendToTime", "params":{"handle":123456789, "goalTime":1.0, "blendDuration":1.0}}
• Get handle of layer by index
Returns the handle of the layer at the given (zero-based) index on the timeline specified by its handle.
{"jsonrpc":"2.0", "id":200, "method":"Pixera.Timelines.Timeline.getLayerAtIndex", "params":{"handle":123456789, "index":0}}
• Get handles of all layers
Returns the handles of all layers on the timeline specified by its handle.
{"jsonrpc":"2.0", "id":199, "method":"Pixera.Timelines.Timeline.getLayers", "params":{"handle":123456789}}
• Mute a layer
The handle of the layer needs to be passed as parameter.
{"jsonrpc":"2.0", "id":247, "method":"Pixera.Timelines.Layer.muteLayer", "params":{"handle":123456789}}
• Un-Mute a layer
The handle of the layer needs to be passed as parameter.
{"jsonrpc":"2.0", "id":248, "method":"Pixera.Timelines.Layer.unMuteLayer", "params":{"handle":123456789}}
• Remove layer
The handle of the layer needs to be passed as parameter.
{"jsonrpc":"2.0", "id":270, "method":"Pixera.Timelines.Clip.removeThis", "params":{"handle":123456789}}