models.proto
syntax = "proto3";
option csharp_namespace = "TSS.Gateway.Sdk.Models";
// The story data structures as the player runs them, returned by the story.data query and, for
// the active scene, by scene.status. Positions and sizes are in pixels on the screen's canvas,
// origin at the bottom-left, y up. Volumes are normalized: 0 to 1.
message Story {
string uuid = 1;
string title = 2;
int32 version = 3;
string activeSceneUuid = 4;
float volume = 5; // Master volume, 0 to 1.
optional Screensaver screensaver = 6;
repeated Scene scenes = 7;
repeated Asset assets = 8;
repeated Trigger triggers = 9;
string integrationId = 10;
repeated Group groups = 11;
bool returnToLastSceneAfterScreensaver = 12; // True resumes at the scene that was active when the screensaver started; false restarts at the first scene.
optional string backgroundColor = 13; // Hex color string, for example "#FF8800".
}
// A set of assets that stays visible across the scenes named in inScenes.
message Group {
string uuid = 1;
string name = 2;
int32 baseLayer = 3; // Layer the group renders from; member asset layers stack on top of it.
repeated string inScenes = 4;
repeated string assets = 5;
}
message Screensaver {
string uuid = 1; // Scene to switch to.
int32 delay = 2; // Milliseconds without interaction before the screensaver scene activates.
}
message Scene {
string uuid = 1;
string title = 2;
bool autoSwitch = 3; // True switches to the next scene automatically when the background video finishes.
repeated string assets = 4; // Uuids of the assets in this scene.
oneof transition {
EffectTransition effectTransition = 5;
CustomTransition customTransition = 6;
};
string integrationId = 7;
Thumbnails thumbnails = 8;
int32 sceneIndex = 9; // The screensaver scene is 0, the other scenes count from 1 in story order, skipping the screensaver. Without a screensaver the count still starts at 1.
}
// A transition rendered by story-authored assets instead of a built-in effect.
message CustomTransition {
int32 duration = 1; // Milliseconds.
repeated string assets = 2; // Uuids of the assets that make up the transition.
}
message EffectTransition {
EffectType effectType = 1;
int32 duration = 2; // Milliseconds.
EaseType easeType = 3;
float feather = 4;
bool playPerSegment = 5; // True runs the effect per horizontal screen segment instead of over the whole screen at once.
}
// Thumbnail image paths of a story, scene, or asset.
message Thumbnails {
string default = 1;
string large = 2;
}
message Asset {
string uuid = 1;
string title = 2;
int32 layer = 3; // Render order within the scene, higher renders on top.
float opacity = 4; // 0 (fully transparent) to 1 (opaque).
bool draggable = 6;
bool roundedCorners = 7;
bool visible = 8;
Rectangle rectangle = 9;
Margins margins = 10; // Applied crop, see AssetCropRequest in requests.proto.
oneof data {
UrlData urlData = 11;
VideoData videoData = 12;
TextData textData = 13;
SoundData soundData = 14;
PdfData pdfData = 15;
NdiData ndiData = 16;
ImageData imageData = 17;
}
string integrationId = 18;
bool hasOnClickActions = 19;
Thumbnails thumbnails = 20;
}
// Position and size in canvas pixels; x/y is the bottom-left corner.
message Rectangle {
float x = 1;
float y = 2;
float width = 3;
float height = 4;
}
// Crop margins in pixels, measured inward from the asset's original edges.
message Margins {
int32 left = 1;
int32 right = 2;
int32 top = 3;
int32 bottom = 4;
}
// A web page asset.
message UrlData {
bool urlNavigation = 1;
string url = 2;
float volume = 3;
optional bool back = 4;
optional bool forward = 5;
optional bool home = 6;
optional bool inputFocus = 7;
optional bool streamActive = 8;
repeated UrlRequest requests = 9; // Pending page interactions, see the url asset requests in requests.proto.
optional bool isMuted = 10;
optional int32 zoom = 11; // Page zoom percentage applied as a reflowing Chromium zoom factor, 25-500. Absent or 0 means 100 (no zoom).
}
message VideoData {
bool play = 1;
bool loop = 3;
bool split = 4; // True when the video is encoded as vertically stacked parts because the source is wider than 7680 pixels.
optional float volume = 5;
optional double progress = 6; // Playback position, 0 (start) to 1 (end).
optional int32 duration = 7; // Milliseconds.
optional string codec = 8;
repeated FileData files = 9;
optional bool isLoaded = 10;
optional bool isMuted = 11;
optional bool hideOnFinish = 12; // True hides the asset the moment playback finishes. Absent or false keeps the finished video on screen.
}
message TextData {
TextHorizontalAlignment horizontalAlignment = 1;
TextVerticalAlignment verticalAlignment = 2;
string color = 3; // Hex color string, for example "#FF8800".
string font = 4 [deprecated = true];
int32 size = 5; // Font size in px, rounded to a whole number; exactSize carries the fraction.
string text = 6;
bool bold = 7 [deprecated = true];
bool italic = 8 [deprecated = true];
bool underline = 9;
string fontFile = 10;
float lineHeight = 11;
repeated TextParagraph paragraphs = 12; // Styled text, one paragraph per line of the text. Empty: the whole text uses the base style above.
optional float exactSize = 13; // Font size in px including its fraction, for example in a scaled story. When set, it is the size to render with instead of size.
}
// One line of styled text. A paragraph without runs is an empty line in the base style; an empty line in another style
// has one run without text that carries that style.
message TextParagraph {
repeated TextRun runs = 1;
}
// A piece of text in one style. A run only sets the properties that differ from the base style of
// its TextData; a property that is not set inherits the base style.
message TextRun {
string text = 1; // Contains no line breaks; the paragraphs separate the lines. Empty: the run only sizes its line.
optional string fontFile = 2; // Same form as TextData.fontFile.
optional float size = 3; // Same unit as TextData.size.
optional string color = 4; // Hex color string, for example "#FF8800".
optional bool underline = 5;
}
message SoundData
{
bool play = 1;
bool loop = 2;
FileData file = 3;
optional int32 duration = 4; // Milliseconds.
optional float volume = 5;
optional double progress = 6; // Playback position, 0 (start) to 1 (end).
optional bool isMuted = 7;
}
message PdfData {
int32 page = 1; // Zero-based page index.
int32 pageCount = 2;
FileData file = 3;
}
// An NDI (network video) source shown as an asset.
message NdiData {
string sourceName = 1;
bool visibleOnConnection = 2;
float volume = 3;
optional bool connected = 4;
optional bool isMuted = 5;
}
message ImageData {
repeated FileData files = 1;
}
message FileData {
string uuid = 1;
int32 version = 2;
string name = 3;
optional string path = 4;
}
message UrlRequest{
oneof request{
NavigationType navigation = 1;
string key = 2;
UrlTouch touch = 3;
string url = 5; // Page to load, see the asset.change-url request in requests.proto.
}
optional bool internal = 4;
}
// A touch on a url asset's page. Coordinates are normalized to the page, 0 to 1, and clamped.
message UrlTouch{
UrlTouchType type = 1;
float x = 2;
float y = 3;
int32 touchId = 4; // Identifies the finger across start/move/end, for multi-touch gestures.
}
// A story-authored trigger; fire it with trigger.fire (requests.proto).
message Trigger {
string uuid = 1;
repeated Action actions = 2;
}
message Action {
string uuid = 1;
int32 screenId = 2;
ActionType type = 3;
}
enum UrlTouchType {
START = 0;
END = 1;
MOVE = 2;
}
enum NavigationType {
BACK = 0;
FORWARD = 1;
REFRESH = 2;
HOME = 3;
}
enum TextHorizontalAlignment {
LEFT = 0;
CENTER = 1;
RIGHT = 2;
}
enum TextVerticalAlignment {
TOP = 0;
MIDDLE = 1;
BOTTOM = 2;
}
enum ActionType {
SCENE_GOTO = 0;
ASSET_TOGGLE = 1;
ASSET_SHOW = 2;
ASSET_HIDE = 3;
SCENE_NEXT = 4;
SCENE_PREV = 5;
}
enum EffectType{
DEFAULT = 0;
FADE = 1;
DIRECT = 2;
PUSH_LEFT = 3;
PUSH_RIGHT = 4;
PUSH_UP = 5;
PUSH_DOWN = 6;
COVER_LEFT = 7;
COVER_RIGHT = 8;
COVER_UP = 9;
COVER_DOWN = 10;
UNCOVER_LEFT = 11;
UNCOVER_RIGHT = 12;
UNCOVER_UP = 13;
UNCOVER_DOWN = 14;
WIPE_LEFT = 15;
WIPE_RIGHT = 16;
WIPE_UP = 17;
WIPE_DOWN = 18;
CURTAIN_HORIZONTAL = 19;
CURTAIN_VERTICAL = 20;
FALL_OVER = 21;
CUBE = 22;
BATMAN = 23;
}
enum EaseType{
LINEAR = 0;
SMOOTH = 1;
BUTTERSMOOTH = 2;
EXTRA_BUTTERSMOOTH = 3;
QUAD_IN = 4;
QUAD_OUT = 5;
QUAD_IN_OUT = 6;
CUBIC_IN = 7;
CUBIC_OUT = 8;
CUBIC_IN_OUT = 9;
QUART_IN = 10;
QUART_OUT = 11;
QUART_IN_OUT = 12;
QUAD_CIRC_IN = 13;
QUAD_CIRC_OUT = 14;
QUAD_CIRC_IN_OUT = 15;
CUBIC_CIRC_IN = 16;
CUBIC_CIRC_OUT = 17;
CUBIC_CIRC_IN_OUT = 18;
QUART_CIRC_IN = 19;
QUART_CIRC_OUT = 20;
QUART_CIRC_IN_OUT = 21;
BOUNCE_IN = 22;
BOUNCE_OUT = 23;
BOUNCE_IN_OUT = 24;
ELASTIC_IN = 25;
ELASTIC_OUT = 26;
ELASTIC_IN_OUT = 27;
ASYNC_SMOOTH = 28;
}