This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Scripting

    mAirList has a built-in scripting engine that allows you to automate tasks, react to events, and integrate mAirList with other systems, beyond what is possible with the regular configuration options.

    Scripts are written in a Pascal dialect (based on Pascal Script), and are stored as plain text files with the extension .mls. They have access to most of the internal objects of mAirList, e.g. the playlists, players, cartwall, and database, as well as a number of helper functions.

    There are two kinds of scripts, which differ in how and when they are executed: one-shot scripts and background scripts.

    One-Shot Scripts

    A one-shot script is loaded, executed once, and unloaded again. Execution starts with the main begin ... end. block at the end of the script:

    begin
      ExecuteCommand('PLAYER 1-1 START');
      SystemLog('Player 1-1 started by script');
    end.
    

    One-shot scripts can be run in the following ways:

    • Manually, from the About menu of the main window (Run Script…).
    • Through the Run script action (Miscellaneous category), e.g. from the event scheduler, a cartwall action, or any other place where actions can be configured.
    • Through the remote control command RUNSCRIPT <filename>, e.g. from a hotkey, a MIDI controller, or a network remote control.

    As the script is unloaded after execution, global variables do not keep their values between two runs. Use runtime data (SetRuntimeData/GetRuntimeData) to store values that must survive, or to share them with other scripts.

    Background Scripts

    A background script is loaded when mAirList starts, and remains active until mAirList is shut down. Instead of a main block, it contains event handlers (hooks): procedures with predefined names and parameters, which are called by mAirList whenever the respective event occurs, e.g. when a player starts, an item is logged, or a MIDI message is received.

    procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);
    begin
      SystemLog('Now playing: ' + Item.GetTitle);
    end;
    

    Background scripts are set up in the configuration, on the Background Scripts page: Add a new entry, select the script file, and optionally check Automatically reload when changed on disk, so that changes to the script are applied immediately, without restarting mAirList.

    Note the following differences to one-shot scripts:

    • A background script does not need a main begin ... end. block. mAirList adds an empty one automatically so that the script compiles. If the script contains a main block anyway, it is never executed. Use the OnLoad event handler for initialization code instead.
    • Global variables keep their values for as long as the script is loaded.
    • Each background script processes its events in its own thread, so a slow event handler does not block the user interface or the playback. Still, event handlers should return as quickly as possible, so that subsequent events are not delayed.
    • Only implement the event handlers you actually need. Event handlers that are not present in the script are simply not called.

    Errors that occur while loading the script or executing an event handler are reported in the System Log.

    Template

    A template that contains all available event handlers (with empty bodies) is included in the mAirList installation folder as Background Script Template.mls. Copy the handlers you need into your own script.

    Event Handlers

    This section lists all event handlers that are available in background scripts, along with their exact syntax and parameters. Event handlers are identified by their name only, so the parameter list must match exactly as shown here; a different parameter list will lead to errors when the handler is called. Copying the handlers from the template is the safest way to get them right.

    A few general notes on the parameters:

    • Playlist and player indexes (PlaylistIndex, PlayerIndex) are counted from 0, i.e. playlist 1 has index 0, and player 1-1 is PlaylistIndex = 0, PlayerIndex = 0.
    • Cart player indexes are counted from 1, i.e. they match the numbers displayed in the cartwall.
    • Durations (TTimeValue) are given in seconds, as a floating point number.
    • Items (IPlaylistItem) give access to the item’s properties, e.g. Item.GetTitle, Item.GetArtist, or Item.GetDuration. The item may be nil in some cases, so check it with Assigned(Item) before use.
    • Player states (TPlayerState) are values such as psEmpty, psLoaded, psPlaying, psFading, psPaused, psStopped, psPFL, psEOF and psError.

    Script and Application Lifecycle

    procedure OnLoad;
    procedure OnUnload;
    

    Called when the script is loaded (i.e. when mAirList starts, or when the script is reloaded after a change), and when it is unloaded (when mAirList shuts down, or before the script is reloaded). Use OnLoad for initialization, e.g. to start timers, and OnUnload for cleanup.

    procedure OnOnAir;
    procedure OnOffAir;
    

    Called when mAirList is switched to ON AIR or OFF AIR mode.

    procedure OnSystemLog(Category: TLogCategory; Message: string);
    

    Called when a message is added to the System Log.

    • Category: The type of message: lcInfo, lcWarning, lcError, lcStatus, lcPlaylist (items started and stopped), or lcDebug.
    • Message: The text of the message.

    Be careful what you do in this handler: Do not write to the System Log yourself, and avoid raising exceptions, as this may result in an endless loop.

    Timers and Runtime Data

    procedure OnTimer;
    

    Called periodically after the timer has been started with EnableTimer(Interval), where Interval is given in milliseconds, e.g. EnableTimer(1000) in OnLoad. Stop the timer with DisableTimer.

    procedure OnTimerEx(ID: string);
    

    Same as OnTimer, but supports multiple timers with different intervals. Start each timer with EnableTimerEx(ID, Interval), and stop it with DisableTimerEx(ID).

    • ID: The ID of the timer that has elapsed, as passed to EnableTimerEx.
    procedure OnRuntimeDataChange(Key, Value: string);
    

    Called when a runtime data value is set, e.g. with SetRuntimeData from any script. Runtime data are global variables that can be shared between scripts.

    • Key: The name of the value.
    • Value: The new value.

    Remote Control Commands

    procedure OnExecuteCommand(Command: string);
    

    Called whenever a remote control command is executed, regardless of its origin (remote control interface, action, script etc.). This also allows you to implement custom commands, by checking for your own command names.

    • Command: The command text, e.g. PLAYER 1-1 START.

    Windows

    procedure OnCartwallShow;
    procedure OnCartwallHide;
    procedure OnMixEditorShow;
    procedure OnMixEditorHide;
    procedure OnCueEditorShow;
    procedure OnCueEditorHide;
    

    Called when the cartwall window, the Mix Editor, or a Cue Editor window is shown or hidden.

    Playlists

    procedure OnAutomationOn(PlaylistIndex: integer);
    procedure OnAutomationOff(PlaylistIndex: integer);
    

    Called when automation is switched on or off for a playlist.

    • PlaylistIndex: The playlist, counted from 0.
    procedure OnPlaylistEmpty(PlaylistIndex: integer);
    

    Called when a playlist runs empty while in automation mode, i.e. there are no more items left to play.

    • PlaylistIndex: The playlist, counted from 0.
    procedure OnPlaylistChange(PlaylistIndex: integer);
    

    Called when the content of a playlist changes, e.g. when items are added, removed, or moved.

    • PlaylistIndex: The playlist, counted from 0.
    procedure OnAfterEditPlaylistItem(Item: IPlaylistItem);
    

    Called after an item has been edited in the Properties dialog, and the changes have been saved.

    • Item: The edited item.

    Playlist Players

    procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);
    

    Called when a playlist player is started.

    • PlaylistIndex, PlayerIndex: The player, both counted from 0.
    • Item: The item loaded in the player.
    procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer; Duration: TTimeValue; Item: IPlaylistItem);
    

    Called when a playlist player is stopped.

    • PlaylistIndex, PlayerIndex: The player, both counted from 0.
    • Duration: How long the item was playing, in seconds.
    • Item: The item loaded in the player.
    procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
    

    Called when a playlist player reaches the EOF warning point (by default, 10 seconds before the end of the item).

    • PlaylistIndex, PlayerIndex: The player, both counted from 0.
    procedure OnPlayerStateChange(PlaylistIndex: integer; PlayerIndex: integer; OldState: TPlayerState; NewState: TPlayerState; Item: IPlaylistItem);
    

    Called whenever a playlist player changes its state, e.g. from psLoaded to psPlaying.

    • PlaylistIndex, PlayerIndex: The player, both counted from 0.
    • OldState, NewState: The previous and the new state of the player.
    • Item: The item loaded in the player (may be nil, e.g. when the player is empty).
    procedure OnPlayerPFLOn(PlaylistIndex: integer; PlayerIndex: integer; PFLCount: integer);
    procedure OnPlayerPFLOff(PlaylistIndex: integer; PlayerIndex: integer; PFLCount: integer);
    

    Called when a playlist player enters or leaves PFL.

    • PlaylistIndex, PlayerIndex: The player, both counted from 0.
    • PFLCount: The number of PFL sources (players, editors etc.) that are active after the change. For example, PFLCount = 0 in OnPlayerPFLOff means that no PFL is active anymore.

    Cartwall

    procedure OnCartwallOnAirModeChange(OldMode, NewMode: TCartwallOnAirMode);
    

    Called when the cartwall changes its mode.

    • OldMode, NewMode: The previous and the new mode: oamOnAir, oamOffAir, oamPFL, or oamVT (voice tracking).
    procedure OnCartwallActivePageChange(OldPage: ICartwallPageControl; NewPage: ICartwallPageControl);
    

    Called when the user switches to another page (tab) of the cartwall.

    • OldPage, NewPage: The previous and the new page. Either can be nil, if no page was or is open.
    procedure OnCartwallPlayerStateChange(PlayerIndex: integer;
      OldState: TPlayerState; NewState: TPlayerState;
      Item: IAudioCartwallItem; PlaylistItem: IPlaylistItem;
      OnAirMode: TCartwallOnAirMode);
    procedure OnCartwallPlayerStateChangeEx(PlayerIndex: integer;
      OldState: TPlayerState; NewState: TPlayerState;
      Item: IAudioCartwallItem; PlaylistItem: IPlaylistItem;
      OnAirMode: TCartwallOnAirMode; Selected: boolean);
    

    Called when the state of a cart player on the current page changes, and for all cart players when the user switches to another page. This is useful to mirror the cartwall on external hardware, e.g. button LEDs.

    • PlayerIndex: The cart player, counted from 1.
    • OldState, NewState: The previous and the new state of the cart player.
    • Item: The cartwall item (button), or nil if the cart player is empty.
    • PlaylistItem: The item loaded in the cart player, or nil.
    • OnAirMode: The current mode of the cartwall (see above).
    • Selected (Ex version only): Whether the cart player is currently selected.
    procedure OnCartwallPlayerStart(PlayerIndex: integer; Item: IAudioCartwallItem; PlaylistItem: IPlaylistItem);
    procedure OnCartwallPlayerStop(PlayerIndex: integer; Item: IAudioCartwallItem; PlaylistItem: IPlaylistItem; Duration: TTimeValue);
    procedure OnCartwallPlayerEOFWarning(PlayerIndex: integer; Item: IAudioCartwallItem; PlaylistItem: IPlaylistItem);
    

    Called when a cart player is started, stopped, or reaches its EOF warning point.

    • PlayerIndex: The cart player, counted from 1.
    • Item: The cartwall item (button).
    • PlaylistItem: The item loaded in the cart player.
    • Duration (OnCartwallPlayerStop only): How long the item was playing, in seconds.

    Items

    procedure OnItemStart(Item: IPlaylistItem; Region: byte; OnAir: boolean; UniqueID: string);
    procedure OnItemStop(Item: IPlaylistItem; Region: byte; OnAir: boolean; UniqueID: string; Duration: TTimeValue);
    

    Called when the playback of an item begins or ends, in any player (playlist, cartwall, etc.). These are the same events that are passed to the logging interfaces, so they are the best choice for “now playing” information or as-run logs.

    • Item: The item.
    • Region: The region the item is played in, when regionalization is used.
    • OnAir: Whether mAirList was in ON AIR mode when the item was played.
    • UniqueID: A unique ID for this playback, which is identical in OnItemStart and the corresponding OnItemStop, so the two events can be matched.
    • Duration (OnItemStop only): How long the item was playing, in seconds.
    procedure OnItemCueMarker(Item: IPlaylistItem; MarkerType: TCuePositionType);
    

    Called when the playback of an on-air item passes a cue marker.

    • Item: The item.
    • MarkerType: The type of the cue marker, e.g. ptRamp1, ptHookIn, ptOutro, ptStartNext, ptFadeOut, or ptCueOut.
    procedure OnItemMetadata(Item: IPlaylistItem; Metadata: string);
    

    Called when metadata (e.g. the current title) is received from a stream that is played or relayed.

    • Item: The stream item.
    • Metadata: The received metadata, e.g. Artist - Title.

    PFL

    procedure OnPFLOn(Item: IPlaylistItem; PFLCount: integer);
    procedure OnPFLOff(Item: IPlaylistItem; PFLCount: integer);
    

    Called when any PFL source (player, cart player, Cue Editor, Mix Editor, etc.) starts or stops PFL playback.

    • Item: The item played in PFL.
    • PFLCount: The number of active PFL sources after the change.
    procedure OnExtPFLOn(Item: IPlaylistItem; ExtPFLCount: integer);
    procedure OnExtPFLOff(Item: IPlaylistItem; ExtPFLCount: integer);
    

    Same as above, but only for “external” PFL sources, i.e. editors such as the Cue Editor or Mix Editor, not players.

    • Item: The item played in PFL.
    • ExtPFLCount: The number of active external PFL sources after the change.

    Serial Ports and MIDI

    procedure OnSerialData(Port: string; Data: AnsiString);
    

    Called when data is received from a serial port. The port must be opened first, either from the script (using the ComPort function), or by adding a Serial Port remote control interface for that port.

    • Port: The name of the port, e.g. COM1.
    • Data: The received data. Data may arrive in arbitrary chunks, so you may have to buffer it until a complete message has been received.
    procedure OnMidiMessage(Device: integer; Status, Data1, Data2: byte);
    procedure OnMidiSysex(Device: integer; Data: string);
    

    Called when a MIDI message or a SYSEX message is received from a MIDI input device that is opened, e.g. by a MIDI remote control interface.

    • Device: The number of the MIDI input device.
    • Status, Data1, Data2: The status byte (message type and channel) and the two data bytes of the message.
    • Data: The SYSEX data.

    Voice Tracking

    procedure OnVTOn;
    procedure OnVTOff;
    

    Called when the Voice Track Recorder is opened or closed.

    procedure OnVTVolume(Player: string; Volume: single; Source: string);
    

    Called when a volume slider is moved in the Voice Track Recorder.

    • Player: The player whose volume was changed, A or B.
    • Volume: The new volume in dB.
    • Source: Where the change originated from: GUI (moved with the mouse) or REMOTE (changed through a remote control).

    Encoder

    procedure OnEncoderInputToggle(Input: TEncoderInput; NewState: boolean);
    

    Called when an input of the encoder is switched on or off.

    • Input: The encoder input, e.g. eiPlayer, eiMic, eiLine, or eiAux.
    • NewState: true if the input was switched on, false if it was switched off.
    procedure OnEncoderConnectionStateChange(Connection: IEncoderConnection; OldState, NewState: TEncoderConnectionState);
    

    Called when the state of an encoder connection (e.g. to a streaming server) changes.

    • Connection: The encoder connection.
    • OldState, NewState: The previous and the new state: ecsDisconnected, ecsConnecting, ecsConnected, or ecsError.

    Remote Control Interfaces

    The following event handlers are related to particular remote control interfaces. In the template, they are commented out, as the script would otherwise fail to compile when the respective module is not available.

    In all of these handlers, the Remote parameter is the remote control interface that triggered the event, so you can distinguish between multiple interfaces of the same type.

    SAS

    procedure OnSASCommand(Remote: ISASRemote; Command: byte; Data: string);
    

    Called for every message received from the SAS interface.

    • Command: The SAS command code.
    • Data: The raw data bytes of the message.
    procedure OnSASGPIOn(Remote: ISASRemote; GPI: byte);
    procedure OnSASGPIOff(Remote: ISASRemote; GPI: byte);
    

    Called when a GPI of the console goes on or off.

    • GPI: The number of the GPI, counted from 1.
    procedure OnSASPFLOn(Remote: ISASRemote; SourceName: string);
    procedure OnSASPFLOff(Remote: ISASRemote; SourceName: string);
    

    Called when the PFL of a console source is switched on or off.

    • SourceName: The name of the source.

    DHD

    procedure OnDHDCommand(Remote: IDHDRemote; ID: cardinal; Len: integer;
      Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7: byte);
    

    Called for every message received from a DHD ECP interface.

    • ID: The message ID.
    • Len: The number of data bytes in the message (0 to 8).
    • Data0 to Data7: The data bytes of the message (unused bytes are 0).
    procedure OnDHDLogic(Remote: IDHDRemote; LogicNo: integer; State: boolean);
    

    Called when a logic of the DHD core changes its state.

    • LogicNo: The logic ID.
    • State: The new state of the logic.
    procedure OnDHDFaderOn(Remote: IDHDRemote; FaderNo: integer; State: boolean);
    procedure OnDHDFaderPFL(Remote: IDHDRemote; FaderNo: integer; State: boolean);
    procedure OnDHDFaderLevel(Remote: IDHDRemote; FaderNo: integer; Level: SmallInt);
    

    Intended to be called when a fader is switched on or off, its PFL is switched, or its level changes.

    procedure OnDHDControlAPIConnected(Remote: IDHDControlAPIRemote);
    procedure OnDHDControlAPIDisconnected(Remote: IDHDControlAPIRemote);
    

    Called when the connection of a DHD Control API interface to the core is established or lost.

    procedure OnDHDControlAPILogic(Remote: IDHDControlAPIRemote; LogicNo: integer; State: boolean);
    

    Called when a logic changes its state (DHD Control API).

    • LogicNo: The logic ID.
    • State: The new state of the logic.
    procedure OnDHDControlAPIChannelOn(Remote: IDHDControlAPIRemote; ChannelNo: integer; State: boolean);
    

    Called when the fader start of a channel changes (DHD Control API).

    • ChannelNo: The fader channel number.
    • State: The new fader start state.

    WheatNet-IP

    procedure OnWheatNetBladeSLIOEvent(Remote: IWheatNetBladeRemote; SLIO: integer; State: boolean);
    

    Called when an SLIO of a WheatNet-IP BLADE changes its state.

    • SLIO: The number of the SLIO.
    • State: The new state.
    procedure OnWheatNetBladeSLIOState(Remote: IWheatNetBladeRemote; SLIO: integer; State: boolean);
    

    Called when the reply to a QuerySLIO request is received. The parameters are the same as above.

    Telos VX (LWCP)

    procedure OnLWCPCommand(Remote: IBaseLWCPRemote; Command: string; ObjectName: string; Data: IPersistentObject);
    

    Called for every LWCP message received from a Telos VX interface.

    • Command: The LWCP operation, e.g. event or ack.
    • ObjectName: The object the message refers to, e.g. studio.line#1.
    • Data: The properties of the message, as name/value pairs.
    procedure OnVXLineEvent(Remote: IVXLWCPRemote; Line, Hybrid: integer;
      Comment, State, CallState: string; Time, Cause: integer;
      Busy: boolean; RemoteNumber, CallerID, Direction: string);
    

    Called when the state of a phone line changes. The parameters correspond to the properties of the line, as reported by the VX engine:

    • Line: The line number.
    • Hybrid: The hybrid the line is assigned to.
    • Comment: The comment entered for the call (e.g. by the call screener).
    • State, CallState: The state of the line and of the call.
    • Time: The duration of the call.
    • Cause: The cause code (e.g. when a call is dropped).
    • Busy: Whether the line is busy.
    • RemoteNumber, CallerID: The number and caller ID of the remote party.
    • Direction: The direction of the call (incoming or outgoing).

    REST and WebSocket

    procedure OnRESTRequest(Request: TRESTRequest; var Response: IPersistentStorage);
    procedure OnRESTRequestUnauthenticated(Request: TRESTRequest; var Response: IPersistentStorage);
    

    Called when a request is made to the REST server. This lets you implement your own JSON endpoints. Use paths that do not collide with the built-in endpoints. For authenticated requests, the user must have the Scripting permission in the REST user management.

    • Request: The request, with the fields Method (e.g. GET or POST), Document (the path, e.g. /myendpoint), Parameters (query or form parameters) and UploadDocument (the JSON body of the request, if any).
    • Response: Set this to the JSON result to handle the request. Leave it unassigned (nil) to pass the request on to the next handler.

    OnRESTRequest is only called for authenticated requests. OnRESTRequestUnauthenticated is called before authentication is checked, so it is also called for requests without valid credentials. Be careful not to expose any sensitive functions there.

    procedure OnRESTRequestRaw(Request: TRawRESTRequest; var Response: TRawRESTResponse);
    procedure OnRESTRequestRawUnauthenticated(Request: TRawRESTRequest; var Response: TRawRESTResponse);
    

    Same as above, but for non-JSON responses, e.g. HTML pages or files.

    • Request: The request, with the fields Method, Document and Parameters.
    • Response: To handle the request, set Response.Handled := true, and fill in ResponseNo (the HTTP status code, e.g. 200), ContentType, CharSet and Data. Alternatively, set SendFile := true and Filename to send a file.
    procedure OnWebSocketServerNewConnection(Event: TRESTWSNewConnectionEvent);
    procedure OnWebSocketServerConnectionClosed(Event: TRESTWSConnectionClosedEvent);
    procedure OnWebSocketServerTextData(Event: TRESTWSTextDataEvent);
    

    Called when a WebSocket client connects to or disconnects from the REST server, or sends text data.

    • Event.Remote: The REST remote control interface.
    • Event.Document: The path of the WebSocket connection.
    • Event.ConnectionInfo: Information about the client connection: ID (unique connection ID), IP, Port, UserID and UserName (of the authenticated user).
    • Event.Data (OnWebSocketServerTextData only): The received text.

    JSON Server and JSON Client

    procedure OnJSONServerRemoteClientConnect(Remote: IJSONServerRemote; ClientID: cardinal);
    procedure OnJSONServerRemoteClientDisconnect(Remote: IJSONServerRemote; ClientID: cardinal);
    

    Called when a client connects to or disconnects from a JSON Server interface.

    • ClientID: A unique ID of the client connection, which can be used with SendTo.
    procedure OnJSONServerRemoteClientData(Remote: IJSONServerRemote; ClientID: cardinal; Data: IPersistentStorage);
    procedure OnJSONServerRemoteClientDataObject(Remote: IJSONServerRemote; ClientID: cardinal; Data: IPersistentObject);
    

    Called when a JSON document is received from a client. OnJSONServerRemoteClientDataObject is only called if the document is a JSON object, which saves you the type check.

    • ClientID: The ID of the client connection.
    • Data: The received JSON document.
    procedure OnJSONClientRemoteConnect(Remote: IJSONClientRemote; ClientID: cardinal);
    procedure OnJSONClientRemoteDisconnect(Remote: IJSONClientRemote; ClientID: cardinal);
    

    Called when the connection of a JSON Client interface to its server is (re-)established or lost.

    • ClientID: Always 0; only present for compatibility with the JSON Server handlers.
    procedure OnJSONClientRemoteData(Remote: IJSONClientRemote; Data: IPersistentStorage);
    procedure OnJSONClientRemoteDataObject(Remote: IJSONClientRemote; Data: IPersistentObject);
    

    Called when a JSON document is received from the server. OnJSONClientRemoteDataObject is only called if the document is a JSON object.

    • Data: The received JSON document.