npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

threefive-scte35

v0.2.0

Published

JavaScript port of the Python threefive SCTE-35 library

Readme

threefive.js

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'

Install

npm install threefive-scte35

Or reference a local clone:

"threefive-scte35": "^0.1.1"

Usage

From base64

import { Cue } from 'threefive-scte35';

const cue = new Cue('/DAvAAAAAAAA///wFAVIAACPf+/+c2nALv4AUsz1AAAAAAAKAAhDVUVJAAABNWLbowo=');

From hex

const cue = new Cue('0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF5...');

From bytes

const cue = new Cue(new Uint8Array([0xfc, 0x30, ...]));

Inspect results

// 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[]

Serialize to plain object

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 }]
// }

API

new Cue(data?)

| 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.


cue.infoSectionSpliceInfoSection

| 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 |


cue.command — splice command instances

| 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.


cue.descriptorsSpliceDescriptor[]

| 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 |

SegmentationDescriptor segmentation types (table 22)

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.

UPID types

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.


Named exports

import {
  Cue,
  SpliceInfoSection,
  SpliceNull, SpliceInsert, TimeSignal, BandwidthReservation, PrivateCommand,
  AvailDescriptor, DtmfDescriptor, SegmentationDescriptor, TimeDescriptor,
  PrivateDescriptor, spliceDescriptor,
  Bitn,
  table20, table22, SUB_SEG_TYPES,
  decodeUpid,
} from 'threefive-scte35';

Design notes

  • Decode-only. No encoding, no XML, no CRC generation.
  • Synchronous. new Cue(data) returns immediately — no async init.
  • BigInt bit reader. Bitn stores the input as one BigInt and slices bits without alignment constraints, matching Python's arbitrary-precision integer approach.
  • Seconds throughout. ptsTime and breakDuration are divided by 90000 at parse time. No raw ticks exposed.
  • ESM only. Targets ES2020 with "type": "module".

Relationship to Python threefive

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.


License

MIT