Pular para o conteúdo

Events API

Este conteúdo não está disponível em sua língua ainda.

The control server pushes live updates over a WebSocket channel: every configuration change made through the API, the per-second status of streams, adapters and softcams, system alerts and license state changes. The built-in web interface keeps its views current with nothing else, so a custom interface can do the same: load the state once with the HTTP methods, then apply the messages of this channel. The channel is one-directional apart from a liveness probe: the server never accepts commands over it.

Request: GET {control_path}control/event/?token=<token> with the header Upgrade: websocket

  • token - string, required to receive events. A one-time token issued by ws-token to the authenticated user; it is valid for 60 seconds and is consumed by the first handshake that presents it.

The credential is the token alone: a session cookie or an Authorization header on the handshake is ignored. The token is bound to the user who requested it, and both roles receive the same messages - an observer’s token admits the connection to every event listed on this page.

The handshake answers:

  • 101 - the connection is upgraded. With a valid token it is admitted into the broadcast set and receives every message below from that moment on. Without a token parameter the connection is a liveness-only session: it is upgraded, answers ping, and never receives an event.
  • 400 - the Upgrade header is missing or is not websocket.
  • 403 - the token is unknown, expired, already used, or its user has been disabled or removed since the token was issued. No session is opened.

Sec-WebSocket-Key is optional: when present the reply carries Sec-WebSocket-Accept, when absent the 101 goes out without it. Connection, Sec-WebSocket-Version and subprotocols are not checked. The scheme is ws://, or wss:// when the control server serves TLS (crt_chain and crt_key in the settings). With the --no-web-auth command line option every handshake is admitted without a token.

Nothing is replayed: a message pushed before the handshake completed is not delivered to the new connection, so a client loads the current state with the HTTP methods after every connect and reconnect. Every reconnect needs a fresh token.

Example, in a browser with a login session:

const { token } = await fetch("/control/", {
method: "POST",
body: JSON.stringify({ cmd: "ws-token" }),
}).then(r => r.json());
const ws = new WebSocket(`ws://server:8000/control/event/?token=${encodeURIComponent(token)}`);
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
console.log(msg.scope, msg);
};

Every server message is one text frame with a JSON object. The scope field names the message type; the other fields depend on the scope:

{
"scope": "set-stream",
"stream": { "id": "a001", "name": "...", "type": "spts", "enable": true, "input": [ "..." ] }
}

The one text frame without JSON is pong, the answer to the client’s ping. Messages are delivered in the order they were produced. A field that is unset in the configuration is absent from the message, never null, so a client checks for presence.

The server accepts exactly one client message:

  • ping - text frame. Answered with the text frame pong on the same connection. A liveness-only session (no token) gets the same answer.

A WebSocket ping control frame (opcode 9) is answered with a pong control frame carrying the same payload; it is not a client message and never closes the connection. Any other text frame closes the connection with code 1008. A binary frame, or a message larger than 256 KiB, ends the connection without a close code; a protocol violation such as an unmasked frame is answered with close code 1002.

The server sends no WebSocket ping frames of its own. A client that wants to detect a dead connection sends ping periodically and treats a late pong as a failure. Astra’s own peer monitor (the ws_monitor module, used by a fallback instance to watch its master) sends ping every second, expects pong within 3 seconds and reconnects one second after a failure.

  • 1001 - the server ends the session: the control server is shutting down (process exit, restart or configuration reload), or the client is too slow. A slow client is one whose unsent backlog exceeds 1 MiB; it is disconnected with the log line WebSocket client buffer full, slow client, disconnecting, and the messages that did not fit are lost.
  • 1002 - a protocol violation in a client frame.
  • 1008 - a client message other than ping.
  • A close frame from the client is not answered; the server drops the connection.

A connection stays open when its user is disabled, removed, or changes the password: those actions revoke the user’s login sessions and streaming sessions, not open WebSocket sessions. The next handshake of that user is refused with 403 at the token check.

Each configuration command that changes the configuration pushes a message with the resulting object, after the change is applied and before the configuration is saved. A client that issued the command receives the message too. Messages that say "remove": true carry only the identifier.

Pushed by set-stream, toggle-stream, and by set-adapter, set-softcam and set-category when a stream had to be changed because an adapter, a softcam or a category it referenced was renamed or removed.

{
"scope": "set-stream",
"gid": 466561,
"stream": { "id": "a001", "name": "...", "type": "spts", "enable": true, "input": [ "..." ] }
}
  • stream - the stream configuration as stored: the object from the request for set-stream, the stored object with enable flipped for toggle-stream, the rewritten stored object when an input address changed (dvb://<adapter id>, cam=<softcam id>) or a group assignment was dropped. A stream discovered by the scan list of set-adapter is pushed the same way. Before pushing, set-stream adds the table version counters to the object: pmt_version and sdt_version for an SPTS stream (1 when the request had none, otherwise the request’s value plus one modulo 32), pat_version, cat_version, sdt_version and nit_version for an MPTS stream (0 when absent, otherwise plus one modulo 32).
  • gid - number, present only in the message of set-stream and only when the configuration holds a gid. The object id counter the web interface keeps in the configuration, updated from the request’s gid when it carried one: a new id is this counter in base 36, and the counter is echoed so every connected interface continues from the same value.

Removal or replacement:

{
"scope": "set-stream",
"stream": { "id": "a001", "remove": true, "up": false }
}
  • remove - true, the stream with this id is no longer in the configuration.
  • up - present when pushed by set-stream: true when the stream is being replaced and a set-stream message with the new object follows, false when it is removed. Absent when the removal is a side effect of set-adapter (a stream whose only input was the removed adapter).

Pushed by set-adapter and toggle-adapter.

{
"scope": "set-adapter",
"gid": 466561,
"adapter": { "id": "a002", "name": "...", "enable": true, "adapter": 0 }
}
  • adapter - the adapter configuration as stored; for toggle-adapter the stored object with enable flipped.
  • gid - number, present only in the message of set-adapter and only when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-adapter", "adapter": {"id": "a002", "remove": true, "up": false}}. up is true when a message with the replacement follows, false when the adapter is removed. The dependent streams are pushed as set-stream messages after this one.

Pushed by set-softcam.

{
"scope": "set-softcam",
"gid": 466561,
"softcam": { "id": "a003", "name": "...", "type": "newcamd" }
}
  • softcam - the softcam configuration as stored.
  • gid - number, present when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-softcam", "softcam": {"id": "a003", "remove": true, "up": false}}, with up as for set-adapter. Streams whose inputs referenced the softcam follow as set-stream messages.

Pushed by set-cas.

{
"scope": "set-cas",
"gid": 466561,
"cas": { "id": "a004", "name": "..." }
}
  • cas - the CAS configuration as stored.
  • gid - number, present when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-cas", "cas": {"id": "a004", "remove": true, "up": false}}, with up as for set-adapter.

Pushed by set-server.

{
"scope": "set-server",
"id": 0,
"server": { ... }
}
  • id - number, the zero-based position of the server in the servers list of the configuration; absent when a new server was appended.
  • server - the server entry as stored; {"remove": true} when the entry at id was removed.

Pushed by set-user (both the control command and the observer’s own-password variant) and toggle-user.

{
"scope": "set-user",
"id": "login",
"user": { "type": 1, "enable": true, "cipher": "...", "created": 1758240000 }
}
  • id - string, the login.
  • user - the user entry as stored: type (1, 2 or 3), enable, cipher (the password hash; the plain password from the request is never pushed) and the other fields of the request. created (Unix time) is set when the request creates the user; on an existing user set-user keeps only cipher from the stored entry, so created is present only when the request repeats it. For toggle-user it is the stored entry with enable flipped. {"remove": true} when the user was removed.

Pushed by the set-category command on the /control/ entry point.

{
"scope": "set-category",
"id": 0,
"category": { "name": "...", "groups": [ { "name": "..." } ] }
}
  • id - the zero-based index of the category the request addressed, as the request sent it (a number, or a string when the request sent a numeric string); absent when a new category was appended.
  • category - the category as stored; groups is always a list. {"remove": true} when the category was removed.

Streams whose group assignment in the renamed or removed category changed are pushed as set-stream messages before this one.

Pushed by set-auth.

{
"scope": "set-auth",
"auth": { "enable": true }
}
  • auth - the HTTP authentication settings as stored (the auth object of the request, with http_ip_allow and http_ip_deny sorted by prefix length, the longest prefix first). Absent when the request had no auth object.

Pushed by set-config.

{
"scope": "set-config",
"key": "...",
"data": { ... }
}
  • key - the configuration key that was set.
  • data - the value stored under it; absent when the key was cleared.

Pushed by set-settings. Astra restarts one second after the reply, so a client receives this message and then loses the connection.

{
"scope": "set-settings",
"gid": 466561,
"settings": { "control_path": "...", "http_server_name": "..." }
}
  • gid - the stored object id counter (see set-stream).
  • settings - the settings object as stored; absent when the request emptied it.

Pushed by set-log.

{
"scope": "log_event",
"set": { "api_access": true }
}
  • set - the log settings as stored.

Pushed by POST /api/output-group[/{name}].

{
"scope": "post-output-group",
"index": 0,
"remove": false,
"group": { "name": "..." }
}
  • index - number, the zero-based position of the group in the output list; absent when a new group was appended.
  • remove - true when the group at index was removed; absent otherwise.
  • group - the group as stored; absent when the group was removed.

Pushed by set-stream-image. Nothing is stored: the message relays a screenshot address to the connected interfaces.

{
"scope": "stream_image",
"channel_id": "a001",
"src": "http://..."
}
  • channel_id - the stream id from the request.
  • src - the url field of the request.

Pushed once per second for every active input of every enabled stream that has an id, from the input’s analyzer, also while no data arrives (bitrate 0, onair false). Not pushed while the input is waiting for a restart (its watchdog fired).

{
"scope": "stream_event",
"channel_id": "a001",
"input_id": 1,
"onair": true,
"bitrate": 4210,
"scrambled": false,
"cc_error": 0,
"pes_error": 0
}
  • channel_id - the stream id.
  • input_id - the input identifier: the one-based position of the input in the stream’s input list as a number, unless the input address carries its own id option (#id=7), whose value is used instead as a string ("7").
  • onair - boolean, the analyzer’s verdict for the last second: false when the payload bitrate is under the expected minimum, a video or audio PID is scrambled or had more than 2 PES errors, or the CC error limit is reached.
  • bitrate - number, Kbit/s over the last second.
  • scrambled - boolean, a video or audio PID carried scrambled packets in the last second.
  • cc_error - number, continuity counter errors in the last second.
  • pes_error - number, PES errors in the last second.

For an MPTS stream the analyzer runs on the multiplex output, and the message carries no input_id; onair is always true, scrambled is false, and cc_error and pes_error are 0:

{
"scope": "stream_event",
"channel_id": "m001",
"onair": true,
"bitrate": 38000,
"scrambled": false,
"cc_error": 0,
"pes_error": 0
}

Pushed once per second for every running adapter.

A DVB adapter:

{
"scope": "adapter_event",
"dvb_id": "a002",
"status": 31,
"signal": 65535,
"signal_db": -4520,
"snr": 62000,
"snr_db": 1380,
"ber": 0,
"unc": 0,
"bitrate": 41000
}
  • dvb_id - the adapter id.
  • status - number, the frontend status bits: 0x01 signal, 0x02 carrier, 0x04 FEC inner coding, 0x08 sync, 0x10 lock, 0x20 timed out, 0x40 reinitialized. 0 is pushed in the second in which the adapter was stopped by its watchdog (CC, PES, sync byte, receive timeout or PAT checksum check); while the adapter is restarting no message is pushed.
  • signal, snr - numbers, the raw driver values.
  • signal_db, snr_db - numbers, decibels multiplied by 100.
  • ber, unc - numbers, bit errors and uncorrected blocks as reported by the driver.
  • bitrate - number, Kbit/s received over the last second.

A virtual adapter (a SAT>IP, CI or address-based adapter) carries the analyzer verdict instead of frontend values:

{
"scope": "adapter_event",
"dvb_id": "a006",
"virtual": true,
"satip": true,
"bitrate": 41000,
"on_air": true
}
  • virtual - always true for these adapters.
  • satip - true for a SAT>IP adapter, absent otherwise.
  • bitrate - number, Kbit/s over the last second.
  • on_air - boolean, the analyzer verdict as in stream_event.

Pushed when a DVB adapter is taken into use or released (an adapter is started, stopped, toggled, removed or reconfigured).

{
"scope": "adapter_status_update",
"adapter": 0,
"busy": true
}
  • adapter - number, the system adapter number (/dev/dvb/adapterN).
  • busy - boolean, true while an adapter configuration uses it.

Pushed for every newcamd softcam: once per second while it is connected and logged in, and once for every failed connection attempt. A softcam connects when the first stream that decrypts with it starts, or at once when its configuration has force set; an unused softcam pushes nothing.

{
"scope": "softcam_event",
"softcam_id": "a003",
"caid": 2304,
"status": 3,
"ecm_rate": 12,
"emm_rate": 0
}
  • softcam_id - the softcam id.
  • status - number: 3 - connected and logged in, the only state in which the softcam serves keys; 0 - a connection or protocol error (connection failed or timed out, response timed out, response not parsed, login rejected), pushed once per attempt with softcam_id as the only other field. No other value is pushed.
  • caid - number, the CA system id reported by the server. Only with status 3.
  • ecm_rate, emm_rate - numbers, ECM and EMM messages over the last 60 seconds. Only with status 3.

An error attempt:

{
"scope": "softcam_event",
"softcam_id": "a003",
"status": 0
}

Pushed when the CPU power-save state changes, and repeated once a minute while power saving is active so an interface that connected later sees the alert. The message is not a periodic statistics feed: the values are a snapshot at the moment of the alert.

{
"scope": "sysinfo",
"system": {
"uptime": 864000,
"cpu_cores": 8,
"cpu_power_save": true,
"cpu_total_usage": 12,
"loadavg": [ 45, 40, 38 ],
"mem_total": 16318452,
"mem_available": 11201324
},
"app": {
"uptime": 3600,
"mem": 1,
"cpu_usage": 3,
"threads": 12
}
}
  • system.uptime - seconds since boot.
  • system.cpu_cores - number of CPUs.
  • system.cpu_power_save - boolean, the scaling policy holds the CPU below the clock it is capable of.
  • system.cpu_total_usage - percent.
  • system.loadavg - the 1, 5 and 15 minute load averages multiplied by 100.
  • system.mem_total, system.mem_available - KiB.
  • app.uptime - seconds since the process started.
  • app.mem - percent of total memory used by the process.
  • app.cpu_usage - percent.
  • app.threads - thread count of the process.

Pushed by the license engine when the license state changes: a license file could not be loaded, a check returned a different type, e-mail, expiry or cleared an error, or a license fault is reported.

{
"scope": "license",
"license": {
"id": "ABCDEF",
"type": 2,
"email": "user@example.com",
"expire": 1790000000,
"origin": "https://..."
}
}

Every field of license is optional and absent when unknown:

  • id - the first six characters of the serial number.
  • type - 1 demo, 2 subscription, 3 corporate, 4 lifetime.
  • email - the e-mail the license is registered to.
  • expire - Unix time; the expiration date, or the activation date for a lifetime license.
  • error_code - number, the current license fault; absent while the license is valid.
  • error_text - string, set when the license file could not be loaded.
  • origin - the license server that answered the last request.
  • offline_expire - Unix time at which the last answer stops holding while the license server is unreachable; absent while the server is reachable.