FAB Subtitler Server supports many additional functions. This page describes the function “Playout interface”.
In short: the playout interface connects to a video playout system, receives the IDs of the items in its playlist that are cued, playing or stopped, and publishes them over MQTT, with the timecode when a timecode type is configured. FAB Subtitler subscribes to these topics to get the subtitles of an ID in advance and to start and stop them in sync with the playout. The function is available also in the free version of FAB Subtitler Server.

- MQTT topic:
.../cue
Published when: An ID is cued or prepared. Published at once, without a delay. - MQTT topic:
.../state
Published when: The playing ID changes, or the playing ID is cleared. With DelayMSStart or DelayMSStop it is published after that delay, see Delays. - MQTT topic:
.../command
Published when: Any command or telegram is received. Published at once.
The following protocols are supported:
Harris4Chreceives the IDs of up to 4 heads (channels) from the playout system. The ID of every head is reported on its own MQTT topic.HarrisCmdreceives text commands (preroll,playandstop) over a network connection, for one channel.FABAutomationreceives the commands of the FAB Automation Protocol (QUERYFILE,STARTFILE,STOPFILE,SETTC…) over a network connection, for one channel. The playout system gets the replyOKto every command. It can also send the timecode.
The cue messages are sent for the CUE telegram of Harris4Ch, the preroll command of HarrisCmd and the QUERYFILE command of FAB Automation.
The messages are published to the primary and the secondary MQTT server which are configured in
FAB Subtitler Server Configuration (button “Configure connection to MQTT server”).
Configuration
- Open FAB Subtitler Server Configuration and click on the page “Additional Functions”.
- Add the function “Playout interface” and fill in the fields below.
- Add one entry for every playout interface that is required.
The fields of an entry are:
- Field: Enabled
Meaning:Yto start this playout interface (the default for a new entry),Nto ignore this entry. - Field: Description
Meaning: Free text which identifies the entry in the list of additional functions. - Field: Protocol
Meaning: The protocol that will be used:Harris4Ch,HarrisCmdorFABAutomation. - Field: ProtocolSource
Meaning: Defines the connection to the video playout system, see below. ForHarrisCmdit also defines the end of a command and the frame rate, forFABAutomationthe frame rate. - Field: MQTTTopic
Meaning: The start of the MQTT topic names. Required. ForHarris4Chthe number of the head (1 to 4) is added to it, forHarrisCmdit is used as it is, unless ChannelInfo defines a suffix, see below. - Field: ChannelInfo
Meaning: The name of the channel (the TV channel) of every head and, optionally, the end of its MQTT topic:name,suffix;name,suffix;.... The names are displayed in the web interface. Optional, see below. - Field: Timecode
Meaning: The type of timecode that is reported with the IDs. UseNone(the default) if no timecode is required. The timecode is then reported as 0 (Harris4Ch) or taken from the preroll command (HarrisCmd).Decklinkreads the timecode from a Decklink card,ZeroBasedreports 00:00:00:00 with every ID,TimeOfDayreports the local time of the computer andTimeOfDayUTCthe UTC time,Protocoltakes the timecode from the commands of the playout system (FABAutomation), see below. - Field: TimecodeSource
Meaning: ForDecklinkit defines the timecode inputs. ForZeroBased,TimeOfDayandTimeOfDayUTCit is the frame rate of the timecode. See below. - Field: DelayMSStart
Meaning: Milliseconds that the state message is delayed when a new ID starts (the ID is not empty). Default 0 (no delay). See Delays below. - Field: DelayMSStop
Meaning: Milliseconds that the state message is delayed when the ID is cleared (the ID is empty). Default 0 (no delay). See Delays below. - Field: DelayTC
Meaning:N(the default): a delayed state contains the timecode of the moment the telegram or command was received.Y: it contains the timecode of the moment the state is sent.
ProtocolSource
The following forms of the connection to the video playout system are supported:
-
Address form:
tcp://@adapterip:port
Meaning: Listen for a TCP connection of the playout system on this port. Usetcp://@0.0.0.0:6001to listen on all network adapters, this always works (also for a connection from the same computer to127.0.0.1). With the IP address of a network adapter, for exampletcp://@192.168.192.99:6001, only connections to that IP address are accepted. -
Address form:
tcp://serverip:port
Meaning: Connect to a TCP port of the playout system, for exampletcp://192.168.192.99:8355. -
Address form:
udp://adapterip:receive@address:port
Meaning: Receive UDP data on this port of the network adapter with the IP addressadapterip. The wordreceiveis required.addressis the IP address of the multicast group to join (224.0.0.0to239.255.255.255), for exampleudp://192.168.211.99:[email protected]:8355. For unicast dataaddressis not used, but it must be a valid IPv4 address, for exampleudp://192.168.211.99:[email protected]:8355. -
Address form:
comN:baud,databits,parity,stopbits,flowcontrol
Meaning: Receive the data over a serial port (COM port), for examplecom1:38400,8,n,1. See Serial port below.
The port must be between 1 and 65535 and the IP addresses must be IPv4 addresses. If the address is not written correctly or the connection cannot be made, the interface is not started, an error is written to the log file and the connection is retried every minute.
Serial port
All protocols can also receive their data over a serial port. Write the serial port instead of the URL:
comN:baud,databits,parity,stopbits,flowcontrol
Only the number of the port is required, every other part is optional and has a default:
- Part: comN
Meaning: The serial port,com1tocom254. - Part: baud
Meaning: The baud rate: 110, 300, 600, 1200, 2400, 4800, 9600 (the default), 14400, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 230400, 256000, 460800 or 921600. - Part: databits
Meaning: The number of data bits, 5 to 8. The default is 8. - Part: parity
Meaning:Nnone (the default),Oodd,Eeven,Mmark orSspace. - Part: stopbits
Meaning: The number of stop bits, 1 (the default) or 2. - Part: flowcontrol
Meaning:rts(the default),none,rtscts,dtrdsrorxonxoff.
The first : can also be written as ,. An empty part has its default. Examples:
com1:38400,8,n,1COM1, 38400 baud, 8 data bits, no parity, 1 stop bit.com3:9600,7,e,2,xonxoffCOM3, 9600 baud, 7 data bits, even parity, 2 stop bits, software flow control.com2:19200COM2, 19200 baud, 8 data bits, no parity, 1 stop bit.
For HarrisCmd and FABAutomation the serial port is written in the place of the URL, for example com1:38400,8,n,1;CRLF;25,UTF8 and com1:38400,8,n,1;25.
If the serial port cannot be opened (for example because it does not exist or is used by another program), the interface is not started, an error is written to the log file and it is tried again every minute.
The replies of FABAutomation are sent over the serial port.
For the protocol Harris4Ch ProtocolSource is only the URL. For the protocol HarrisCmd it has three parts
separated by ;, the encoding follows the frame rate after a ,:
url;end of command;frame rate,encoding
- Part: url
Meaning: The connection, as in the table above. - Part: end of command
Meaning: The text that ends every command.CR(#13),LF(#10),CRLF(#13#10) andLFCR(#10#13) are special words (written in capital or small letters) for these characters. Any other text is used as it is, for example#or##. - Part: frame rate
Meaning: The frame rate of the timecodes in the commands:25,24,23.98,29.97df,29.97ndf,30ndf,30df,47.95,48,50,59.94df,59.94ndf,60ndfor60df. It can also be written without the decimal separator:2398is 23.98,2997is 29.97 and5994is 59.94. Adddforndfdirectly after the number for drop frame or non drop frame, for example2997df. Withoutdfa frame rate of 29.97, 30, 59.94 or 60 is non drop frame. Any other frame rate is an error: the interface is not started and the log file lists the supported frame rates. - Part: encoding
Meaning: The character encoding of the received commands, written after the frame rate and a,:ANSI(the standard character set of the Windows computer, the ANSI code page) orUTF8. It matters for characters with accents, for example in the title of a preroll command.
The ; that separate the parts are the first and the last ; of ProtocolSource, so the end of command can also be ;.
All parts are required. Example: udp://192.168.209.120:[email protected]:6005;CRLF;25,UTF8.
For the protocol FABAutomation ProtocolSource is the URL, optionally followed by ; and the frame rate of the timecodes in the
commands (one of the frame rates that are accepted for HarrisCmd, 25 if it is left out), for example tcp://@0.0.0.0:6001;25.
The reply to a command is sent over TCP or over the serial port. When the commands are received over UDP the playout system does not get a reply.
MQTTTopic
For the protocol Harris4Ch the number of the head is added to the end of MQTTTopic. For MQTTTopic fab/playout/head the
following topics are used:
- Topic:
fab/playout/head1/state…fab/playout/head4/state
Contents: The state of the head: the current ID and timecode. The messages are published as retained messages (the MQTT server keeps the last message and gives it to every client that connects later). - Topic:
fab/playout/head1/command…fab/playout/head4/command
Contents: The commands that were received for the head from the playout system. - Topic:
fab/playout/head1/cue…fab/playout/head4/cue
Contents: The ID of every cue or prepare command that was received for the head: the ID that will be played. It is published at once, without a delay. The messages are published as retained messages, like the state.
The protocols HarrisCmd and FABAutomation have only one channel, so the number is not added. For MQTTTopic fab/playout/channel the
topics are fab/playout/channel/state, fab/playout/channel/command and fab/playout/channel/cue.
If MQTTTopic is empty, or the protocol is unknown, or the ProtocolSource is empty or wrong, or no MQTT server is configured, an error is written to the log file and the playout interface is not started.
ChannelInfo
ChannelInfo gives every head a name that is displayed in the web interface (the column Channel of the table of the playout interface)
and, if wanted, its own end of the MQTT topic. It has one entry for every head, separated by ;: 4 entries for Harris4Ch, 1 entry for HarrisCmd.
Every entry is written as
name,suffix
- Part: name
Meaning: The descriptive name of the head, for example the name of the TV channel. - Part: suffix
Meaning: The end of the MQTT topic of the head. The topic of the head is MQTTTopic followed by the suffix, and then/state,/commandor/cue. The suffix is used exactly as it is written, no/is added.
Example:
MQTTTopic=rtve/accesibilidad/automatizacion/
ChannelInfo=La 1,madrid-ent51;La 2,madrid-ent52;24 horas,madrid-ent53;Teledeporte,madrid-ent54
This uses the topics rtve/accesibilidad/automatizacion/madrid-ent51/state, .../madrid-ent52/state and so on.
- An entry is split at its last comma, so a name can contain commas. A name that contains a
;must be written in double quotes. - An entry without a comma is only a name. The head then has no suffix: for
Harris4Chthe number of the head is added to MQTTTopic as described above, forHarrisCmdnothing is added. - If ChannelInfo is empty, the heads are named
Head 1toHead 4and the numbers are added to MQTTTopic. - If ChannelInfo contains empty data for one of the heads, then the head is not used and also timecode for that head is not read.
- If the number of entries is not the number of heads, or two heads would have the same MQTT topic, an error is written to the log file and the playout interface is not started.
TimecodeSource
For Timecode Decklink the timecode source is read from the SDI (or other) input of a Decklink card.
TimecodeSource is a list of inputs separated by ;. Every input is defined as follows:
card,head,input,type
- Part: card
Meaning: The number of the Decklink device, starting with 1. Every input of a Decklink card with several inputs (for example Duo 2) is a device of its own. - Part: head
Meaning: The number of the head (1 to 4) which uses this timecode input. - Part: input
Meaning: The input of the card:SDI,HDMI,OpticalSDI,Component,CompositeorSVideo. - Part: type
Meaning: The type of the timecode:ATCLTCorATCVITC.
Every Decklink device and every head can be used only once. A head which has no timecode input
reports the timecode 0. The protocol HarrisCmd has only the head 1, so only one input with head 1 can be defined.
Timecode ZeroBased, TimeOfDay and TimeOfDayUTC
These types need no timecode input and have no TCStart, TCJump and TCStop messages. The timecode is reported with every ID change, also when the ID is cleared:
- Timecode:
ZeroBased
The timecode that is reported: 00:00:00:00 on every new ID. - Timecode:
TimeOfDay
The timecode that is reported: The local time of the computer at the moment the telegram or command is processed, for example 14:05:31:12. - Timecode:
TimeOfDayUTC
The timecode that is reported: The UTC time at that moment.
TimecodeSource can contain the frame rate of the timecode, one of the frame rates that are accepted in the ProtocolSource of HarrisCmd (for example 25, 29.97 or 2997). If it is empty, 25 is used. A frame rate that is not one of them is written to the log file as an error and 25 is used. The timecode of these types is the same for every head, it is always known (TCJump is true), and for HarrisCmd it is used instead of the timecode of the preroll command.
Timecode Protocol
With Timecode Protocol the timecode comes from the commands of the playout system. This is possible for a protocol that has timecode in
its commands, at the moment this is FABAutomation; for Harris4Ch and HarrisCmd it is the same as None.
The frame rate of the timecodes is the one in ProtocolSource. The timecode of an ID is:
- Command:
STARTFILEorRESUMEFILEwith a timecode in DATA (TC:10:00:00:00or only10:00:00:00)
The timecode: The timecode in DATA. The clock of the protocol is set to it and runs from there. - Command:
SETTC
The timecode: Sets the clock of the protocol, see below. - Command: any other command
The timecode: The clock of the protocol.
The clock of the protocol is set by the timecode of a STARTFILE or RESUMEFILE command and by the SETTC command, and then runs in real time.
After 23:59:59 and the last frame it continues with 00:00:00:00. The web interface shows the running timecode.
The clock is kept over a restart of the service, see Restart of the service below.
SETTC can set an absolute timecode (DATA=10:00:00:00),
add (DATA=+00:00:05:00) or subtract (DATA=-00:00:05:00) an offset to the timecode that runs now, or set the time of day
(DATA=RT:RT:RT:RT, the local time of the computer). An offset is ignored while the clock is not set. Every SETTC also publishes a state
message with the Reason TCJump: the ID that was published last and the new timecode. As long as the clock is not set, and for commands without
a timecode, the timecode is not known (TCJump is false, the timecode is reported as 0). Without Timecode Protocol the timecodes of the
commands are not used and SETTC is ignored (it is only reported as command). The timecode of a timecode input (Decklink) is not combined with it.
If Timecode is None, no timecode is read and the timecode is reported as 0. This is not an error. An empty Timecode (as in entries that were created before None was introduced) has the same meaning.
If Timecode or TimecodeSource is wrong, an error is written to the log file and no timecode is read,
the IDs are still reported.
Delays
DelayMSStart and DelayMSStop work like the delay for PLAY and for STOP of the automation interface of FAB Subtitler. They delay the state message
(.../state, reason IDChange) that reports a change of the playing ID:
- DelayMSStart: the message is published this many milliseconds after the telegram or command was received when a new ID starts (the ID in the message is not empty).
- DelayMSStop: the same when the ID is cleared (the ID in the message is empty).
- A value of 0 (the default) or less means no delay.
What is not delayed:
- The command messages (
.../command) and the cue messages (.../cue) are published at once when the telegram or command is received. The cue message is published first, before the command message of the same telegram or command. - The messages TCStart, TCJump and TCStop are not delayed either. They contain the ID that was published last on that head (empty if none), not the ID that was just received. So FAB Subtitler does not start an ID before its delay has passed.
- The web interface shows an ID as soon as it is received, also while its state message is still waiting.
Order and a new ID that replaces waiting messages. The state messages of a head are published in the order in which they were received, with these two rules:
-
A stop does not overtake a start. A message with an empty ID is never published before the message that was received before it. For example, with DelayMSStart=2000 and DelayMSStop=500, a STOP that is received 100 ms after a PLAY is published directly after that PLAY, 2000 ms after the PLAY was received, and not after 600 ms. So a stop can be delayed longer than DelayMSStop, but the sequence ID, empty, ID, empty is never changed.
-
A new ID is never delayed longer than DelayMSStart. When a new ID (not empty) is received, it is published DelayMSStart after it was received, even when a message before it is still waiting for a longer delay. Every waiting message that would be published at the same time or later is not published at all: the new ID replaces it. For example, with DelayMSStart=0 and DelayMSStop=2500, a STOP is received and 1 second later the next PLAY. The next ID is published at once, and the STOP, which would have been published 1.5 seconds later, is never published, so the receiver sees the first ID, then the next one, without an empty ID in between. A message that is replaced is written to the log file (
Head 1: the state message for the ID "..." is not published, it is replaced by the ID "...", which is due at the same time or earlier). Time and timecode. Every message contains the UTC time of the moment it is published. DelayTC defines which timecode a delayed ID message contains: -
DelayTC:
N
The timecode of a delayed state: The timecode at the moment the telegram or command was received. FAB Subtitler then starts the item later by the delay. -
DelayTC:
Y
The timecode of a delayed state: The timecode at the moment the state is published: the timecode of reception plus the time the message waited (the delay, or longer when it had to wait for an earlier message). The delay then does not shift the timecode. A timecode that is not known stays 0.
Messages that wait. At most 100 messages per head wait, if there are more the oldest is published at once. Messages that are still waiting when the connection to the playout system is closed or the service stops are discarded, and a
warning is written to the log file. When a delay is configured, the log file contains the line The state messages are delayed by ... ms when an ID starts and by ... ms when the ID is cleared ... when the entry is started.
Example configuration
The following is an example of the configuration which can be used to receive data from a video playout system on UDP Port 6005 on the ethernet adapter with IP address 192.168.209.120 for the Harris4Ch protocol with 4 heads for 4 channels and also read timecode from a Decklink Duo 2 card with 4 SDI inputs, every input is assigned to a different Head ID.
All examples use ChannelInfo to give the channel a name, for example Channel 1. This name is displayed in the column Channel of the table
of the playout interface in the web interface. The names have no suffix, so the MQTT topics are not changed. Replace the names by the names of your channels.
Enabled=Y
Description=Playout channels 1-4
Protocol=Harris4Ch
ProtocolSource=udp://192.168.209.120:[email protected]:6005
MQTTTopic=fab/playout/head
ChannelInfo=Channel 1;Channel 2;Channel 3;Channel 4
Timecode=Decklink
TimecodeSource=1,1,SDI,ATCLTC;2,2,SDI,ATCLTC;3,3,SDI,ATCLTC;4,4,SDI,ATCLTC
The following is an example for the protocol HarrisCmd. The commands are received on UDP port 6005 of the
ethernet adapter with IP address 192.168.209.120, every command ends with CR LF and the timecodes in the
commands have the frame rate 25 and are sent as UTF8. The Timecode is None, so the timecode of the preroll command is used.
Enabled=Y
Description=Playout channel 1
Protocol=HarrisCmd
ProtocolSource=udp://192.168.209.120:[email protected]:6005;CRLF;25,UTF8
MQTTTopic=fab/playout/channel
ChannelInfo=Channel 1
Timecode=None
TimecodeSource=
The following is an example for the protocol FABAutomation. The service listens on TCP port 6001 of all network adapters,
the timecodes in the commands have the frame rate 25 and the timecode of the IDs is taken from the commands.
The playout system connects to the port, sends SETTC to set the timecode and QUERYFILE, STARTFILE and STOPFILE for the IDs.
Enabled=Y
Description=Playout channel 1
Protocol=FABAutomation
ProtocolSource=tcp://@0.0.0.0:6001;25
MQTTTopic=fab/playout/channel
ChannelInfo=Channel 1
Timecode=Protocol
TimecodeSource=
The following is an example for the protocol Harris4Ch where no timecode input is available. The IDs are reported with the local time of the computer as timecode, with frame rate 25.
Enabled=Y
Description=Playout channels 1-4
Protocol=Harris4Ch
ProtocolSource=udp://192.168.209.120:[email protected]:6005
MQTTTopic=fab/playout/head
ChannelInfo=Channel 1;Channel 2;Channel 3;Channel 4
Timecode=TimeOfDay
TimecodeSource=25
HarrisCmd commands
The protocol HarrisCmd receives the following commands. Multiple spaces in a command are reduced to one space,
the commands can be written in any case. The examples use # as end of command.
- Command:
preroll [ID] - [SOM] - [DUR] - [TITLE]#
Meaning: The next item is prepared, for examplepreroll 123456 - 10:00:00:00 - 00:00:30:00 - publicidad#. It is reported as command and as cue (topic.../cue, reasonCue) with the ID, SOM and DUR. The SOM (start of message timecode) is also kept as the timecode of the next play command. The title can contain-. - Command:
play [ID] - [TOD]#
Meaning: The item with this ID starts, for exampleplay 123456 - 12:34:15:22#. The ID of the play command (not the one of the preroll) becomes the current ID. The timecode is the SOM of the preroll command that was received before, or 0 if there was none. The TOD (time of day) is ignored. - Command:
stop#
Meaning: The current ID is cleared, the timecode is 0. The command can be followed by a space and anything else.
If a timecode type is defined (Timecode and TimecodeSource), its timecode is used instead of the timecode of the preroll command, also for the stop command. Without a timecode input there are no TCStart, TCJump and TCStop messages.
The SOM of a preroll command is used only for the next play command. If the SOM of a preroll command is missing or is not a valid timecode, a warning is written to the log file and the next play command has the timecode 0; the cue message is still published, with an empty SOM. If the DUR is not a valid timecode, a warning is written to the log file and the DUR of the cue message is empty. A preroll command without an ID is only reported as command, not as cue (a warning is written to the log file). A play command without an ID is ignored (a warning is written to the log file). An unknown command is written to the log file and reported as command. The playout system does not receive an answer to any command.
FABAutomation commands
The protocol FABAutomation receives the commands of the FAB Automation Protocol, the same protocol that FAB Subtitler can receive as automation
system. The description of the protocol and of its commands is in the document “FAB Automation Protocol” (PDF), which you receive from FAB.
The playout interface uses these commands:
QUERYFILEis published on the cue topic, with the ReasonPrepare, so that FAB Subtitler gets the subtitles of the ID in advance.STARTFILE,STOPFILE,PAUSEFILEandRESUMEFILEchange the ID of the state. ASTOPFILEorPAUSEFILEwith a FILENAME that is not the ID that is playing is ignored.SETTCsets the clock of the protocol, see TimecodeProtocol.
Every command is published as command message, see below. Every command, also one that is not used, is replied with OK, because the service does not know
which subtitles are available. Empty lines are ignored and not replied.
MQTT messages
The messages are written in JSON format (plain text with named fields). The state of a head (topic <MQTTTopic><head>/state) looks like this:
{
"Reason": "IDChange",
"ID": "A711PGU02065",
"TCMS": "36000000",
"TC": "10:00:00:00",
"TCJump": false,
"FR": "25",
"UTC": "2026-08-10T08:00:00.000",
"Source": "MYSERVER-FABSUBTSERVER",
"ChannelName": "Madrid-Ent5-1"
}
-
Field: Reason
Meaning: Why the message was sent, see below. -
Field: ID
Meaning: The ID which is currently playing on the head, empty when nothing is playing. -
Field: TCMS
Meaning: The timecode in milliseconds. -
Field: TC
Meaning: The timecode as hours:minutes:seconds:frames. -
Field: TCJump
Meaning:truewhen the timecode in the message is known: for the TCStart, TCJump and TCStop messages, and for an ID change when the timecode comes from a timecode input that currently runs (a timecode that stopped does not count) or, forHarrisCmd, from the preroll command, or, forFABAutomationwith TimecodeProtocol, from the commands and the clock of the protocol.falsewhen the timecode is not known, the message then reports a timecode of 00:00:00:00 that FAB Subtitler ignores (it uses its own timecode). -
Field: FR
Meaning: The frame rate of the timecode. ForHarrisCmdthis is the frame rate defined in ProtocolSource when the timecode comes from a command. -
Field: UTC
Meaning: The time at which the message was created (UTC). -
Field: Source
Meaning: The name of the computer followed by-FABSUBTSERVER, for exampleMYSERVER-FABSUBTSERVER. FAB Subtitler ignores the messages that have its own Source (its own name and, when a configuration profile is used,-and the name of the profile), so the messages of the server are not ignored by a FAB Subtitler on the same computer. -
Field: ChannelName
Meaning: The name of the head in ChannelInfo (for exampleMadrid-Ent5-1), the same text as in the column Channel of the web interface. When ChannelInfo is empty it isHead <number>. All messages that the playout interface publishes (state, command and cue) have this field. -
Reason: IDChange
When the message is sent: The ID of the head has changed (a new ID started, or the head stopped and the ID is empty). -
Reason: TCStart
When the message is sent: The first timecode was received, or the timecode runs again after it stopped. -
Reason: TCJump
When the message is sent: The timecode jumped by more than 12 frames, forward or back. The wrap from 23:59:59:xx to 00:00:00:00 is not a jump. With TimecodeProtocoleverySETTCcommand of the playout system also sends this message. -
Reason: TCStop
When the message is sent: The timecode has not changed for 1 second. FAB Subtitler holds its timer at the timecode of the message until the timecode runs again (TCStart, TCJump or a new ID with a timecode), so that no subtitles are transmitted without a timecode.
The messages for TCStart, TCJump and TCStop contain the ID of the last state message that was published on the head (see Delays: it is the ID that is playing, except while the message about a new ID or a stop is still waiting for its delay) and the new timecode.
The commands of a head (topic <MQTTTopic><head>/command, for HarrisCmd <MQTTTopic>/command) report every telegram or command received from the playout
system, also when it repeats the previous one:
- Reason: PlayoutCommand
Command:C4GID=<id>;TC=<timecode>
Meaning: A PLAY (the ID that is playing) or STOP (empty ID) telegram was received. - Reason: PlayoutCommand
Command:C4GCUEID=<id>;TC=<timecode>
Meaning: A CUE telegram was received, the ID that is cued. This is not the current ID. It is also published as cue message. - Reason: PlayoutCommand
Command:FABCMD=<command>
Meaning: A FABAutomation command (any command) was received, for exampleFABCMD=COMMAND=QUERYFILE;FILENAME=A711PGU02065. - Reason: PlayoutCommand
Command:HARRISCMD=<command>
Meaning: A HarrisCmd command (preroll, play, stop or an unknown command) was received. The command is shown with multiple spaces reduced to one, for exampleHARRISCMD=preroll 123456 - 10:00:00:00 - 00:00:30:00 - publicidad.
The command messages contain the fields Reason, Command, UTC, Source and ChannelName (the name of the head in ChannelInfo, as in the state message).
The cue of a head (topic <MQTTTopic><head>/cue, for HarrisCmd <MQTTTopic>/cue) reports the ID of every cue or prepare command that was
received from the playout system, also when it repeats the previous one. It is published as soon as the command is received and is not delayed
by DelayMSStart. FAB Subtitler uses it to get the subtitles of the ID in advance, for example from the file server or the subtitle database.
The message looks like this:
{
"Reason": "Cue",
"ID": "A711PGU02066",
"SOM": "10:00:00:00",
"DUR": "00:00:30:00",
"SOMFR": "25",
"TCMS": "35990000",
"TC": "09:59:50:00",
"TCKnown": true,
"FR": "25",
"UTC": "2026-08-10T07:59:50.012",
"Source": "MYSERVER-FABSUBTSERVER",
"ChannelName": "Madrid-Ent5-1"
}
- Field: Reason
Meaning:Cue: the ID that is played next, there is only one.Prepare: an ID that is prepared, there can be several of them (a protocol which has this command reports it with this reason).Harris4Ch(CUE telegram) andHarrisCmd(preroll command) reportCue,FABAutomationreports theQUERYFILEcommand asPrepare. - Field: ID
Meaning: The ID that is cued. - Field: SOM
Meaning: The start of message timecode, as hours:minutes:seconds:frames. Empty when the protocol does not receive it:Harris4ChandFABAutomationdo not,HarrisCmddoes when the preroll command has a valid SOM. - Field: DUR
Meaning: The duration, as hours:minutes:seconds:frames. Empty when the protocol does not receive it, as for SOM (FABAutomationnever has it). - Field: SOMFR
Meaning: The frame rate of SOM and DUR. Empty when SOM and DUR are empty. - Field: TCMS
Meaning: The timecode in milliseconds at the moment the command was received. - Field: TC
Meaning: The timecode at the moment the command was received, as hours:minutes:seconds:frames. It is the timecode of the timecode input of the head, or of the clock forTimeOfDay,TimeOfDayUTCandZeroBased, or the clock of the protocol forProtocol. - Field: TCKnown
Meaning:truewhen TC is known (from a timecode input that currently runs, or from the clock),falsewhen there is no timecode and TC is 00:00:00:00. - Field: FR
Meaning: The frame rate of TC. - Field: UTC
Meaning: The time at which the message was created (UTC). The receiver can use it to decide whether the message is still valid. - Field: Source
Meaning: The name of the computer followed by-FABSUBTSERVER. - Field: ChannelName
Meaning: The name of the head in ChannelInfo, as in the state message.
FAB Subtitler (automation system MQTT) subscribes to the topic <topic>/cue and adds the ID to the list of the IDs that will be transmitted next, and requests its
subtitles from the file server or the subtitle database in the same way as for the cue of the other protocols. It ignores a cue message when its UTC is
more than 10 seconds old. This protects it from an old cue: the MQTT server keeps the last cue message (retained message) and sends it again when FAB Subtitler connects. Because of this the
clocks of the computers must be set correctly.
Status in the web interface
The web interface (tab AddFuncs) shows for every playout interface a status line with the state of the connection to the playout system, and a table with the channels: the ID, the timecode, the timecode input, the last command and the time at which it was received. The ID is shown as soon as it is received, it is not delayed by DelayMSStart or DelayMSStop. The status line is one of these:
- Connection: TCP, the service listens (
tcp://@...), no client has connected
Status line:No client connected, listening on <url> (<protocol>) - Connection: TCP, the service listens (
tcp://@...), a client is connected
Status line:Client connected: <IP address of the client>, listening on <url> (<protocol>) - Connection: TCP, the service connects to the playout system (
tcp://serverip:port)
Status line:Connected to <url> (<protocol>)orNot connected to <url> (<protocol>), trying to connect - Connection: UDP
Status line:No data received yet on <url> (<protocol>), orReceiving on <url> (<protocol>), the last data was received 3 s ago - Connection: serial port
Status line:Connected to <serial port> (<protocol>) - Connection: the playout interface could not be started
Status line:Not connected to <url> (<protocol>), retrying every 60 seconds
A status line that starts with No or Not is shown as a warning. The state of the connection is updated every second, the timecode
of a running clock (Timecode Protocol, TimeOfDay or TimeOfDayUTC) about four times per second. When a client connects or disconnects, a line
Connection: ... is written to the log file of the entry.
Restart of the service
The messages about the timecode (TCStart, TCJump and TCStop) contain the ID that was published last on the head. FAB Subtitler stops when it receives such a message without an ID, so the service must not forget the ID when it is restarted or when it reconnects to the playout system. Therefore:
- The ID is kept when the connection to the playout system is closed and made again.
- The last published ID of every head, and with Timecode
Protocolthe clock of every head, are saved in the filec:\ProgramData\FAB\FAB Subtitler Server\PlayoutState\<number of the entry>.inf(for example00012.inf, the number is the same as in the name of the log file of the entry). The file is saved when a new ID was published, when the playout system set the clock and every 5 minutes. - When the service starts, it reads the file and uses the IDs for the messages about the timecode, until the playout system reports another ID. The web interface
shows the ID in the column ID. With Timecode
Protocolthe clock continues in real time from where it was, as if the service had not been stopped. The log file of the entry says which IDs were restored, or why the state of the last run was not used (no file, too old, another protocol or MQTT topic). - Nothing is published when the service starts: the MQTT server still has the last state message (it is a retained message).
- The file is not used when it was saved more than 24 hours before, when it is of another protocol or when the MQTT topic of the head was changed. Delete the file if the service must start without the last ID.
- A command of the playout system always replaces the restored ID, also an empty one (stop).
- Every additional function has its own number, it is shown in front of its name in the list of the Configuration program. The number is also in the name of the log file and of this file. Older versions of the Configuration program could give the same number to two functions, they then shared the log file and the state file. The service gives such a function another number when it starts (a warning is written to the log of the service), and the Configuration program corrects the numbers when the configuration is opened: save the configuration to keep them.
Notes
- If the playout system cannot connect to the TCP port of the service, check that the Windows firewall allows connections to this port, and that
ProtocolSource is
tcp://@0.0.0.0:<port>or contains the IP address that the playout system connects to. - Every entry writes its own log file to the folder
c:\ProgramData\FAB\FAB Subtitler Server\Log. The name of the file starts withAddFunc_followed by the number of the entry (for exampleAddFunc_00012). When the playout interface is started (and every time its connection is made again), the log contains the lineInitializing playout interface ...and, when it is ready,Playout interface initialized ..., so you can see when it was started. The log contains all errors, every change of the ID of a head, the start, jump and stop of the timecode, and all messages that are published over MQTT, with the topic and the complete message. - Every 3 hours the log file contains a line for every head (that is processed) about the last 6 hours: how the ID changes and the timecode events (TCStart, TCJump, TCStop) follow each other, for example
Head 1: For 63 of the 64 events in the last 6 hours the ID went to empty 2.31 to 2.96 s before a timecode event (median 2.92 s), and the new ID follows 0.04 to 0.12 s after it.It shows how long before a timecode event the ID was cleared and how long after it the next ID came (only changes that are at most 5 seconds away from the event are counted), for example to judge DelayMSStart and DelayMSStop. The first line is written 3 hours after the entry was started. Without timecode events the line saysThere were no timecode events in the last 6 hours. - At most 100 received telegrams or commands (CUE, PLAY, STOP, preroll, play, stop, FAB commands) wait to be published over MQTT. If the playout system sends more than that before they could be published, the oldest ones are discarded and a warning is written to the log file. This protects the MQTT server from being overloaded.
- A
HarrisCmdcommand is at most 2048 characters long. Longer commands, and data that is longer than that without an end of command, are discarded, and a warning is written to the log file. Data that is incomplete for more than 2 seconds is also discarded. - When the playout interface is initialized, the log file of the entry lists the MQTT topics of every head (
.../state,.../commandand.../cue) and the MQTT servers they are published to. A head which is not processed because ChannelInfo has no name for it is also listed. - The passwords of the MQTT servers are not written to the log files, they are replaced by
****. - The replies of
FABAutomationare sent over TCP: to the playout system that connected when ProtocolSource istcp://@adapterip:port(to all connected clients), over the connection that the service made when it istcp://serverip:port, or over the serial port when ProtocolSource is a serial port. The reply is sent as soon as the command was received, it does not wait for the MQTT messages. - If the Decklink input of a head cannot be started (for example the card is not found or is used by something else), an error is written to the log file and it is tried again every minute. The IDs are reported in the meantime. The Decklink card must be usable for input.
- If no timecode at all is received from a Decklink input 5 seconds after it was started, a warning is written to
the log file, and again every minute while there is still none. The reason is usually that the video signal has
no timecode of the configured type (
ATCLTCorATCVITC), or that there is no video signal. - With
Decklink, the timecode that is reported with an ID is the last timecode of the input of that head, but only while the timecode runs. If it has stopped (or the signal repeats the same timecode, for example 00:00:00:00), the timecode is reported as not known (TCJumpisfalse) and FAB Subtitler uses its own timecode.
Short instructions to install Mosquitto service on Windows
- Download and install Mosquitto service for Windows
- Open cmd.exe as administrator
- Create a user with the password
cd "C:\Program Files\mosquitto"
mosquitto_passwd -c -b passwd.txt myusername mypassword
- Edit the config file: open C:\Program Files\mosquitto\mosquitto.conf in Notepad (as Administrator) and add these lines at the end
listener 1883
allow_anonymous false
password_file C:\Program Files\mosquitto\passwd.txt
log_dest file C:\Program Files\mosquitto\mosquitto.log
log_type all
- Make sure that the Mosquitto service can read the file passwd.txt
icacls "C:\Program Files\mosquitto\passwd.txt" /grant "SYSTEM:(R)"
net start mosquitto
- Open the firewall port:
netsh advfirewall firewall add rule name="Mosquitto 1883" dir=in action=allow protocol=TCP localport=1883
-
Restart the Mosquitto service
-
Test if the connection to MQTT server is working
mosquitto_sub -h localhost -p 1883 -u myusername -P mypassword -t test
This page was last updated on 2026-10-17