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.
Start analyzer
Section titled “Start analyzer”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=valuesuffix; the options are applied to the analyzed input as for a stream input.dvb://a002analyzes a running adapter of the configuration by itsid. Instead of a string the field may carry the parsed form: an object withformat(the scheme) andaddrplus the option fields; advbobject may name the adapter inidinstead ofaddr, then every other option of the object is dropped.
Response:
{ "scan-init": "ok", "id": "scan-731"}id- string, the session identifier forscan-checkandscan-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-scanis 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.
Poll analyzer
Section titled “Poll analyzer”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 previousscan-check, in arrival order. Absent when nothing new arrived. Each call empties the queue. An entry is either a PSI table (it has apsifield) or a status entry (it has ananalyzefield).
Unknown or expired identifier:
{ "scan-check": "ok", "error": "instance not found" }The command name still carries "ok"; check the error field.
Status entry
Section titled “Status entry”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 PIDs0,1,17,18,20and8191are always present, the PMT, elementary stream and CA PIDs are added as they are learned from the tables. Fields:pid;packetscounted in the second;bitratein 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 to0for a PID whosepes_erroris0. Packets of PIDs not announced by the PAT and PMTs are counted in the row of PID8191.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_errorsis summed before the per-row reset ofsc_error, so it may exceed the sum of the rows.total.scrambled-truewhen a video or audio PID hassc_errorabove0.total.bitrate_limit- Kbit/s, the threshold applied to the video and audio bitrate:2plus32per video PID and4per audio PID.on_air-falsewhenscrambledistrue, when the video plus audio bitrate is belowbitrate_limit, or when a video or audio PID has more than2PES errors in the second;trueotherwise.
PSI entries
Section titled “PSI entries”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,sdtoreit.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 between1and8190:pnris the program number,pidthe PID of its PMT. The item withpnr0names 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_id9) 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 fromtype_idand the descriptors:VIDEO(0x01,0x02,0x10,0x1B,0x24),AUDIO(0x03,0x04,0x0F,0x11,0x81,0x87, and0x06with an AC-3 or enhanced AC-3 descriptor),TTX(0x06with a teletext descriptor),SUB(0x06with a subtitling descriptor),AIT(0x05with the application signalling descriptor0x6F),DATAotherwise;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 theirdescriptors.
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 itsdescriptors.
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_utandstop_utas Unix time;running_statusandca_modeas coded in the section;descriptors.
Descriptors
Section titled “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.
9cas-caid,pid(the ECM or EMM PID),data- the private bytes as a0xhex string, absent when there are none.10lang-lang.64network_name_descriptor-network_name.67satellite_delivery_system_descriptor-frequency(MHz),orbital_position("019,2E": degrees with a comma decimal andEorW),polarization(H,V,L,R),s2(boolean),rolloff(35,25,20,AUTO, present only whens2istrue),modulation(AUTO,QPSK,8PSK,16-QAM),symbolrate(kSym/s),fec(string).68cable_delivery_system_descriptor-frequency(MHz),modulation(NONE,16-QAM,32-QAM,64-QAM,128-QAM,256-QAM,AUTO),symbolrate(kSym/s),fec(string).72service-service_type_id,service_provider,service_name.77short_event_descriptor-lang,event_name,text_char.78extended_event_descriptor-desc_num,last_desc_num,lang,items(array of{ "item_desc": "...", "item": "..." }, present when the descriptor has items),text.82stream_id-stream_id.83caid-caid.84content_descriptor-items, array of{ "cn_l1": N, "cn_l2": N, "un_l1": N, "un_l2": N }.85parental_rating_descriptor-items, array of{ "country": "...", "rating": N }.86teletext_descriptor-lang.89subtitling_descriptor-lang.90terrestrial_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).91multilingual_network_name_descriptor-network_name, an object keyed by language code.131logical_channel_descriptor-lcn, array of{ "pnr": N, "lcn": N }.- any other tag -
type_nameunknown,data- the whole descriptor as a0xhex string, truncated with... (strip)when longer than the buffer.
Stop analyzer
Section titled “Stop analyzer”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.