Skip to content

Scan API

The scan methods run the MPEG-TS analyzer on any input address for a short time: scan-init starts an analyzer session, scan-check collects what it found since the previous call and keeps the session alive, scan-kill stops it. The interface uses them for the DVB scan and for the stream analyzer page. All three are served on the POST /control/ entry point with the command name in cmd and are control only; an observer receives 404. See How to call API methods for the entry points, authentication and roles. Every method answers 200 with a JSON body; a failure is reported inside the body.

A session does not touch the configuration and sends no WebSocket notification.

Request: POST /control/. Control only.

{
"cmd": "scan-init",
"scan": "udp://239.255.1.1:1234"
}
  • scan - string, required. The input address in the Media Address Format, with the usual #option&option=value suffix; the options are applied to the analyzed input as for a stream input. dvb://a002 analyzes a running adapter of the configuration by its id. Instead of a string the field may carry the parsed form: an object with format (the scheme) and addr plus the option fields; a dvb object may name the adapter in id instead of addr, then every other option of the object is dropped.

Response:

{
"scan-init": "ok",
"id": "scan-731"
}
  • id - string, the session identifier for scan-check and scan-kill: scan- followed by a random number between 100 and 999 that is not in use.

Error replies:

{ "scan-init": "er", "error": "failed to get address" }
  • failed to get address - scan is absent, or a string without ://.
  • input initialization failed - the input could not be created.

An address with an unknown scheme, or a dvb:// address whose adapter is not running, is written to the log; the session is still created and answers "ok", but delivers no entries.

Lifetime: the session is checked every 10 seconds and stopped when no scan-check arrived since the previous check, so poll at least every 10 seconds to keep it alive. A session without polling stops between 10 and 20 seconds after scan-init. The input is started for the session; a DVB adapter is shared with the streams that use it.

Request: POST /control/. Control only.

{
"cmd": "scan-check",
"id": "scan-731"
}
  • id - string, required. Session identifier.

Response:

{
"scan-check": "ok",
"scan": [
{ "psi": "pat", "pid": 0, "table_id": 0, "version": 3, "crc32": 2718450225, "tsid": 1, "programs": [ { "pnr": 1, "pid": 32 } ] },
{ "analyze": [ { "pid": 0, "packets": 10, "bitrate": 15, "cc_error": 0, "pes_error": 0, "pcr_error": 0, "sc_error": 0 } ], "total": { "bitrate": 4200, "packets": 2793, "cc_errors": 0, "pes_errors": 0, "sc_errors": 0, "pcr_errors": 0, "scrambled": false, "bitrate_limit": 38 }, "on_air": true }
]
}
  • scan - array of the entries collected since the previous scan-check, in arrival order. Absent when nothing new arrived. Each call empties the queue. An entry is either a PSI table (it has a psi field) or a status entry (it has an analyze field).

Unknown or expired identifier:

{ "scan-check": "ok", "error": "instance not found" }

The command name still carries "ok"; check the error field.

Produced once per second with the counters of that second, also while no data arrives (every counter 0, on_air false).

{
"analyze": [
{ "pid": 0, "packets": 10, "bitrate": 15, "cc_error": 0, "pes_error": 0, "pcr_error": 0, "sc_error": 0 },
{ "pid": 256, "packets": 2650, "bitrate": 3985, "cc_error": 0, "pes_error": 0, "pcr_error": 0, "sc_error": 0 },
{ "pid": 8191, "packets": 120, "bitrate": 180, "cc_error": 0, "pes_error": 0, "pcr_error": 0, "sc_error": 0 }
],
"total": {
"bitrate": 4200,
"packets": 2793,
"cc_errors": 0,
"pes_errors": 0,
"sc_errors": 0,
"pcr_errors": 0,
"scrambled": false,
"bitrate_limit": 38
},
"on_air": true
}
  • analyze - array with one row per analyzed PID: the PIDs 0, 1, 17, 18, 20 and 8191 are always present, the PMT, elementary stream and CA PIDs are added as they are learned from the tables. Fields: pid; packets counted in the second; bitrate in Kbit/s (packets * 188 * 8 / 1000); cc_error - continuity counter errors, not counted when the packet carries the discontinuity indicator; pes_error - video and audio packets whose payload start does not begin with a PES header; pcr_error - PCR values that deviate by more than 500 ns from the value extrapolated from the previous PCR interval and the packet count since the last PCR; the extrapolation assumes a constant packet rate between two PCRs, so a variable bitrate stream reports errors even when its PCR is correct; sc_error - scrambled packets, reset to 0 for a PID whose pes_error is 0. Packets of PIDs not announced by the PAT and PMTs are counted in the row of PID 8191.
  • total.bitrate, total.packets - sums over every row.
  • total.cc_errors, total.pes_errors, total.sc_errors, total.pcr_errors - sums of the row counters; total.sc_errors is summed before the per-row reset of sc_error, so it may exceed the sum of the rows.
  • total.scrambled - true when a video or audio PID has sc_error above 0.
  • total.bitrate_limit - Kbit/s, the threshold applied to the video and audio bitrate: 2 plus 32 per video PID and 4 per audio PID.
  • on_air - false when scrambled is true, when the video plus audio bitrate is below bitrate_limit, or when a video or audio PID has more than 2 PES errors in the second; true otherwise.

Produced when a table with a new checksum is seen. A PAT entry is sent whenever the PAT checksum changes; every other table type is repeated only when its checksum has not been seen for 10 seconds. Every PSI entry carries:

  • psi - string, the table name: pat, cat, pmt, nit, sdt or eit.
  • pid - number, the PID the section arrived on.
  • table_id - number.
  • version - number, the table version.
  • crc32 - number, the section checksum.

The remaining fields depend on the table.

{
"psi": "pat",
"pid": 0,
"table_id": 0,
"version": 3,
"crc32": 2718450225,
"tsid": 1,
"programs": [
{ "pnr": 0, "pid": 16 },
{ "pnr": 1, "pid": 32 }
]
}
  • tsid - transport stream identifier.
  • programs - list of the PAT items with a PID between 1 and 8190: pnr is the program number, pid the PID of its PMT. The item with pnr 0 names the NIT PID.

A new PAT resets the analyzer: the PMT, elementary stream and CA PIDs learned before are forgotten and learned again.

{
"psi": "cat",
"pid": 1,
"table_id": 1,
"version": 0,
"crc32": 1234567890,
"descriptors": [
{ "type_id": 9, "type_name": "cas", "caid": 2600, "pid": 1000 }
]
}
  • descriptors - the CAT descriptors, see Descriptors. The PID of every CA descriptor (type_id 9) is added to the analyzed PIDs.
{
"psi": "pmt",
"pid": 32,
"table_id": 2,
"version": 5,
"crc32": 3456789012,
"pnr": 1,
"pcr": 256,
"descriptors": [],
"streams": [
{
"pid": 256,
"type_id": 27,
"type_name": "VIDEO",
"descriptors": []
},
{
"pid": 257,
"type_id": 4,
"type_name": "AUDIO",
"descriptors": [
{ "type_id": 10, "type_name": "lang", "lang": "eng" }
]
}
]
}
  • pnr - program number.
  • pcr - PID that carries the PCR of the program.
  • descriptors - program level descriptors.
  • streams - elementary streams: pid; type_id - the stream type of the PMT; type_name - the class derived from type_id and the descriptors: VIDEO (0x01, 0x02, 0x10, 0x1B, 0x24), AUDIO (0x03, 0x04, 0x0F, 0x11, 0x81, 0x87, and 0x06 with an AC-3 or enhanced AC-3 descriptor), TTX (0x06 with a teletext descriptor), SUB (0x06 with a subtitling descriptor), AIT (0x05 with the application signalling descriptor 0x6F), DATA otherwise; descriptors - the stream descriptors.

Only the actual network table (table_id 64) is reported.

{
"psi": "nit",
"pid": 16,
"table_id": 64,
"version": 2,
"crc32": 4567890123,
"section_number": 0,
"last_section_number": 0,
"network_id": 1,
"descriptors": [
{ "type_id": 64, "type_name": "network_name_descriptor", "network_name": "ASTRA" }
],
"streams": [
{
"tsid": 1,
"onid": 1,
"descriptors": [
{ "type_id": 67, "type_name": "satellite_delivery_system_descriptor", "frequency": 11913, "orbital_position": "019,2E", "polarization": "H", "s2": true, "rolloff": "35", "modulation": "8PSK", "symbolrate": 27500, "fec": "3/4" }
]
}
]
}
  • section_number, last_section_number - the section counters; a multi-section NIT arrives as one entry per section.
  • network_id - network identifier.
  • descriptors - network level descriptors.
  • streams - transport streams of the network: tsid, onid (original network identifier) and their descriptors.

Only the table of the actual transport stream (table_id 66) whose tsid equals the PAT tsid is reported, so an SDT entry never precedes the PAT entry.

{
"psi": "sdt",
"pid": 17,
"table_id": 66,
"version": 1,
"crc32": 5678901234,
"section_number": 0,
"last_section_number": 0,
"tsid": 1,
"services": [
{
"sid": 1,
"descriptors": [
{ "type_id": 72, "type_name": "service", "service_type_id": 1, "service_provider": "Provider", "service_name": "Channel 1" }
]
}
]
}
  • section_number, last_section_number - the section counters.
  • tsid - transport stream identifier.
  • services - one item per service: sid (the service identifier, equal to the program number) and its descriptors.

Event information tables with a table_id from 78 (0x4E) to 111 (0x6F): present/following and schedule, actual and other transport stream.

{
"psi": "eit",
"pid": 18,
"table_id": 78,
"version": 9,
"crc32": 6789012345,
"sid": 1,
"section_number": 0,
"last_section_number": 1,
"tsid": 1,
"onid": 1,
"events": [
{
"event_id": 1001,
"start_ut": 1758240000,
"stop_ut": 1758243600,
"running_status": 4,
"ca_mode": 0,
"descriptors": [
{ "type_id": 77, "type_name": "short_event_descriptor", "lang": "eng", "event_name": "News", "text_char": "Evening news" }
]
}
]
}
  • sid - service identifier.
  • section_number, last_section_number - the section counters.
  • tsid, onid - transport stream and original network identifiers.
  • events - one item per event: event_id; start_ut and stop_ut as Unix time; running_status and ca_mode as coded in the section; descriptors.

Every descriptors item is an object with type_id (the descriptor tag) and type_name, plus the fields of the recognized tags below. Text fields are decoded to UTF-8. Language codes are three lower-case letters.

  • 9 cas - caid, pid (the ECM or EMM PID), data - the private bytes as a 0x hex string, absent when there are none.
  • 10 lang - lang.
  • 64 network_name_descriptor - network_name.
  • 67 satellite_delivery_system_descriptor - frequency (MHz), orbital_position ("019,2E": degrees with a comma decimal and E or W), polarization (H, V, L, R), s2 (boolean), rolloff (35, 25, 20, AUTO, present only when s2 is true), modulation (AUTO, QPSK, 8PSK, 16-QAM), symbolrate (kSym/s), fec (string).
  • 68 cable_delivery_system_descriptor - frequency (MHz), modulation (NONE, 16-QAM, 32-QAM, 64-QAM, 128-QAM, 256-QAM, AUTO), symbolrate (kSym/s), fec (string).
  • 72 service - service_type_id, service_provider, service_name.
  • 77 short_event_descriptor - lang, event_name, text_char.
  • 78 extended_event_descriptor - desc_num, last_desc_num, lang, items (array of { "item_desc": "...", "item": "..." }, present when the descriptor has items), text.
  • 82 stream_id - stream_id.
  • 83 caid - caid.
  • 84 content_descriptor - items, array of { "cn_l1": N, "cn_l2": N, "un_l1": N, "un_l2": N }.
  • 85 parental_rating_descriptor - items, array of { "country": "...", "rating": N }.
  • 86 teletext_descriptor - lang.
  • 89 subtitling_descriptor - lang.
  • 90 terrestrial_delivery_system_descriptor - frequency (MHz), bandwidth ("8 MHz", "7 MHz", …), priority, modulation (QPSK, 16-QAM, 64-QAM), hierarchy (0, 1, 2, 4), code_rate_hp, code_rate_lp (strings), guard_interval (1/32, 1/16, 1/8, 1/4), transmission (2k, 8k, 4k).
  • 91 multilingual_network_name_descriptor - network_name, an object keyed by language code.
  • 131 logical_channel_descriptor - lcn, array of { "pnr": N, "lcn": N }.
  • any other tag - type_name unknown, data - the whole descriptor as a 0x hex string, truncated with ... (strip) when longer than the buffer.

Request: POST /control/. Control only.

{
"cmd": "scan-kill",
"id": "scan-731"
}
  • id - string, required. Session identifier.

Response:

{ "scan-kill": "ok" }

The input is stopped and the session with its collected entries is dropped. An unknown or already expired identifier changes nothing and is still answered "ok"; a following scan-check reports instance not found.