Om du skapar ett anpassat lager finns det möjlighet att även inkludera förinställningar för anpassad kontroll med ditt lager. Detta är praktiskt om ditt lager har tryckknappar som styr beteendet hos ditt lager när det är live.
Datastruktur
Följande datastruktur är ett exempel på utdata som måste finnas i din sammansättning under strukturutdatanyckeln `tvOut_ControlRepresentations`:
{
"tvOut_ControlRepresentations": [
{
"title": "Compact Cut's",
"buttons": [
{
"actions": [
{
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"type": "signal",
"signalKey": "tvGroup_Control__Cut_1_TypeSignal",
"signalName": "Cut 1"
}
],
"liveState": {
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"dynamicSourceId": "tvIn_VideoSourceAImage"
},
"sourcePreview": {
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"dynamicSourceId": "tvIn_VideoSourceAImage"
},
"color": "#BBBBBB",
"width": 1,
"height": 1,
"x": 0,
"y": 0,
"icon": "facetime-video",
"dynamicText": {
"template": "{{inputputValues.tvIn_VideoSourceAName}}",
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69"
}
}
]
}
]
}
En förinställning har en "titel" och en uppsättning "knappar", men en enda knapp är också ok.
Nycklarna `layerId` och `variantId` måste fyllas i dynamiskt med strängdata från sammansättningens inmatningsnycklar `tvIn_LayerIdentifier` och `tvIn_RuntimeIdentifier`.
Använda fjärrkontrollen Förinställning API i Quartz Kompositör
De inbyggda lagren i mimoLive använder en LUA skript för att dynamiskt generera denna datastruktur eftersom Quartz Composer inte stöder generering av datastrukturer på egen hand. Den LUA innehåller en komplex funktion addButton() som kan användas för att skapa strukturen för en enda knapp. Vanligtvis kan du bara använda den här funktionen och behöver inte modifiera den. Därför är det ganska enkelt att bygga nya standardinställningar för fjärrkontrollen för ditt eget lager.
Detta är till exempel LUA skript för att generera fjärrkontrollerna för Stop Watch-lagret. Observera att du kan anpassa denna kod genom att bara ändra raderna 15 till 29 i koden.
inLayerIdentifier = QC_STRING
inVariantIdentifier = QC_STRING
outControlRepresentations = QC_STRUCT
main = function()
controlRepresentations = {}
-- first representation
controlRepresenation = {}
-- {
controlRepresenation["Title"] = "Stop Watch"
buttons = {}
-- {
-- addButton(buttonsTable, buttonTitle, subTitle, positionX, positionY, width, height, color, icon, actionTarget, liveStateSource, previewSource)
-- first row
addButton(buttons, "{{outputValues.tvOut_TimeString}}", "", 0, 0, 2, 1, "#333333", "", "", "", "")
addButton(buttons, "Live", "{\{name\}}", 2, 0, 1, 1, "#333333", "", "toggleLive", "layerVariant", "")
-- second row
addButton(buttons, "Start", "", 0, 1, 1, 1, "#33cc33", "play", "tvGroup_Control__Start_TypeSignal", "", "")
addButton(buttons, "Stop", "", 1, 1, 1, 1, "#cc3333", "pause", "tvGroup_Control__Stop_TypeSignal", "", "")
addButton(buttons, "Reset", "", 2, 1, 1, 1, "#cccc33", "stop", "tvGroup_Control__Reset_TypeSignal", "", "")
-- }
controlRepresenation["buttons"] = buttons
-- }
table.insert(controlRepresentations , controlRepresenation)
outControlRepresentations = controlRepresentations
end
function addButton(buttonsTable, buttonTitle, buttonSubTitle, positionX, positionY, width, height, color, icon, actionTarget, liveStateSource, previewSource)
local button = {}
-- {
if #buttonTitle > 0 then
if string.find(buttonTitle, "{{") then
-- dynamic titel
local dynamicText = {}
-- {
dynamicText["layerId"] = inLayerIdentifier
dynamicText["variantId"] = inVariantIdentifier
dynamicText["template"] = buttonTitle
-- }
button["dynamicText"] = dynamicText
else
-- static title
button["text"] = buttonTitle
end -- if dynamic
end -- if buttonTitle
if #buttonSubTitle > 0 then
if string.find(buttonSubTitle, "{{") then
-- dynamic titel
local dynamicSubText = {}
-- {
dynamicSubText["layerId"] = inLayerIdentifier
dynamicSubText["variantId"] = inVariantIdentifier
dynamicSubText["template"] = buttonSubTitle
-- }
button["dynamicSubText"] = dynamicSubText
else
-- static title
button["subtext"] = buttonSubTitle
end -- if dynamic
end -- if buttonSubTitle
button["x"] = positionX
button["y"] = positionY
button["width"] = width
button["height"] = height
if #color > 0 then
button["color"] = color
end -- if
if #actionTarget > 0 then
local actions = {}
-- {
local action = {}
-- {
action["layerId"] = inLayerIdentifier
action["variantId"] = inVariantIdentifier
if string.ends(actionTarget, "_TypeSignal") then
action["type"] = "signal"
action["signalKey"] = actionTarget
action["signalName"] = buttonTitle
elseif actionTarget == "toggleLive" then
action["type"] = "toggleLive"
else
action["type"] = "toggleSwitch"
action["toggleSwitchKey"] = actionTarget
action["toggleSwitchName"] = buttonTitle
end -- if
-- }
table.insert(actions , action)
-- }
button["actions"] = actions
end -- if actionTarget
if #liveStateSource > 0 then
local liveState = {}
-- {
liveState["layerId"] = inLayerIdentifier
liveState["variantId"] = inVariantIdentifier
if string.starts(liveStateSource,"tvIn_VideoSource") then
-- get the live state from a dynamic video source
liveState["dynamicSourceId"] = liveStateSource
elseif liveStateSource == "layerVariant" then
-- nor more information needed
else
liveState["propertyPath"] = liveStateSource end -- if
-- }
button["liveState"] = liveState
end -- if liveState Source
if #previewSource > 0 then
local sourcePreview = {}
-- {
sourcePreview["layerId"] = inLayerIdentifier
sourcePreview["variantId"] = inVariantIdentifier
sourcePreview["dynamicSourceId"] = previewSource
-- }
button["sourcePreview"] = sourcePreview
end -- if
if #icon > 0 then
-- See bottom of documentation page for list of avaiable icon names
button["icon"] = icon
end -- if
-- }
table.insert(buttonsTable, button)
end -- func
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
function string.ends(String,End)
return End=='' or string.sub(String,-string.len(End))==End
end
Button Positionering
När du använder flera knappar måste knapplayouten styras manuellt. Det innebär att knapparna positioneras på rutnätet med hjälp av attributen "x" och "y", som precis som attributen "bredd" och "höjd" anges i multiplar av rutnätsceller. Positionerna är relativa till den övre vänstra rutnätscellen som knappgruppen drogs till.
Button Åtgärder
Buttoner kan ha flera åtgärder, en enda åtgärd eller ingen alls. Det finns olika giltiga kombinationer av åtgärdsmål och åtgärdstyper.
Observera att åtgärderna "textInput" och "numericInput" bör vara fristående, eftersom en konsekvent användarupplevelse i fjärrkontrollen inte kan garanteras.
Mål för åtgärder
Åtgärdsmål är element inuti mimoLive-dokumentet. De adresseras på ett hierarkiskt sätt:
"Dokument-ID" ritas alltid vid körning, så det behöver inte finnas med i förinställningen.
- Om varken "layerId" eller "variantId" anges kommer åtgärden att utlösas på själva dokumentet.
- Om "layerId" anges kommer åtgärden att utlösas på det angivna lagret.
- Om "layerId" och "variantId" anges kommer åtgärden att utlösas på den angivna varianten. Endast i detta fall kan tillägget "toggleSwitchKey" eller "signalKey" anges (se Åtgärdstyper nedan).
Typer av åtgärder
Typ av åtgärd | Förklaring | Ytterligare attribut | Giltiga mål |
---|---|---|---|
växlaLive | Växla levande tillstånd | ingen | Dokument (Start/Stop show), Lager, Variant |
inställd på liv | Ställ in live-status till "live" | ingen | Dokument (Start Show), Lager, Variant |
setOff | Sätt live-status till "av" | ingen | Dokument (Stop Show), Lager, Variant |
signal | Utlösa en signal | signalKey, signalName (rekommenderas) | Variant |
ToggleSwitch | Växla ett booleskt ingångsvärde | toggleSwitchKey, toggleSwitchName (rekommenderas) | Variant |
textInput | Öppnar ett textinmatningsfält som, när det skickas, uppdaterar värdet i inputKey. | inputKey, inputName (rekommenderas) | Lager, Variant, Källa |
numeriskIngång | Slider som styr ett numeriskt värde på inputKey. | inputKey, inputDescription (objekt med både min- och maxvärden), inputName (rekommenderas) | Lager, Variant, Källa |
Handlingstyperna "textInput" och "numericInput" är tillgängliga sedan mimoLive 5.2.
Button Live State
Objektet "liveState" kan användas för att konfigurera knappens tally-ljusstatus, som kan vara på (röd markering), övergång (gul markering) eller av (ingen markering).
Levande statliga källor
I likhet med mål för knappåtgärder kan live-status erhållas från flera källor:
- "Dokument-ID" ritas alltid vid körning, så det behöver inte finnas med i förinställningen.
- Om varken "layerId" eller "variantId" anges, används dokumentets live-status (showen har startat eller inte).
- Om "layerId" anges används lagrets live-status.
- Om "layerId" och "variantId" anges används variantens live-status.
- Endast i detta fall kan tillägget "propertyPath" anges för att indikera att en boolesk egenskap på variantens in- eller utgångsvärden måste användas.
- En annan möjlighet (ömsesidigt uteslutande med propertyPath!) är att ange en egenskap "dynamicSourceId" som omdirigerar live state-uppslagningen till en källa (hämtad med ID), som respekterar dynamiska förändringar av den valda källan (t.ex. i video switcher). Värdet för "dynamicSourceId" söks upp i variantens ingångsvärden.
Ange den fullständiga sökvägen till egenskapen, med utgångspunkt från varianten som rot, t.ex. "inputValues.some_Boolean_Property" eller "outputValues.other_Property".
- Om "sourceId" anges används källans live-status.
Button Text
Aktionsknappar kan visa primära och sekundära textrader, båda kan vara av statisk eller dynamisk natur.
Primär text
Denna text kommer att vara den primära indikatorn på vad knappen kommer att göra för användaren. Om knappförinställningen innehåller en text-egenskap är det en statisk text som kommer att visas som den är.
Alternativt kan en dynamicText anges som möjliggör inkludering av mimoLive-skikt eller variantegenskaper med hjälp av en enkel mallsyntax. I mallsträngen kan vanliga tecken kombineras med egenskapssökvägar som omsluts av hakparenteser:
"template": "{\{propertyPath\}}"
Egenskapssökvägar utvärderas i förhållande till det objekt som är upplöst med hjälp av "layerId", "variantId", "sourceId" och "filterId". Målupplösning följer dessa regler:
- "Dokument-ID" ritas alltid vid körning, så det behöver inte finnas med i förinställningen.
- Om varken "layerId" eller "variantId" anges, utvärderas egenskapssökvägarna relativt till dokumentet
- Om "layerId" (och eventuellt "variantId") anges, utvärderas egenskapssökvägarna i förhållande till ett lager/variant.
- En variants överordnade lager kan nås genom att starta en sökväg med "lager", t.ex. "aslayer.name".
Det första sökvägssegmentet för ingångs- och utgångsvärden måste vara camelCased ("inputValues.tvIn...") och inte kebab-cased ("input-values.tvIn...") som i API-dokumenten.
- Statisk text har alltid företräde framför dynamisk text, eftersom detta gör det möjligt för användare att skriva över den dynamiska texten med någon anpassad text som kan vara mer användbar i deras situation.
Sekundär text
För att ge användaren mer information om en knapp, t.ex. namnet på det överordnade lagret, kan en sekundär text anges med hjälp av egenskaperna "subtext" eller "dynamicSubText".
Templating-syntax och objektupplösning följer exakt samma regler som primärtexten.
Button text och ikonstorlek
Texten och ikonerna på knapparna kan variera i storlek beroende på sammanhanget. Med alternativet "fontScale" kan du ange en relativ skala till en standardstorlek som beräknas för den aktuella skärmstorleken. "1" kommer att vara standardstorleken. Mindre än 1 (t.ex. 0,8) kommer att minska teckenstorleken och större än 1 (t.ex. 1,5) kommer att öka den.
Button Förhandsgranskning
Åtgärdsknappar kan visa en förhandsgranskningsbild av den källa de styr, eller någon annan källa som finns tillgänglig i dokumentet.
Beroende på om källan är statisk (endast bilder som drogs in i mimoLive), en statisk PNG representation av källan laddas en gång som stöder en alfakanal. För alla andra källor laddas en JPEG representationen av källan uppdateras regelbundet. Målet för uppdateringshastigheten för dynamiska källor är 5 bilder per sekund, men denna hastighet minskas om nätanslutningshastigheten visar sig vara otillräcklig för upprepad laddning av förhandsgranskningsbilder.
Det finns för närvarande inget stöd för att visa dokumentets programutdata på en åtgärdsknapp. Standardbilder för lager, även om de inte syns i listan över källor, är tillgängliga för förhandsgranskning.
För att specificera en källförhandsgranskning används en objektupplösningsmekanism:
- "Dokument-ID" ritas alltid vid körning, så det behöver inte finnas med i förinställningen.
- Om "sourceId" anges används källan med det ID:t för förhandsgranskning.
- Om alla "layerId", "variantId" och "dynamicSourceId" anges, kommer källans ID att sökas upp i det angivna lagrets variant under nyckeln i "dynamicSourceId". Detta kan användas för att referera till källor som videoomkopplarens källa A-G, även när de ändras i dokumentet.
Button Färg
Genom att använda attributet "color" kan knappar färgläggas med valfri färgkod som kan representeras i HTML (t.ex. "#f80", "#ff0088", "orange" eller "rgb(255, 66, 88)").
Button Ikon
Buttoner kan visa en ikon för att indikera deras funktionalitet. För att se en lista över alla tillgängliga ikoner, öppna http://localhost:8989/icons/demo.html medan mimoLive körs och fjärrkontroller är aktiverade.
Använd det vanliga namnet på ikonen, t.ex. "bakåt" eller "pil ned".