or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

captions.mdcodecs.mdflv.mdindex.mdmp2t.mdmp4.mdpartial.mdtools.md

tools.mddocs/

0

# Debug and Inspection Tools

1

2

Comprehensive debugging utilities for MP4, FLV, and transport stream inspection. These tools are essential for troubleshooting streaming issues, understanding media structure, and debugging transmuxing problems.

3

4

## Capabilities

5

6

### MP4 Inspection Tools

7

8

Complete MP4 debugging and analysis utilities for understanding MP4 box structure and content.

9

10

```javascript { .api }

11

/**

12

* MP4 inspection and debugging tools

13

*/

14

const mp4Tools: {

15

/** Inspect MP4 structure and parse all boxes */

16

inspect(data: Uint8Array): MP4Structure;

17

18

/** Convert MP4 structure to human-readable text representation */

19

textify(structure: MP4Structure): string;

20

21

/** Parse MP4 box type from binary data */

22

parseType(data: Uint8Array): string;

23

24

/** Find specific box type in MP4 data */

25

findBox(data: Uint8Array, boxType: string): Uint8Array | null;

26

27

/** Parse track fragment (traf) box */

28

parseTraf(data: Uint8Array): TrafBox;

29

30

/** Parse track fragment decode time (tfdt) box */

31

parseTfdt(data: Uint8Array): TfdtBox;

32

33

/** Parse handler (hdlr) box */

34

parseHdlr(data: Uint8Array): HdlrBox;

35

36

/** Parse track fragment header (tfhd) box */

37

parseTfhd(data: Uint8Array): TfhdBox;

38

39

/** Parse track run (trun) box */

40

parseTrun(data: Uint8Array): TrunBox;

41

42

/** Parse segment index (sidx) box */

43

parseSidx(data: Uint8Array): SidxBox;

44

45

/** Parse sample flags from trun box */

46

parseSampleFlags(flags: number): SampleFlags;

47

};

48

49

interface MP4Structure {

50

boxes: MP4Box[];

51

totalSize: number;

52

}

53

54

interface MP4Box {

55

type: string;

56

size: number;

57

offset: number;

58

data: Uint8Array;

59

children?: MP4Box[];

60

}

61

```

62

63

**Usage Examples:**

64

65

```javascript

66

const muxjs = require("mux.js");

67

68

// Inspect MP4 file structure

69

const mp4Data = new Uint8Array([/* MP4 file data */]);

70

const structure = muxjs.mp4.tools.inspect(mp4Data);

71

72

console.log('MP4 Analysis:');

73

console.log(`Total size: ${structure.totalSize} bytes`);

74

console.log(`Root boxes: ${structure.boxes.length}`);

75

76

// List all boxes

77

structure.boxes.forEach(box => {

78

console.log(`Box: ${box.type}, size: ${box.size} bytes`);

79

if (box.children) {

80

box.children.forEach(child => {

81

console.log(` Child: ${child.type}, size: ${child.size} bytes`);

82

});

83

}

84

});

85

86

// Get human-readable representation

87

const textOutput = muxjs.mp4.tools.textify(structure);

88

console.log('MP4 Structure:');

89

console.log(textOutput);

90

91

// Find specific boxes

92

const moovBox = muxjs.mp4.tools.findBox(mp4Data, 'moov');

93

if (moovBox) {

94

console.log('Found movie box');

95

96

// Parse handler box to identify track type

97

const hdlrBox = muxjs.mp4.tools.findBox(moovBox, 'hdlr');

98

if (hdlrBox) {

99

const handler = muxjs.mp4.tools.parseHdlr(hdlrBox);

100

console.log(`Track handler: ${handler.handlerType}`);

101

}

102

}

103

104

// Analyze fragmented MP4

105

const moofBox = muxjs.mp4.tools.findBox(mp4Data, 'moof');

106

if (moofBox) {

107

console.log('Found movie fragment');

108

109

// Parse track fragment

110

const trafBox = muxjs.mp4.tools.findBox(moofBox, 'traf');

111

if (trafBox) {

112

const traf = muxjs.mp4.tools.parseTraf(trafBox);

113

console.log(`Track fragment for track ${traf.trackId}`);

114

115

// Parse decode time

116

const tfdtData = muxjs.mp4.tools.findBox(trafBox, 'tfdt');

117

if (tfdtData) {

118

const tfdt = muxjs.mp4.tools.parseTfdt(tfdtData);

119

console.log(`Base media decode time: ${tfdt.baseMediaDecodeTime}`);

120

}

121

}

122

}

123

```

124

125

### Transport Stream Inspection Tools

126

127

Tools for analyzing MPEG-2 transport stream structure and content.

128

129

```javascript { .api }

130

/**

131

* Transport stream inspection and debugging tools

132

*/

133

const mp2tTools: {

134

/** Inspect transport stream structure and packets */

135

inspect(data: Uint8Array): TransportStreamStructure;

136

};

137

138

interface TransportStreamStructure {

139

packets: TransportPacketInfo[];

140

programs: ProgramInfo[];

141

streams: StreamInfo[];

142

totalPackets: number;

143

}

144

145

interface TransportPacketInfo {

146

pid: number;

147

payloadUnitStartIndicator: boolean;

148

adaptationFieldControl: number;

149

continuityCounter: number;

150

payload: Uint8Array;

151

}

152

153

interface ProgramInfo {

154

programNumber: number;

155

pmtPid: number;

156

streams: StreamInfo[];

157

}

158

159

interface StreamInfo {

160

pid: number;

161

streamType: number;

162

streamTypeDescription: string;

163

elementaryPidCount: number;

164

}

165

```

166

167

**Usage Examples:**

168

169

```javascript

170

const muxjs = require("mux.js");

171

172

// Inspect transport stream

173

const tsData = new Uint8Array([/* Transport stream data */]);

174

const tsStructure = muxjs.mp2t.tools.inspect(tsData);

175

176

console.log('Transport Stream Analysis:');

177

console.log(`Total packets: ${tsStructure.totalPackets}`);

178

console.log(`Programs: ${tsStructure.programs.length}`);

179

console.log(`Streams: ${tsStructure.streams.length}`);

180

181

// Analyze programs

182

tsStructure.programs.forEach(program => {

183

console.log(`Program ${program.programNumber}:`);

184

console.log(` PMT PID: 0x${program.pmtPid.toString(16)}`);

185

186

program.streams.forEach(stream => {

187

console.log(` Stream PID: 0x${stream.pid.toString(16)}`);

188

console.log(` Type: ${stream.streamTypeDescription} (0x${stream.streamType.toString(16)})`);

189

console.log(` Packet count: ${stream.elementaryPidCount}`);

190

});

191

});

192

193

// Analyze packet distribution

194

const pidCounts = {};

195

tsStructure.packets.forEach(packet => {

196

pidCounts[packet.pid] = (pidCounts[packet.pid] || 0) + 1;

197

});

198

199

console.log('Packet distribution by PID:');

200

Object.entries(pidCounts).forEach(([pid, count]) => {

201

console.log(` PID 0x${parseInt(pid).toString(16)}: ${count} packets`);

202

});

203

```

204

205

### FLV Inspection Tools

206

207

Tools for analyzing FLV file structure and tags.

208

209

```javascript { .api }

210

/**

211

* FLV inspection and debugging tools

212

*/

213

const flvTools: {

214

/** Inspect individual FLV tag structure */

215

inspectTag(data: Uint8Array): FlvTagInfo;

216

217

/** Inspect complete FLV file structure */

218

inspect(data: Uint8Array): FlvStructure;

219

220

/** Convert FLV structure to human-readable text */

221

textify(structure: FlvStructure): string;

222

};

223

224

interface FlvTagInfo {

225

tagType: number;

226

tagTypeDescription: string;

227

dataSize: number;

228

timestamp: number;

229

timestampExtended: number;

230

streamId: number;

231

data: Uint8Array;

232

}

233

234

interface FlvStructure {

235

header: FlvHeader;

236

tags: FlvTagInfo[];

237

totalSize: number;

238

duration: number;

239

}

240

241

interface FlvHeader {

242

signature: string;

243

version: number;

244

flags: {

245

audio: boolean;

246

video: boolean;

247

};

248

headerSize: number;

249

}

250

```

251

252

**Usage Examples:**

253

254

```javascript

255

const muxjs = require("mux.js");

256

257

// Inspect FLV file

258

const flvData = new Uint8Array([/* FLV file data */]);

259

const flvStructure = muxjs.flv.tools.inspect(flvData);

260

261

console.log('FLV Analysis:');

262

console.log(`Version: ${flvStructure.header.version}`);

263

console.log(`Has audio: ${flvStructure.header.flags.audio}`);

264

console.log(`Has video: ${flvStructure.header.flags.video}`);

265

console.log(`Duration: ${flvStructure.duration}ms`);

266

console.log(`Total tags: ${flvStructure.tags.length}`);

267

268

// Analyze tag types

269

const tagTypeCounts = {};

270

flvStructure.tags.forEach(tag => {

271

const type = tag.tagTypeDescription;

272

tagTypeCounts[type] = (tagTypeCounts[type] || 0) + 1;

273

});

274

275

console.log('Tag distribution:');

276

Object.entries(tagTypeCounts).forEach(([type, count]) => {

277

console.log(` ${type}: ${count} tags`);

278

});

279

280

// Get readable representation

281

const textOutput = muxjs.flv.tools.textify(flvStructure);

282

console.log('FLV Structure:');

283

console.log(textOutput);

284

285

// Inspect specific tag

286

const firstVideoTag = flvStructure.tags.find(tag => tag.tagType === 9);

287

if (firstVideoTag) {

288

const tagInfo = muxjs.flv.tools.inspectTag(firstVideoTag.data);

289

console.log('First video tag:', tagInfo);

290

}

291

```

292

293

## Debugging Workflows

294

295

### Transmuxing Debug Workflow

296

297

Common workflow for debugging transmuxing issues:

298

299

```javascript

300

const muxjs = require("mux.js");

301

302

function debugTransmuxing(transportStreamData) {

303

console.log('=== Transport Stream Analysis ===');

304

305

// 1. Inspect input transport stream

306

const tsStructure = muxjs.mp2t.tools.inspect(transportStreamData);

307

console.log(`Input: ${tsStructure.totalPackets} packets`);

308

console.log(`Programs: ${tsStructure.programs.length}`);

309

310

// 2. Set up transmuxer with debugging

311

const transmuxer = new muxjs.mp4.Transmuxer();

312

313

transmuxer.on('data', (segment) => {

314

console.log('=== MP4 Output Analysis ===');

315

316

// Inspect initialization segment

317

if (segment.initSegment.length > 0) {

318

const initStructure = muxjs.mp4.tools.inspect(segment.initSegment);

319

console.log('Init segment boxes:');

320

initStructure.boxes.forEach(box => {

321

console.log(` ${box.type}: ${box.size} bytes`);

322

});

323

}

324

325

// Inspect media segment

326

const mediaStructure = muxjs.mp4.tools.inspect(segment.data);

327

console.log('Media segment boxes:');

328

mediaStructure.boxes.forEach(box => {

329

console.log(` ${box.type}: ${box.size} bytes`);

330

});

331

332

// Check for captions

333

console.log(`Captions: ${segment.captions.length}`);

334

segment.captions.forEach(captionSet => {

335

console.log(` ${captionSet.content.length} captions from ${captionSet.startTime}s to ${captionSet.endTime}s`);

336

});

337

338

// Check metadata

339

console.log(`Metadata frames: ${segment.metadata.frames.length}`);

340

});

341

342

// 3. Process data

343

transmuxer.push(transportStreamData);

344

transmuxer.flush();

345

}

346

347

// Usage

348

debugTransmuxing(transportStreamData);

349

```

350

351

### MP4 Structure Analysis

352

353

Detailed MP4 structure analysis for troubleshooting:

354

355

```javascript

356

function analyzeMP4Structure(mp4Data) {

357

const structure = muxjs.mp4.tools.inspect(mp4Data);

358

359

console.log('=== MP4 Structure Analysis ===');

360

361

// Check for required boxes

362

const requiredBoxes = ['ftyp', 'moov'];

363

const foundBoxes = structure.boxes.map(box => box.type);

364

365

requiredBoxes.forEach(required => {

366

if (foundBoxes.includes(required)) {

367

console.log(`✓ Found required box: ${required}`);

368

} else {

369

console.log(`✗ Missing required box: ${required}`);

370

}

371

});

372

373

// Analyze tracks

374

const moovBox = muxjs.mp4.tools.findBox(mp4Data, 'moov');

375

if (moovBox) {

376

const trakBoxes = [];

377

let offset = 8; // Skip box header

378

379

while (offset < moovBox.length) {

380

const boxType = muxjs.mp4.tools.parseType(moovBox.subarray(offset + 4, offset + 8));

381

if (boxType === 'trak') {

382

trakBoxes.push(moovBox.subarray(offset));

383

}

384

385

const size = new DataView(moovBox.buffer, moovBox.byteOffset + offset).getUint32(0);

386

offset += size;

387

}

388

389

console.log(`Tracks found: ${trakBoxes.length}`);

390

391

trakBoxes.forEach((trakBox, index) => {

392

const hdlrBox = muxjs.mp4.tools.findBox(trakBox, 'hdlr');

393

if (hdlrBox) {

394

const handler = muxjs.mp4.tools.parseHdlr(hdlrBox);

395

console.log(` Track ${index + 1}: ${handler.handlerType}`);

396

}

397

});

398

}

399

400

// Check for fragmentation

401

const hasFragments = foundBoxes.includes('moof');

402

console.log(`Fragmented MP4: ${hasFragments ? 'Yes' : 'No'}`);

403

404

return structure;

405

}

406

```

407

408

## Advanced Debugging Features

409

410

### Box-Level Analysis

411

412

```javascript

413

// Detailed box analysis

414

function analyzeBox(boxData, boxType) {

415

console.log(`=== ${boxType.toUpperCase()} Box Analysis ===`);

416

417

switch (boxType) {

418

case 'tfhd':

419

const tfhd = muxjs.mp4.tools.parseTfhd(boxData);

420

console.log(`Track ID: ${tfhd.trackId}`);

421

console.log(`Base data offset: ${tfhd.baseDataOffset}`);

422

break;

423

424

case 'trun':

425

const trun = muxjs.mp4.tools.parseTrun(boxData);

426

console.log(`Sample count: ${trun.sampleCount}`);

427

console.log(`Data offset: ${trun.dataOffset}`);

428

break;

429

430

case 'sidx':

431

const sidx = muxjs.mp4.tools.parseSidx(boxData);

432

console.log(`Reference ID: ${sidx.referenceId}`);

433

console.log(`Timescale: ${sidx.timescale}`);

434

break;

435

}

436

}

437

```

438

439

### Performance Monitoring

440

441

```javascript

442

// Performance monitoring during inspection

443

function monitoredInspect(data, format) {

444

const startTime = performance.now();

445

446

let result;

447

switch (format) {

448

case 'mp4':

449

result = muxjs.mp4.tools.inspect(data);

450

break;

451

case 'flv':

452

result = muxjs.flv.tools.inspect(data);

453

break;

454

case 'ts':

455

result = muxjs.mp2t.tools.inspect(data);

456

break;

457

}

458

459

const endTime = performance.now();

460

console.log(`${format.toUpperCase()} inspection took ${endTime - startTime}ms`);

461

462

return result;

463

}

464

```

465

466

## Types

467

468

```javascript { .api }

469

interface TrafBox {

470

trackId: number;

471

baseDataOffset?: number;

472

sampleDescriptionIndex?: number;

473

defaultSampleDuration?: number;

474

defaultSampleSize?: number;

475

defaultSampleFlags?: number;

476

}

477

478

interface TfdtBox {

479

version: number;

480

baseMediaDecodeTime: number;

481

}

482

483

interface HdlrBox {

484

handlerType: string;

485

name: string;

486

}

487

488

interface TfhdBox {

489

trackId: number;

490

baseDataOffset?: number;

491

sampleDescriptionIndex?: number;

492

defaultSampleDuration?: number;

493

defaultSampleSize?: number;

494

defaultSampleFlags?: number;

495

}

496

497

interface TrunBox {

498

sampleCount: number;

499

dataOffset?: number;

500

firstSampleFlags?: number;

501

samples: TrunSample[];

502

}

503

504

interface TrunSample {

505

duration?: number;

506

size?: number;

507

flags?: number;

508

compositionTimeOffset?: number;

509

}

510

511

interface SidxBox {

512

referenceId: number;

513

timescale: number;

514

earliestPresentationTime: number;

515

firstOffset: number;

516

references: SidxReference[];

517

}

518

519

interface SidxReference {

520

referenceType: number;

521

referencedSize: number;

522

subsegmentDuration: number;

523

startsWithSap: boolean;

524

sapType: number;

525

sapDeltaTime: number;

526

}

527

528

interface SampleFlags {

529

isLeading: number;

530

dependsOn: number;

531

isDependedOn: number;

532

hasRedundancy: number;

533

degradPrio: number;

534

isNonSync: boolean;

535

}

536

```