0
# Transport Stream Processing
1
2
Comprehensive MPEG-2 Transport Stream support including packet parsing, PES (Packetized Elementary Stream) reconstruction, caption extraction, metadata processing, and timestamp handling for HLS and DASH streaming workflows.
3
4
## Capabilities
5
6
### Transport Stream Packet Processing
7
8
Core classes for parsing and processing MPEG-2 Transport Stream packets at the lowest level.
9
10
```javascript { .api }
11
/**
12
* Splits incoming binary data into MPEG-2 Transport Stream packets
13
*/
14
class TransportPacketStream extends Stream {
15
constructor();
16
17
/** Process TS bytes and emit individual packets */
18
push(bytes: Uint8Array): void;
19
20
/** Flush remaining packet data */
21
flush(): void;
22
23
/** End timeline processing */
24
endTimeline(): void;
25
26
/** Reset packet parser state */
27
reset(): void;
28
}
29
30
/**
31
* Parses TS packet headers and payload data
32
*/
33
class TransportParseStream extends Stream {
34
constructor();
35
36
/** Process TS packet and extract payload */
37
push(packet: TSPacket): void;
38
39
/** Process PES data from packet payload */
40
processPes_(packet: TSPacket, offset: number, result: ParseResult): void;
41
}
42
43
/**
44
* Reconstructs elementary streams from parsed TS data
45
*/
46
class ElementaryStream extends Stream {
47
constructor();
48
49
/** Process parsed TS data and reconstruct streams */
50
push(data: ParsedTSData): void;
51
52
/** Reset all elementary streams */
53
reset(): void;
54
55
/** Flush all elementary streams */
56
flush(): void;
57
58
/** Internal flush method for all streams */
59
flushStreams_(): void;
60
}
61
62
interface TSPacket {
63
pid: number;
64
payloadUnitStartIndicator: boolean;
65
adaptationFieldControl: number;
66
payload: Uint8Array;
67
timestamp?: number;
68
}
69
70
interface ParseResult {
71
audio: AudioPES[];
72
video: VideoPES[];
73
metadata: MetadataPES[];
74
captions: CaptionPES[];
75
}
76
77
interface ParsedTSData {
78
type: 'audio' | 'video' | 'metadata' | 'captions';
79
pid: number;
80
data: Uint8Array;
81
pts?: number;
82
dts?: number;
83
}
84
```
85
86
**Usage Example:**
87
88
```javascript
89
const muxjs = require("mux.js");
90
91
// Create TS processing pipeline
92
const transportPacketStream = new muxjs.mp2t.TransportPacketStream();
93
const transportParseStream = new muxjs.mp2t.TransportParseStream();
94
const elementaryStream = new muxjs.mp2t.ElementaryStream();
95
96
// Connect pipeline
97
transportPacketStream.pipe(transportParseStream);
98
transportParseStream.pipe(elementaryStream);
99
100
// Handle reconstructed elementary streams
101
elementaryStream.on('data', function(stream) {
102
console.log('Elementary stream:', stream.type, 'PID:', stream.pid);
103
if (stream.pts) {
104
console.log('PTS:', stream.pts);
105
}
106
});
107
108
// Process transport stream data
109
transportPacketStream.push(tsBytes);
110
transportPacketStream.flush();
111
```
112
113
### Caption Stream Processing
114
115
Specialized processing for extracting and parsing caption data from transport streams.
116
117
```javascript { .api }
118
/**
119
* Extracts caption data from transport stream
120
*/
121
class CaptionStream extends Stream {
122
constructor();
123
124
/** Process caption data from TS */
125
push(data: CaptionData): void;
126
127
/** Flush caption processing */
128
flush(): void;
129
130
/** Reset caption parser */
131
reset(): void;
132
}
133
134
/**
135
* CEA-608 closed caption processing
136
*/
137
class Cea608Stream extends Stream {
138
constructor();
139
140
/** Process CEA-608 caption packets */
141
push(data: Cea608Data): void;
142
143
/** Flush CEA-608 processing */
144
flush(): void;
145
}
146
147
/**
148
* CEA-708 closed caption processing
149
*/
150
class Cea708Stream extends Stream {
151
constructor();
152
153
/** Process CEA-708 caption packets */
154
push(data: Cea708Data): void;
155
156
/** Flush CEA-708 processing */
157
flush(): void;
158
}
159
160
interface CaptionData {
161
pts: number;
162
dts?: number;
163
data: Uint8Array;
164
stream?: number;
165
}
166
167
interface Cea608Data extends CaptionData {
168
field: number;
169
line21: Uint8Array;
170
}
171
172
interface Cea708Data extends CaptionData {
173
serviceNumber: number;
174
ccData: Uint8Array;
175
}
176
```
177
178
**Usage Example:**
179
180
```javascript
181
const muxjs = require("mux.js");
182
183
const captionStream = new muxjs.mp2t.CaptionStream();
184
const cea608Stream = new muxjs.mp2t.Cea608Stream();
185
186
// Handle extracted captions
187
captionStream.on('data', function(captions) {
188
captions.forEach(caption => {
189
console.log('Caption PTS:', caption.pts);
190
console.log('Caption text:', caption.text);
191
});
192
});
193
194
// Handle CEA-608 captions specifically
195
cea608Stream.on('data', function(cea608) {
196
console.log('CEA-608 caption:', cea608.text);
197
console.log('Field:', cea608.field);
198
});
199
```
200
201
### Metadata Stream Processing
202
203
Processing of timed ID3 metadata embedded in transport streams.
204
205
```javascript { .api }
206
/**
207
* Processes timed ID3 metadata from transport streams
208
*/
209
class MetadataStream extends Stream {
210
constructor();
211
212
/** Process metadata packets */
213
push(data: MetadataPacket): void;
214
215
/** Flush metadata processing */
216
flush(): void;
217
218
/** Reset metadata parser */
219
reset(): void;
220
}
221
222
interface MetadataPacket {
223
pts: number;
224
dts?: number;
225
data: Uint8Array;
226
pid: number;
227
}
228
229
interface ProcessedMetadata {
230
pts: number;
231
id3: ID3Frame[];
232
cueOut?: CuePoint;
233
cueIn?: CuePoint;
234
}
235
236
interface ID3Frame {
237
id: string;
238
data: Uint8Array;
239
text?: string;
240
}
241
242
interface CuePoint {
243
pts: number;
244
duration?: number;
245
data?: any;
246
}
247
```
248
249
**Usage Example:**
250
251
```javascript
252
const muxjs = require("mux.js");
253
254
const metadataStream = new muxjs.mp2t.MetadataStream();
255
256
metadataStream.on('data', function(metadata) {
257
console.log('Metadata PTS:', metadata.pts);
258
259
if (metadata.id3) {
260
metadata.id3.forEach(frame => {
261
console.log('ID3 frame:', frame.id, frame.text || 'binary data');
262
});
263
}
264
265
if (metadata.cueOut) {
266
console.log('Ad break start:', metadata.cueOut);
267
}
268
269
if (metadata.cueIn) {
270
console.log('Ad break end:', metadata.cueIn);
271
}
272
});
273
```
274
275
### Timestamp Rollover Handling
276
277
Specialized stream for handling timestamp rollover in transport streams where timestamps exceed maximum values.
278
279
```javascript { .api }
280
/**
281
* Handles timestamp rollover in transport streams
282
*/
283
class TimestampRolloverStream extends Stream {
284
constructor();
285
286
/** Process data with timestamp rollover correction */
287
push(data: TimestampedData): void;
288
289
/** Flush with rollover handling */
290
flush(): void;
291
292
/** Reset rollover tracking */
293
reset(): void;
294
295
/** Set discontinuity for timestamp reset */
296
discontinuity(): void;
297
}
298
299
interface TimestampedData {
300
type: 'audio' | 'video' | 'metadata' | 'captions';
301
pts?: number;
302
dts?: number;
303
data: Uint8Array;
304
}
305
```
306
307
## Advanced Usage
308
309
### Complete Transport Stream Pipeline
310
311
```javascript
312
const muxjs = require("mux.js");
313
314
// Create complete TS processing pipeline
315
const transportPacketStream = new muxjs.mp2t.TransportPacketStream();
316
const transportParseStream = new muxjs.mp2t.TransportParseStream();
317
const elementaryStream = new muxjs.mp2t.ElementaryStream();
318
const timestampRolloverStream = new muxjs.mp2t.TimestampRolloverStream();
319
const captionStream = new muxjs.mp2t.CaptionStream();
320
const metadataStream = new muxjs.mp2t.MetadataStream();
321
322
// Connect main pipeline
323
transportPacketStream.pipe(transportParseStream);
324
transportParseStream.pipe(elementaryStream);
325
elementaryStream.pipe(timestampRolloverStream);
326
327
// Handle different stream types
328
timestampRolloverStream.on('data', function(stream) {
329
switch (stream.type) {
330
case 'audio':
331
console.log('Audio stream - PTS:', stream.pts, 'Size:', stream.data.length);
332
break;
333
case 'video':
334
console.log('Video stream - PTS:', stream.pts, 'DTS:', stream.dts);
335
break;
336
case 'captions':
337
captionStream.push(stream);
338
break;
339
case 'metadata':
340
metadataStream.push(stream);
341
break;
342
}
343
});
344
345
// Handle extracted content
346
captionStream.on('data', function(captions) {
347
console.log('Extracted captions:', captions.length);
348
});
349
350
metadataStream.on('data', function(metadata) {
351
console.log('Extracted metadata at PTS:', metadata.pts);
352
});
353
354
// Process transport stream
355
transportPacketStream.push(tsData);
356
transportPacketStream.flush();
357
```
358
359
### Program Map Table (PMT) Handling
360
361
```javascript
362
// Handle PMT updates for dynamic stream configuration
363
transportParseStream.on('data', function(result) {
364
if (result.pmt) {
365
console.log('PMT Update:');
366
console.log(' Program ID:', result.pmt.programId);
367
console.log(' PCR PID:', result.pmt.pcrPid);
368
369
result.pmt.streams.forEach(stream => {
370
console.log(` Stream PID ${stream.pid}: type ${stream.streamType}`);
371
});
372
}
373
});
374
```
375
376
### Discontinuity Handling
377
378
```javascript
379
// Handle discontinuities in transport streams
380
const timestampRolloverStream = new muxjs.mp2t.TimestampRolloverStream();
381
382
// Signal discontinuity (e.g., when switching between segments)
383
timestampRolloverStream.discontinuity();
384
385
// Continue processing with corrected timestamps
386
timestampRolloverStream.on('data', function(stream) {
387
// Timestamps are now corrected for discontinuities
388
console.log('Corrected PTS:', stream.pts);
389
});
390
```
391
392
## Constants and Stream Types
393
394
### Stream Type Constants
395
396
```javascript { .api }
397
/** MPEG-2 transport stream type constants */
398
const H264_STREAM_TYPE = 0x1b;
399
const ADTS_STREAM_TYPE = 0x0f;
400
const METADATA_STREAM_TYPE = 0x15;
401
402
/** Transport stream constants */
403
const MP2T_PACKET_LENGTH = 188; // bytes
404
const SYNC_BYTE = 0x47;
405
const PAT_PID = 0x0000;
406
const CAT_PID = 0x0001;
407
const TSDT_PID = 0x0002;
408
const NULL_PID = 0x1fff;
409
```
410
411
### Caption Types
412
413
```javascript { .api }
414
/** Caption service types */
415
const CAPTION_SERVICES = {
416
CC1: 1,
417
CC2: 2,
418
CC3: 3,
419
CC4: 4,
420
T1: 5,
421
T2: 6,
422
T3: 7,
423
T4: 8
424
};
425
```
426
427
## Error Handling
428
429
Transport stream processing emits comprehensive error and warning events:
430
431
```javascript
432
const elementaryStream = new muxjs.mp2t.ElementaryStream();
433
434
elementaryStream.on('error', function(error) {
435
console.error('TS processing error:', error.message);
436
// Common errors: invalid sync bytes, corrupted packets, unknown stream types
437
});
438
439
elementaryStream.on('warning', function(warning) {
440
console.warn('TS processing warning:', warning.message);
441
// Common warnings: timestamp discontinuities, missing PMT, adaptation field issues
442
});
443
444
// Handle caption-specific errors
445
const captionStream = new muxjs.mp2t.CaptionStream();
446
447
captionStream.on('error', function(error) {
448
console.error('Caption processing error:', error.message);
449
// Common errors: invalid CEA data, unsupported caption types
450
});
451
```