JavaScript/TypeScript port of Python threefive — a SCTE-35 decoder for broadcast ad markers.
Decode-only. Synchronous. ESM. No dependencies.
import { Cue } from 'threefive-scte35';
const cue = new Cue('/DAvAAAAAAAA///wFAVIAACPf+/+c2nALv4AUsz1AAAAAAAKAAhDVUVJAAABNWLbowo=');
cue.command.name // 'Splice Insert'
cue.command.ptsTime // 21514.559089 (seconds)
cue.command.breakDuration // 60.293567 (seconds)
cue.descriptors[0].name // 'Avail Descriptor'npm install threefive-scte35Or reference a local clone:
"threefive-scte35": "^0.1.1"import { Cue } from 'threefive-scte35';
const cue = new Cue('/DAvAAAAAAAA///wFAVIAACPf+/+c2nALv4AUsz1AAAAAAAKAAhDVUVJAAABNWLbowo=');const cue = new Cue('0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF5...');const cue = new Cue(new Uint8Array([0xfc, 0x30, ...]));// Info section
cue.infoSection.tableId // '0xfc'
cue.infoSection.spliceCommandType // 5
cue.infoSection.ptsAdjustment // 0
cue.infoSection.crc // '0x62dba30a'
// Splice command
cue.command.name // 'Splice Insert'
cue.command.commandType // 5
cue.command.ptsTime // seconds (null if not specified)
cue.command.breakDuration // seconds (null if not a timed break)
// Descriptors
cue.descriptors // SpliceDescriptor[]const obj = cue.get();
// {
// info_section: { table_id: '0xfc', splice_command_type: 5, ... },
// command: { name: 'Splice Insert', pts_time: 21514.559089, break_duration: 60.293567, ... },
// descriptors: [{ name: 'Avail Descriptor', provider_avail_id: 309 }]
// }| Argument | Type |
|---|---|
data |
string | Uint8Array | undefined |
String inputs: hex (0xfc30... or fc30...) or base64. Uint8Array is passed directly. Passing nothing creates an empty instance.
The constructor calls decode() automatically.
| Property | Type | Notes |
|---|---|---|
tableId |
string | null |
Always '0xfc' |
sectionLength |
number | null |
|
protocolVersion |
number | null |
|
encryptedPacket |
boolean | null |
|
ptsAdjustment |
number |
Seconds (90kHz converted) |
spliceCommandType |
number | null |
|
spliceCommandLength |
number | null |
|
descriptorLoopLength |
number |
|
crc |
string | null |
Stored, not verified |
| Class | commandType |
Key fields |
|---|---|---|
SpliceNull |
0 |
— |
SpliceInsert |
5 |
spliceEventId, ptsTime, breakDuration, breakAutoReturn, outOfNetworkIndicator, uniqueProgramId, availNum, availsExpected |
TimeSignal |
6 |
ptsTime, timeSpecifiedFlag |
BandwidthReservation |
7 |
— |
PrivateCommand |
255 |
identifier, privateBytes |
ptsTime and breakDuration are in seconds (already divided by 90000). null when not present.
| Class | tag |
Key fields |
|---|---|---|
AvailDescriptor |
0 |
providerAvailId |
DtmfDescriptor |
1 |
preroll, dtmfCount, dtmfChars |
SegmentationDescriptor |
2 |
segmentationEventId, segmentationTypeId, segmentationMessage, segmentationDuration, segmentationUpid, segmentNum, segmentsExpected |
TimeDescriptor |
3 |
taiSeconds, taiNs, utcOffset |
PrivateDescriptor |
any other | privateData |
Common values:
segmentationTypeId |
segmentationMessage |
|---|---|
0x10 |
Program Start |
0x11 |
Program End |
0x20 |
Chapter Start |
0x21 |
Chapter End |
0x22 |
Break Start |
0x23 |
Break End |
0x30 |
Provider Advertisement Start |
0x31 |
Provider Advertisement End |
0x34 |
Provider Placement Opportunity Start |
0x35 |
Provider Placement Opportunity End |
0x36 |
Distributor Placement Opportunity Start |
0x37 |
Distributor Placement Opportunity End |
Full table in src/segmentation.ts.
segmentationUpid is a UpidResult:
{
upidType: 8,
upidTypeName: 'AiringID',
upidLength: 8,
upidValue: '0x2ca0a18a'
}Supported: No UPID, AdID, UMID, ISAN, TID, AiringID, ADI, EIDR, ATSC, MPU, MID, ADS Info, URI, UUID, SCR.
import {
Cue,
SpliceInfoSection,
SpliceNull, SpliceInsert, TimeSignal, BandwidthReservation, PrivateCommand,
AvailDescriptor, DtmfDescriptor, SegmentationDescriptor, TimeDescriptor,
PrivateDescriptor, spliceDescriptor,
Bitn,
table20, table22, SUB_SEG_TYPES,
decodeUpid,
} from 'threefive-scte35';- Decode-only. No encoding, no XML, no CRC generation.
- Synchronous.
new Cue(data)returns immediately — no async init. - BigInt bit reader.
Bitnstores the input as one BigInt and slices bits without alignment constraints, matching Python's arbitrary-precision integer approach. - Seconds throughout.
ptsTimeandbreakDurationare divided by 90000 at parse time. No raw ticks exposed. - ESM only. Targets
ES2020with"type": "module".
This is a port of the decode path from superkabuki/threefive_is_scte35. Field names and class structure follow the Python library closely so output is comparable. The test suite cross-checks all parsed values against Python cue.show() output.
Not ported: encoding, XML output, CRC computation, HLS/DASH playlist parsing, network fetching.
MIT