Ventuz Director is a template-based show control application that has been designed to remote control one or multiple Ventuz Runtimes. The already large range of functions can be extended by Plugins. Nevertheless there are some use cases where it makes sense to control Director itself. This is possible since Ventuz version 5.4.0 by using GPI triggers and now gets extended by a full Remoting API that allows you to connect via Websocket or REST.
This makes it possible and fairly simple to integrate Director into any existing workflow. It can easily be connected to existing software like a broadcast controller or just be controlled from a custom web app.
You can use a websocket connection to Ventuz Director and send commands to control it. The websocket URL is ws://<Machine IP>:20404/DirectorRemoting_Service/1.0/commands/ws. When the connection is established you can send messages in a special JSON format to remote Director.
The format of a websocket remoting message (request) looks like follows:
{ "Command":"<command>", "RequestID":"<int>", "<Parameter Name>": "<value>" }
The Command and RequestID entries are mandatory! Certain commands do have one or multiple optional or mandatory parameters that can be added to the message.
In REST the command is part of the URL itself http://<Machine IP>:20404/DirectorRemoting_Service/1.0/commands/api/:<command>, therefore a sample command for activating a certain Topology looks like this http://<Machine IP>:20404/DirectorRemoting_Service/1.0/commands/api/:topology.set. If a command has certain parameters they are added in JSON as a multi-part request.
{ "Name": "Test Topology" }
Parameter marked with * are required for the specific command.
Command | Parameter | REST Method | Result Parameter | Description | |
---|---|---|---|---|---|
Application | |||||
log.write | Level<string>*: Desired log level. Message<string>*: User-defined message. SourceModul<string>: Origin module of the log message. InstanceId<string>: Identifier to distinguish different instances of the same module type. MessageId<int>: Numeric id to identify pre-defined log messages. PopUp<bool>: Specifies if the log message is presented in a popup message box. ExceptionMessage<string>: An exception that may have caused the log message will be generated and logged. | POST | none | Writes a log entry on five different levels provided by the user: Verbose, Info, Warning, Error or Fatal. | |
status.get | none | POST | Version<string>, LifetimeMs<long>, User<string>, Machine<string>, TopologyName<string>, TopologyState<string>, ShowId<guid>, ShowName<string>, ShowUri<string>,ProjectId<guid>, ProjectName<string>, ProjectUri<string>, RemotePlaylistId<guid>, ChannelCount<int> | Retrieves an object which contains some useful general information. | |
Window | |||||
window.fullscreen | none | POST | none | Switches between fullscreen and window mode. | |
window.reverse | none | POST | none | Reverses the window to its previous size. | |
window.getlayout | none | POST | Index(<int>), Name<string> | Retrieves the available window layouts. Only available inside an active show! | |
window.setlayout | Index(<int>*): Layout index. Not required if Name is provided. Name(<string>*): Layout name. Not required if Index is provided. | POST | none | Activates the selected window layout. | |
window.can.setlayout | Index(<int>*): Layout index. Not required if Name is provided. Name(<string>*): Layout name. Not required if Index is provided. | POST | none | Checks if the requested window layout can be set. | |
Topology | |||||
topology.get | none | GET | Name<string>, SourceType <DefaultTopology,LocalFile,EmbeddedInProject> | Returns a list of available Shows, retreived through VMS | |
topology.set | Name<string>*: Topology name. SaveTopology<bool>: If true, the current topology is saved before switching. TimeOut<long>: Milliseconds to wait for Ventuz Presenter to load and validate the scenes after topology set. Response will contain a warning if exceeded. | POST | none | Activates the selected topology. After the command is executed it will wait for the initialization of all Client Systems. If a timeout is presented the status will be SucceededWithWarnings. | |
topology.status | none | GET | Name<string>, NumberOfPorts<int>, State<Ok,Warning,Error> | Gets the Info of the current active Topology. | |
Show | |||||
show.get | none | POST | Id<guid>, ProjectId<guid>, PublishContextId<guid>, Uri<string>, Description<string> | Retrieves information about the current show | |
show.open | Uri<string>*: Uri or path of the show file. TimeOut<long>: Milliseconds to wait for Ventuz Presenter to load and validate the scenes. Response will contain a warning if exceeded. | POST | none | Opens a show through its local path. After the command is executed it will wait for the initialization of all Clients. If a timeout is presented the status will be SucceededWithWarnings. | |
show.close | SaveShow<bool>: If true the current show will be saved before it is closed. ClearRenderer<bool>: If true, the renderer output will be cleared. | POST | none | Closes the active show | |
show.cue | Uri<string>*: Uri of the template or page OR TemplateData<string>*: Template data in JSON format. OR TemplateDisplayName<string>*: Name of a template.(If multiple with the same name, first will be cued.) OR PageDisplayName<string>*: Name of a Director Page. (If multiple with the same name, first will be cued.) ChannelIndex<int> IgnoreChannelRules<bool>: If true, rules for the channel are ignored. If ChannelIndex is not provided, rules of all channels will be ignored. TimeOut<long>:TimeOut<long>: Milliseconds to wait for Ventuz Presenter to load and validate the scenes. Response will contain a warning if exceeded. | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a cue on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.can.cue | Uri<string>*: Uri of the template or page OR TemplateData<string>*: Template data in JSON format. OR TemplateDisplayName<string>*: Name of a template. OR PageDisplayName<string>*: Name of a Director Page. ChannelIndex<int> IgnoreChannelRules<bool>: If true, rules for the channel are ignored. If ChannelIndex is not provided, rules of all channels will be ignored. TimeOut<long>:TimeOut<long>: Milliseconds to wait for Ventuz Presenter to load and validate the scenes. Response will contain a warning if exceeded. | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Checks wether a specific template or page can be cued on a certain Channel. | |
show.can.cuechannel | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Checks wether anything can be cued on a certain Channel. | |
show.take | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a take on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.can.take | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Checks wether a take or a take and recue can be performed on a certain Channel. | |
show.takerecue | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a take and recue on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.recueonair | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a recue on-air on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.can.recueonair | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Checks if recue of the active Template or Page can be performed. | |
show.takeout | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a take out on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.can.takeout | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a take out on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.takeoutrecue | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a take out and recue on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.clear | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Performs a clear on a certain channel, if ChannelIndex is not included, the action is executed on all Channels. | |
show.can.clear | ChannelIndex<int> | POST | ChannelIndex<int>, ChannelName<string>, Status<string>, Message<string> | Checks if a clear to the active template or page can be performed. | |
show.gettemplates | none | GET | TemplateData <string JSON> | Retrieves the available templates of the active show | |
show.getpages | none | GET | TemplateData <string JSON> | Retrieves the available pages of the active show | |
show.createpage | Name<string>*: User defined name of the page. Level<string>*: Uri of the Template from where the page will be saved. Description<string>: User defined description. Keywords<string>: Comma separated keywords. Category<string>: User defined category. ChannelIds<int>: Comma separated list of Channel Ids | GET | none | Create a Page from the given TemplateData | |
show.getchannels | none | GET | ChannelIndex<int>, Name<string> | Retrieves the available channels of the active show. | |
show.getprojectdata | none | GET | Result <Dictionary<string, object> | Retrieves the data model of Project Data | |
show.setprojectdata | Detailed Parameter Description | POST | none | Sets the corresponding Project Data item. | |
show.preloadtemplates | none | POST | none | Preloads all [Templates Templates] on all Channels. | |
show.preloadtemplates_playlist | none | POST | none | Preloads all [Templates Templates] of all Playlists. | |
show.preloadtemplates_timeline | none | POST | none | Preloads all [Templates Templates] on all Timelines. | |
show.reloadtemplates | TimeOut<long>: Milliseconds to wait for Ventuz Presenter to load and validate the scenes. Response will contain a warning if exceeded. | POST | none | Reloads all [Templates Templates] on all Channels. | |
show.getassets | IncludeThumbnail<bool> | POST | none | If <true>, the response will also include the Base64 encoded string of the Thumbnail in PNG format. | |
Playlist | |||||
playlist.getmeta | ChannelIndex<int>* Index<int>: Zero-based numeric position of the item on the playlist. Id<int>: Globally unique identifier (GUID) of the item. Name<string>: Internal name of the item. DisplayName<string>: Displayed name of the item in the UI. One of the four identifying parameters above is required! | POST | Id<guid>, Name<string>, DisplayName<string>, ChannelIndex<int>, Index<int>, Status<Default, Cued,On-Air, Aired>, Description<string>, Category<string[]>, Keywords<string[]>, ChannelIds<int[]>, TemplateUri<string>, GroupName<string> | Returns information for a single playlist item. You can choose whether you request it through Index,Id,Name or DisplayName. | |
playlist.get | none | POST | ChannelIndex<int>, ChannelName<string>, Items<array of json objects>, Items contains: Name<string>,DisplayName<string>, ChannelIndex<int>, Index<int>, Id<guid>, Status<Default, Cued, On-Air, Aired> | Returns all Playlists of all Channels. | |
playlist.activate | ChannelIndex<int>* Index<int>: Zero-based numeric position of the item on the playlist. Id<int>: Globally unique identifier (GUID) of the item. Name<string>: Internal name of the item. DisplayName<string>: Displayed name of the item in the UI. One of the four identifying parameters above is required! | POST | none | Allows to activate an item on a specific Playlist, either by its Index, Id, Name or DisplayName. | |
playlist.restart | none | POST | none | Restarts all Playlists and cueing the first item. Timeline must be deactivated. | |
Remote Playlist | |||||
remoteplaylist.get | none | GET | Id<string>, Name<string>, PublishContexts<array of json objects> | Retrieves the ids of the available remote playlists with the name and id of each publish context. | |
remoteplaylist.open | PlaylistId<string>* PublishContextName<string> PublishContextId<guid> SpecialAction<UseBlankShow,UseShowUri,UseDefaultShow,UseCurrentShow>: details | POST | none | Opens a remote playlist i.e coming through MOS | |
Macros | |||||
macro.get | none | GET | Id<string>, Name<string> | Retrieves the available Macros within an active Show | |
macro.execute | Id<string> Name<string> One of the two is required! | POST | none | Activates a Macros based on its Id or Name. | |
macro.can.execute | Id<string> Name<string> One of the two is required! | POST | none | Checks whether the requested Macro can be executed or not.. | |
Timeline | |||||
timeline.play | none | POST | none | Plays the Timeline. | |
timeline.pause | none | POST | none | Pauses the playback of the Timeline. | |
timeline.rewind | none | POST | none | Rewinds the Timeline. | |
timeline.forward | none | POST | none | Forwards the Timeline. | |
timeline.jumpstart | none | POST | none | The Timeline jumps to the beginning. | |
timeline.jumpend | none | POST | none | The Timeline jumps to the end. |
The following commands are processed in parallel while the others are executed one after the other. The reason for this is that the commands mentioned here are commands that refer to Channels.
The response of these operations varies a little from the others.
The parameters depend of the requested data path type:
Data Item | Parameter | Description | Mandatory / Optional |
---|---|---|---|
Event | |||
DataPath | Path where the event should be invoked | Mandatory | |
Boolean | |||
DataPath | Path where the value should be set | Mandatory | |
SpecialAction | Toggle: Sets a boolean to true if it is currently false and vice versa. It should be written in this way: SpecialAction: Toggle | Optional | |
ValueToSet | true or false | Optional (only needed if Toggle is not requested, if both are requested then Toggle has priority) | |
String | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | The desired value which will set the text in the data channel | Mandatory | |
Enum | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | The desired enumeration value | Mandatory | |
Asset | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | The uri of the desired Asset | Mandatory | |
Arrays | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | Parsable string representation of the array | Mandatory | |
Color | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | Color in the format of r,g,b or a,r,g,b if Alpha is required | Mandatory | |
Single,Double,Integer | |||
DataPath | Path where the value should be set | Mandatory | |
ValueToSet | The required number | Mandatory | |
SetRelative | If true, the given number will be added to the current value of the data channel. (Default value is "false") | Optional |
SpecialAction | Description | Additional required parameters |
---|---|---|
UseBlankShow | A completely new show will be used. | None |
UseShowUri | The user should provide the show (via the show uri or path). | ShowUri |
UseDefaultShow | The show provided by the "Default Show Mappings" will be used. | None |
UseCurrentShow | The currently open show will be used. | None |
The response is returned in JSON format, indicating with a Status whether the execution succeeded, succeeded with warnings or failed and the corresponding Result as an Array.
The Websocket response also includes the related RequestID
Sample Response from a topology.get Websocket message
{ "RequestID" :"30", "Status": "Succeeded", "Result": [ { "Name": "(local)", "SourceType": "DefaultTopology" }, { "Name": "3ChannelsTopology", "SourceType": "LocalFile" }, { "Name": "NewTopologyFromScratch", "SourceType": "LocalFile" } ] }
RequestID
The RequestId given by the user (only applies in Websocket connections).
Code
Response-Codes which indicates the status of the recently executed request.
Code | Value(int) | Description |
Ok | 0 | The request was executed successfully. |
ErrorException | 1 | The execution failed due to an unexpected error. |
ErrorValidation | 2 | The execution failed due to an invalid value given or caused by the request. |
ErrorNotFound | 3 | The execution failed because a value given or caused by the request was not found. |
ErrorNoShow | 4 | Most of the commands can only be executed with an open Show. If there is no Show open at the time of execution, this error will be given. |
ErrorInvalidOperation | 5 | The execution failed because an invalid operation was attempted for example a Channel Rule is forbidding an item to be cued. |
Result
Property that contains the concrete result of each request. Usually in POST requests that are not related to channel-based commands the result is null.
When performing channel-based commands this property returns a list of ChannelStatus indicating the status of the operation for each channel.
Warnings
List of Issue that represent warnings in the executed request, when performing channel-based commands, the ResultIndex indicates the index of the item in the Result array, otherwise, ResultIndex it will be -1.
Errors
List of Issue that represent the reason why the executed request threw an error, when performing channel-based commands, the ResultIndex indicates the index of the item in the Result array, otherwise, ResultIndex it will be -1.
Here are some Websocket request message examples.
Get all available Topologies:
Command
{ "Command":"topology.get", "RequestID": 30 }
Response
{ "Code": 0, "Result": [ { "Name": "(local)", "SourceType": "DefaultTopology" }, { "Name": "3ChannelsTopology", "SourceType": "LocalFile" }, { "Name": "NewTopologyFromScratch", "SourceType": "LocalFile" }, { "Name": "Topology2", "SourceType": "LocalFile" }, { "Name": "CI_Presentation", "SourceType": "EmbeddedInProject" } ], "Warnings": [], "Errors": [] }
Activate a Topology:
{ "Command":"topology.set", "RequestID": 31, "Name": "3ChannelsTopology" }
Open a Director Show:
{ "Command":"show.open", "RequestID": 32, "Uri": "C:\\Users\\Public\\Documents\\Ventuz6\\Content\\Projects\\Hockey\\Hockey.show" }
Get channels of a Show:
Command
{ "Command":"show.getchannels", "RequestID": 33 }
Response
{ "Code": 0, "Result": [ { "ChannelIndex": 0, "Name": "Background" }, { "ChannelIndex": 1, "Name": "Content" } ], "Warnings": [], "Errors": [] }
When any of the Channel based commands are executed, the response can be as follows (all examples will be based on the show.cue command):
All channels performed the command successfully:
{ "Code": 0, "Result": [ { "ChannelIndex": 0, "ChannelName": "Background", "Code": 0, "TakeIndex": 0, "TakeCount": 1 }, { "ChannelIndex": 1, "ChannelName": "Content", "Code": 0, "TakeIndex": 0, "TakeCount": 1 } ], "Warnings": [], "Errors": [] }
Some Channels performed the command with Warnings:
{ "Code": 0, "Result": [ { "ChannelIndex": 0, "ChannelName": "Background", "Code": 0, "TakeIndex": 0, "TakeCount": 1 }, { "ChannelIndex": 1, "ChannelName": "Content", "Code": 0, "TakeIndex": 0, "TakeCount": 1 } ], "Warnings": [ { "ResultIndex": 0, "Message": "Item is still cueing" } ], "Errors": [] }
In this case the item on the ChannelIndex 0 is still cueing, the item on ChannelIndex 1 was successfully cued.
Some Channels performed the command with Errors:
{ "Code": 0, "Result": [ { "ChannelIndex": 0, "ChannelName": "Background", "Code": 0, "TakeIndex": 0, "TakeCount": 1 }, { "ChannelIndex": 1, "ChannelName": "Content", "Code": 5, "TakeIndex": 0, "TakeCount": 1 } ], "Warnings": [], "Errors": [ { "ResultIndex": 1, "Message": "Unable to perform desired action due to a blocking channel rule." } ]
In this case the item on the ChannelIndex 0 was successfully cued, but the item on ChannelIndex 1 was not cued due to a Channel Rule.
Note that the main Code is Ok because the command performed in at least one Channel.
All channels executed the command with Errors:
{ "Code": 1, "Result": [ { "ChannelIndex": 0, "ChannelName": "Background", "Code": 1, "TakeIndex": 0, "TakeCount": 1 }, { "ChannelIndex": 1, "ChannelName": "Content", "Code": 5, "TakeIndex": 0, "TakeCount": 1 } ], "Warnings": [], "Errors": [ { "ResultIndex": 0, "Message": "Unexpected error when performing show.cue, please refer to Director Log for details" }, { "ResultIndex": 1, "Message": "Unable to perform desired action due to a blocking channel rule." } ] }
In this case, main Code is ErrorException.
When a command is executed that is not part of the Channel based commands the response would be as follows:
Ok:
{ "Code": 0, "Result": null, "Warnings": [], "Errors": [] }
The command was successfully executed, there are no warnings or errors.
Ok with warnings:
{ "Code": 0, "Result": null, "Warnings": [ { "ResultIndex": -1, "Message": "Time out while connecting to all Ventuz Runtime instances" } ], "Errors": [] }
The command was successfully executed, but there were Warnings on the execution which could cause unexpected behaviors in future interactions with Director.
Error:
{ "Code": 4, "Result": null, "Warnings": [], "Errors": [ { "ResultIndex": -1, "Message": "No show open" } ] }
The command attempted to execute with no success because there is no active Show.In this case Errors are included.
Ok:
Based on the status.get command.
{ "Code": 0, "Result": { "Version": "6.9.0.0", "LifetimeMs": 44066, "User": "UserName", "Machine": "MachineName", "TopologyName": "CI_Presentation", "TopologyState": "Warning", "ShowId": "589c4ac0-8818-480b-8c02-b43a64f4603b", "ShowName": "CIPresentation", "ShowUri": "ventuz:///CIPresentation.show", "ProjectId": "48b1df08-9547-409e-8bd7-59be4f765349", "ProjectName": "CIPresentation", "ProjectUri": "file:///C:/Users/Public/Documents/Ventuz6/Content/Projects/CIPresentation/CIPresentation.vzp", "RemotePlaylistId": null, "ChannelCount": 2 }, "Warnings": [], "Errors": [] }
Based on the topology.get command.
{ "Code": 0, "Result": [ { "Name": "(local)", "SourceType": "DefaultTopology" }, { "Name": "3ChannelsTopology", "SourceType": "LocalFile" }, { "Name": "NewTopologyFromScratch", "SourceType": "LocalFile" }, { "Name": "Topology2", "SourceType": "LocalFile" }, { "Name": "CI_Presentation", "SourceType": "EmbeddedInProject" } ], "Warnings": [], "Errors": [] }