0
# Tools and Inspection
1
2
Debugging and analysis tools for MP4, FLV, and transport stream containers with detailed structure parsing, text output, and comprehensive metadata extraction for troubleshooting streaming issues.
3
4
## Capabilities
5
6
### MP4 Inspection Tools
7
8
Comprehensive MP4 analysis tools for debugging container structure and understanding media data organization.
9
10
```javascript { .api }
11
/**
12
* Parse and analyze MP4 container structure
13
* @param bytes - MP4 binary data
14
* @returns Parsed MP4 structure object
15
*/
16
function inspectMp4(bytes: Uint8Array): MP4Structure;
17
18
/**
19
* Convert parsed MP4 structure to human-readable text
20
* @param json - Parsed MP4 structure from inspectMp4
21
* @param depth - Indentation depth for nested boxes (default: 0)
22
* @returns Formatted text representation
23
*/
24
function textifyMp4(json: MP4Structure, depth?: number): string;
25
26
interface MP4Structure {
27
type: string;
28
size: number;
29
offset: number;
30
boxes?: MP4Structure[];
31
data?: any;
32
}
33
```
34
35
**Usage Example:**
36
37
```javascript
38
const muxjs = require("mux.js");
39
40
// Analyze MP4 file structure
41
const mp4Data = new Uint8Array(/* MP4 file data */);
42
const structure = muxjs.mp4.tools.inspectMp4(mp4Data);
43
44
console.log('MP4 Structure:');
45
console.log(muxjs.mp4.tools.textifyMp4(structure));
46
47
// Find specific boxes
48
structure.boxes.forEach(box => {
49
if (box.type === 'moov') {
50
console.log('Found moov box at offset:', box.offset);
51
console.log('moov box size:', box.size);
52
53
// Examine tracks within moov
54
box.boxes.forEach(subBox => {
55
if (subBox.type === 'trak') {
56
console.log(' Track found:', subBox);
57
}
58
});
59
}
60
});
61
```
62
63
### Transport Stream Inspection Tools
64
65
Detailed analysis tools for MPEG-2 Transport Stream debugging and structure examination.
66
67
```javascript { .api }
68
/**
69
* Analyze MPEG-2 Transport Stream structure
70
* @param bytes - TS binary data
71
* @param pmt - Program Map Table data (optional)
72
* @returns Analysis results with packet and stream information
73
*/
74
function inspect(bytes: Uint8Array, pmt?: PMTData): TSAnalysis;
75
76
/**
77
* Parse audio PES packets from transport stream
78
* @param bytes - TS binary data containing audio
79
* @param pmt - Program Map Table for stream identification
80
* @returns Parsed audio PES information
81
*/
82
function parseAudioPes(bytes: Uint8Array, pmt: PMTData): AudioPESInfo[];
83
84
/**
85
* Parse video PES packets from transport stream
86
* @param bytes - TS binary data containing video
87
* @param pmt - Program Map Table for stream identification
88
* @returns Parsed video PES information
89
*/
90
function parseVideoPes(bytes: Uint8Array, pmt: PMTData): VideoPESInfo[];
91
92
interface TSAnalysis {
93
packetCount: number;
94
syncByteErrors: number;
95
continuityErrors: number;
96
programs: ProgramInfo[];
97
streams: StreamInfo[];
98
timing: TimingInfo;
99
}
100
101
interface ProgramInfo {
102
programId: number;
103
pcrPid: number;
104
streamCount: number;
105
}
106
107
interface StreamInfo {
108
pid: number;
109
streamType: number;
110
codecName: string;
111
packetCount: number;
112
payloadBytes: number;
113
}
114
115
interface TimingInfo {
116
firstPCR?: number;
117
lastPCR?: number;
118
firstPTS?: number;
119
lastPTS?: number;
120
duration?: number;
121
}
122
123
interface AudioPESInfo {
124
pts: number;
125
dts?: number;
126
payloadSize: number;
127
streamId: number;
128
codecInfo?: AudioCodecInfo;
129
}
130
131
interface VideoPESInfo {
132
pts: number;
133
dts?: number;
134
payloadSize: number;
135
streamId: number;
136
frameType?: 'I' | 'P' | 'B';
137
codecInfo?: VideoCodecInfo;
138
}
139
```
140
141
**Usage Example:**
142
143
```javascript
144
const muxjs = require("mux.js");
145
146
// Analyze transport stream
147
const tsData = new Uint8Array(/* TS file data */);
148
const analysis = muxjs.mp2t.tools.inspect(tsData);
149
150
console.log('Transport Stream Analysis:');
151
console.log('Total packets:', analysis.packetCount);
152
console.log('Sync byte errors:', analysis.syncByteErrors);
153
console.log('Continuity errors:', analysis.continuityErrors);
154
155
console.log('\nPrograms:');
156
analysis.programs.forEach(program => {
157
console.log(` Program ${program.programId}: PCR PID ${program.pcrPid}, ${program.streamCount} streams`);
158
});
159
160
console.log('\nStreams:');
161
analysis.streams.forEach(stream => {
162
console.log(` PID ${stream.pid}: ${stream.codecName} (${stream.packetCount} packets, ${stream.payloadBytes} bytes)`);
163
});
164
165
if (analysis.timing.duration) {
166
console.log('\nTiming:');
167
console.log('Duration:', analysis.timing.duration, 'seconds');
168
}
169
```
170
171
### FLV Inspection Tools
172
173
Analysis tools for FLV container structure and content examination.
174
175
```javascript { .api }
176
/**
177
* Parse and analyze FLV container structure
178
* @param bytes - FLV binary data
179
* @returns Parsed FLV structure and metadata
180
*/
181
function inspect(bytes: Uint8Array): FLVStructure;
182
183
interface FLVStructure {
184
header: FLVHeader;
185
tags: FLVTagInfo[];
186
metadata?: FLVMetadata;
187
summary: FLVSummary;
188
}
189
190
interface FLVHeader {
191
signature: string;
192
version: number;
193
hasAudio: boolean;
194
hasVideo: boolean;
195
dataOffset: number;
196
}
197
198
interface FLVTagInfo {
199
type: 'audio' | 'video' | 'script';
200
timestamp: number;
201
dataSize: number;
202
streamId: number;
203
offset: number;
204
codecInfo?: any;
205
}
206
207
interface FLVSummary {
208
duration?: number;
209
audioTags: number;
210
videoTags: number;
211
scriptTags: number;
212
totalSize: number;
213
}
214
```
215
216
**Usage Example:**
217
218
```javascript
219
const muxjs = require("mux.js");
220
221
// Analyze FLV file
222
const flvData = new Uint8Array(/* FLV file data */);
223
const structure = muxjs.flv.tools.inspect(flvData);
224
225
console.log('FLV Analysis:');
226
console.log('Version:', structure.header.version);
227
console.log('Has audio:', structure.header.hasAudio);
228
console.log('Has video:', structure.header.hasVideo);
229
230
console.log('\nSummary:');
231
console.log('Audio tags:', structure.summary.audioTags);
232
console.log('Video tags:', structure.summary.videoTags);
233
console.log('Script tags:', structure.summary.scriptTags);
234
235
if (structure.metadata) {
236
console.log('\nMetadata:');
237
console.log('Duration:', structure.metadata.duration);
238
console.log('Dimensions:', structure.metadata.width, 'x', structure.metadata.height);
239
}
240
```
241
242
### Specialized Parsing Tools
243
244
Additional parsing utilities for specific MP4 boxes and data structures.
245
246
```javascript { .api }
247
/**
248
* Parse ID3 metadata frames
249
* @param data - ID3 frame data
250
* @returns Parsed ID3 frame information
251
*/
252
function parseId3(data: Uint8Array): ID3Frame[];
253
254
/**
255
* Parse Track Fragment Decode Time (TFDT) box
256
* @param data - TFDT box data
257
* @returns Parsed decode time information
258
*/
259
function parseTfdt(data: Uint8Array): TfdtInfo;
260
261
/**
262
* Parse Track Fragment Header (TFHD) box
263
* @param data - TFHD box data
264
* @returns Parsed fragment header information
265
*/
266
function parseTfhd(data: Uint8Array): TfhdInfo;
267
268
/**
269
* Parse Track Run (TRUN) box
270
* @param data - TRUN box data
271
* @returns Parsed track run information
272
*/
273
function parseTrun(data: Uint8Array): TrunInfo;
274
275
/**
276
* Parse Segment Index (SIDX) box
277
* @param data - SIDX box data
278
* @returns Parsed segment index information
279
*/
280
function parseSidx(data: Uint8Array): SidxInfo;
281
282
/**
283
* Parse sample flags from MP4 data
284
* @param flags - Sample flags value
285
* @returns Decoded flag information
286
*/
287
function parseSampleFlags(flags: number): SampleFlags;
288
289
interface ID3Frame {
290
id: string;
291
size: number;
292
flags: number;
293
data: Uint8Array;
294
text?: string;
295
}
296
297
interface TfdtInfo {
298
version: number;
299
baseMediaDecodeTime: number;
300
}
301
302
interface TfhdInfo {
303
version: number;
304
flags: number;
305
trackId: number;
306
baseDataOffset?: number;
307
sampleDescriptionIndex?: number;
308
defaultSampleDuration?: number;
309
defaultSampleSize?: number;
310
defaultSampleFlags?: number;
311
}
312
313
interface TrunInfo {
314
version: number;
315
flags: number;
316
sampleCount: number;
317
dataOffset?: number;
318
firstSampleFlags?: number;
319
samples: SampleInfo[];
320
}
321
322
interface SampleInfo {
323
duration?: number;
324
size?: number;
325
flags?: number;
326
compositionTimeOffset?: number;
327
}
328
329
interface SampleFlags {
330
isLeading: number;
331
dependsOn: number;
332
isDependedOn: number;
333
hasRedundancy: number;
334
paddingValue: number;
335
isNonSyncSample: boolean;
336
degradationPriority: number;
337
}
338
```
339
340
## Advanced Usage
341
342
### Comprehensive Media Analysis
343
344
```javascript
345
const muxjs = require("mux.js");
346
347
function analyzeMediaFile(fileData, fileType) {
348
switch (fileType) {
349
case 'mp4':
350
const mp4Structure = muxjs.mp4.tools.inspectMp4(fileData);
351
console.log('=== MP4 Analysis ===');
352
console.log(muxjs.mp4.tools.textifyMp4(mp4Structure));
353
354
// Find and analyze TRUN boxes for detailed sample information
355
findBoxesByType(mp4Structure, 'trun').forEach(trunBox => {
356
const trunInfo = muxjs.mp4.tools.parseTrun(trunBox.data);
357
console.log('Track run samples:', trunInfo.sampleCount);
358
console.log('Data offset:', trunInfo.dataOffset);
359
});
360
break;
361
362
case 'ts':
363
const tsAnalysis = muxjs.mp2t.tools.inspect(fileData);
364
console.log('=== Transport Stream Analysis ===');
365
366
// Detailed stream analysis
367
tsAnalysis.streams.forEach(stream => {
368
console.log(`Stream PID ${stream.pid}:`);
369
console.log(` Codec: ${stream.codecName}`);
370
console.log(` Packets: ${stream.packetCount}`);
371
console.log(` Payload: ${stream.payloadBytes} bytes`);
372
});
373
374
// Parse PES data if PMT is available
375
if (tsAnalysis.programs.length > 0) {
376
const audioStreams = muxjs.mp2t.tools.parseAudioPes(fileData, tsAnalysis.pmt);
377
const videoStreams = muxjs.mp2t.tools.parseVideoPes(fileData, tsAnalysis.pmt);
378
379
console.log('Audio PES packets:', audioStreams.length);
380
console.log('Video PES packets:', videoStreams.length);
381
}
382
break;
383
384
case 'flv':
385
const flvStructure = muxjs.flv.tools.inspect(fileData);
386
console.log('=== FLV Analysis ===');
387
console.log('Total tags:', flvStructure.tags.length);
388
389
// Analyze tag distribution over time
390
const tagTimeline = flvStructure.tags.map(tag => ({
391
type: tag.type,
392
timestamp: tag.timestamp,
393
size: tag.dataSize
394
}));
395
396
console.log('Tag timeline:', tagTimeline.slice(0, 10)); // First 10 tags
397
break;
398
}
399
}
400
401
function findBoxesByType(structure, targetType) {
402
const results = [];
403
404
function search(box) {
405
if (box.type === targetType) {
406
results.push(box);
407
}
408
if (box.boxes) {
409
box.boxes.forEach(search);
410
}
411
}
412
413
search(structure);
414
return results;
415
}
416
```
417
418
### Timing Analysis Tools
419
420
```javascript
421
// Analyze timing relationships across different formats
422
function analyzeTimingConsistency(mp4Data, tsData) {
423
// Analyze MP4 timing
424
const mp4Structure = muxjs.mp4.tools.inspectMp4(mp4Data);
425
const tfdtBoxes = findBoxesByType(mp4Structure, 'tfdt');
426
427
const mp4Timing = tfdtBoxes.map(box => {
428
const tfdt = muxjs.mp4.tools.parseTfdt(box.data);
429
return tfdt.baseMediaDecodeTime;
430
});
431
432
// Analyze TS timing
433
const tsAnalysis = muxjs.mp2t.tools.inspect(tsData);
434
435
console.log('MP4 decode times:', mp4Timing);
436
console.log('TS timing info:', tsAnalysis.timing);
437
438
// Compare timing consistency
439
if (tsAnalysis.timing.duration && mp4Timing.length > 0) {
440
const tsDuration = tsAnalysis.timing.duration;
441
const mp4Duration = (mp4Timing[mp4Timing.length - 1] - mp4Timing[0]) / 90000; // Convert to seconds
442
443
console.log('Duration comparison:');
444
console.log(' TS duration:', tsDuration, 'seconds');
445
console.log(' MP4 duration:', mp4Duration, 'seconds');
446
console.log(' Difference:', Math.abs(tsDuration - mp4Duration), 'seconds');
447
}
448
}
449
```
450
451
### Caption Packet Analysis
452
453
```javascript
454
const muxjs = require("mux.js");
455
456
function analyzeCaptionData(captionData) {
457
const parser = muxjs.mp4.tools.captionPacketParser;
458
459
try {
460
const parsedCaptions = parser.parse(captionData);
461
462
console.log('Caption Analysis:');
463
console.log('Total caption packets:', parsedCaptions.length);
464
465
parsedCaptions.forEach((caption, index) => {
466
console.log(`Caption ${index + 1}:`);
467
console.log(' PTS:', caption.pts);
468
console.log(' Type:', caption.type);
469
console.log(' Text:', caption.text || 'No text data');
470
});
471
472
} catch (error) {
473
console.error('Caption parsing failed:', error.message);
474
}
475
}
476
```
477
478
## Error Handling
479
480
Tools provide detailed error information for debugging container issues:
481
482
```javascript
483
const muxjs = require("mux.js");
484
485
try {
486
const mp4Structure = muxjs.mp4.tools.inspectMp4(corruptedMp4Data);
487
console.log(muxjs.mp4.tools.textifyMp4(mp4Structure));
488
} catch (error) {
489
console.error('MP4 inspection failed:', error.message);
490
// Common errors: invalid box sizes, corrupted headers, truncated data
491
}
492
493
try {
494
const tsAnalysis = muxjs.mp2t.tools.inspect(corruptedTsData);
495
} catch (error) {
496
console.error('TS inspection failed:', error.message);
497
// Common errors: sync byte misalignment, invalid packet structure
498
}
499
```