or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

codecs.mdflv.mdindex.mdmp4.mdpartial.mdtools.mdtransport-streams.mdutilities.md

utilities.mddocs/

0

# Utilities and Helpers

1

2

Shared utilities for time conversion, binary data handling, stream processing, and mathematical operations that support the core functionality across all mux.js modules.

3

4

## Capabilities

5

6

### Stream Base Class

7

8

Foundation class for all streaming operations in mux.js, providing consistent event-driven processing patterns.

9

10

```javascript { .api }

11

/**

12

* Base class for all stream processing in mux.js

13

* Provides event system and pipeline connectivity

14

*/

15

class Stream {

16

constructor();

17

18

/** Initialize stream (called during construction) */

19

init(): void;

20

21

/** Add event listener */

22

on(type: string, listener: Function): void;

23

24

/** Remove event listener */

25

off(type: string, listener: Function): void;

26

27

/** Trigger event with optional arguments */

28

trigger(type: string, ...args: any[]): void;

29

30

/** Clean up resources and remove listeners */

31

dispose(): void;

32

33

/** Connect this stream to another stream */

34

pipe(destination: Stream): Stream;

35

36

/** Process data (override in subclasses) */

37

push(data: any): void;

38

39

/** Complete processing and emit final data */

40

flush(flushSource?: Stream): void;

41

42

/** Partial flush for segment boundaries */

43

partialFlush(flushSource?: Stream): void;

44

45

/** End timeline processing */

46

endTimeline(flushSource?: Stream): void;

47

48

/** Reset stream state */

49

reset(flushSource?: Stream): void;

50

}

51

```

52

53

**Usage Example:**

54

55

```javascript

56

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

57

58

// Create custom stream by extending base class

59

class CustomTransformStream extends muxjs.utils.Stream {

60

constructor() {

61

super();

62

this.buffer = [];

63

}

64

65

push(data) {

66

// Transform incoming data

67

const transformed = this.transformData(data);

68

this.buffer.push(transformed);

69

70

// Emit when buffer is full

71

if (this.buffer.length >= 10) {

72

this.trigger('data', this.buffer.splice(0, 10));

73

}

74

}

75

76

flush() {

77

// Emit remaining data

78

if (this.buffer.length > 0) {

79

this.trigger('data', this.buffer.splice(0));

80

}

81

this.trigger('done');

82

}

83

84

transformData(data) {

85

// Custom transformation logic

86

return data;

87

}

88

}

89

90

// Use custom stream

91

const customStream = new CustomTransformStream();

92

93

customStream.on('data', function(transformedData) {

94

console.log('Transformed data:', transformedData);

95

});

96

97

customStream.on('done', function() {

98

console.log('Processing complete');

99

});

100

```

101

102

### Clock and Time Conversion Utilities

103

104

Comprehensive time conversion utilities for handling different timestamp formats used in video streaming.

105

106

```javascript { .api }

107

/** 90kHz clock rate used in video timestamps */

108

const ONE_SECOND_IN_TS = 90000;

109

110

/**

111

* Convert seconds to video timestamps (90kHz)

112

* @param seconds - Time in seconds

113

* @returns Timestamp in 90kHz units

114

*/

115

function secondsToVideoTs(seconds: number): number;

116

117

/**

118

* Convert seconds to audio timestamps

119

* @param seconds - Time in seconds

120

* @param sampleRate - Audio sample rate (e.g., 44100, 48000)

121

* @returns Timestamp in sample rate units

122

*/

123

function secondsToAudioTs(seconds: number, sampleRate: number): number;

124

125

/**

126

* Convert video timestamps to seconds

127

* @param timestamp - Timestamp in 90kHz units

128

* @returns Time in seconds

129

*/

130

function videoTsToSeconds(timestamp: number): number;

131

132

/**

133

* Convert audio timestamps to seconds

134

* @param timestamp - Timestamp in sample rate units

135

* @param sampleRate - Audio sample rate

136

* @returns Time in seconds

137

*/

138

function audioTsToSeconds(timestamp: number, sampleRate: number): number;

139

140

/**

141

* Convert audio timestamps to video timestamps

142

* @param timestamp - Audio timestamp in sample rate units

143

* @param sampleRate - Audio sample rate

144

* @returns Video timestamp in 90kHz units

145

*/

146

function audioTsToVideoTs(timestamp: number, sampleRate: number): number;

147

148

/**

149

* Convert video timestamps to audio timestamps

150

* @param timestamp - Video timestamp in 90kHz units

151

* @param sampleRate - Audio sample rate

152

* @returns Audio timestamp in sample rate units

153

*/

154

function videoTsToAudioTs(timestamp: number, sampleRate: number): number;

155

156

/**

157

* Convert metadata timestamps to seconds with timeline adjustment

158

* @param timestamp - Metadata timestamp

159

* @param timelineStartPts - Timeline start PTS

160

* @param keepOriginalTimestamps - Whether to preserve original timing

161

* @returns Time in seconds

162

*/

163

function metadataTsToSeconds(

164

timestamp: number,

165

timelineStartPts: number,

166

keepOriginalTimestamps: boolean

167

): number;

168

```

169

170

**Usage Example:**

171

172

```javascript

173

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

174

const clock = muxjs.utils.clock;

175

176

// Convert between different timestamp formats

177

const seconds = 10.5;

178

const videoTs = clock.secondsToVideoTs(seconds);

179

console.log('10.5 seconds =', videoTs, 'video timestamp units');

180

181

const audioTs = clock.secondsToAudioTs(seconds, 48000);

182

console.log('10.5 seconds =', audioTs, 'audio timestamp units at 48kHz');

183

184

// Convert back to seconds

185

const backToSeconds = clock.videoTsToSeconds(videoTs);

186

console.log('Converted back:', backToSeconds, 'seconds');

187

188

// Cross-format conversion

189

const audioToVideo = clock.audioTsToVideoTs(audioTs, 48000);

190

console.log('Audio timestamp as video timestamp:', audioToVideo);

191

192

// Timeline calculations

193

const metadataTime = clock.metadataTsToSeconds(

194

945000, // metadata timestamp

195

90000, // timeline start (1 second)

196

false // adjust for timeline

197

);

198

console.log('Metadata time:', metadataTime, 'seconds');

199

```

200

201

### Binary Data Utilities

202

203

Low-level utilities for binary data manipulation and parsing.

204

205

```javascript { .api }

206

/**

207

* Binary data manipulation utilities

208

*/

209

const bin = {

210

/**

211

* Read big-endian 32-bit unsigned integer

212

* @param data - Data buffer

213

* @param offset - Byte offset

214

* @returns 32-bit unsigned integer

215

*/

216

readUint32BE(data: Uint8Array, offset: number): number;

217

218

/**

219

* Read big-endian 16-bit unsigned integer

220

* @param data - Data buffer

221

* @param offset - Byte offset

222

* @returns 16-bit unsigned integer

223

*/

224

readUint16BE(data: Uint8Array, offset: number): number;

225

226

/**

227

* Write big-endian 32-bit unsigned integer

228

* @param data - Data buffer

229

* @param offset - Byte offset

230

* @param value - Value to write

231

*/

232

writeUint32BE(data: Uint8Array, offset: number, value: number): void;

233

234

/**

235

* Write big-endian 16-bit unsigned integer

236

* @param data - Data buffer

237

* @param offset - Byte offset

238

* @param value - Value to write

239

*/

240

writeUint16BE(data: Uint8Array, offset: number, value: number): void;

241

};

242

```

243

244

### Exponential Golomb Decoder

245

246

Specialized decoder for exponential Golomb encoded values used in H.264 streams.

247

248

```javascript { .api }

249

/**

250

* Exponential Golomb decoder for H.264 parameter parsing

251

*/

252

class ExpGolomb {

253

constructor(data: Uint8Array);

254

255

/** Read unsigned exponential Golomb coded integer */

256

readUnsignedExpGolomb(): number;

257

258

/** Read signed exponential Golomb coded integer */

259

readSignedExpGolomb(): number;

260

261

/** Read single bit */

262

readBits(count: number): number;

263

264

/** Skip bits */

265

skipBits(count: number): void;

266

267

/** Skip leading zero bits */

268

skipLeadingZeros(): number;

269

}

270

```

271

272

**Usage Example:**

273

274

```javascript

275

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

276

277

// Parse H.264 SPS (Sequence Parameter Set) data

278

function parseSPS(spsData) {

279

const expGolomb = new muxjs.utils.ExpGolomb(spsData);

280

281

// Skip NAL header

282

expGolomb.skipBits(8);

283

284

// Read profile information

285

const profileIdc = expGolomb.readBits(8);

286

const constraintFlags = expGolomb.readBits(8);

287

const levelIdc = expGolomb.readBits(8);

288

289

// Read SPS ID

290

const spsId = expGolomb.readUnsignedExpGolomb();

291

292

console.log('H.264 SPS Info:');

293

console.log(' Profile IDC:', profileIdc);

294

console.log(' Level IDC:', levelIdc);

295

console.log(' SPS ID:', spsId);

296

297

return {

298

profileIdc,

299

constraintFlags,

300

levelIdc,

301

spsId

302

};

303

}

304

```

305

306

### String Utilities

307

308

String processing utilities for codec and container data handling.

309

310

```javascript { .api }

311

/**

312

* String manipulation utilities

313

*/

314

const stringUtils = {

315

/**

316

* Convert byte array to ASCII string

317

* @param data - Byte array

318

* @param offset - Start offset (default: 0)

319

* @param length - Length to read (default: remaining)

320

* @returns ASCII string

321

*/

322

bytesToString(data: Uint8Array, offset?: number, length?: number): string;

323

324

/**

325

* Convert ASCII string to byte array

326

* @param str - ASCII string

327

* @returns Byte array

328

*/

329

stringToBytes(str: string): Uint8Array;

330

331

/**

332

* Parse null-terminated string from byte array

333

* @param data - Byte array

334

* @param offset - Start offset

335

* @returns Parsed string and new offset

336

*/

337

parseNullTerminatedString(data: Uint8Array, offset: number): {

338

string: string;

339

offset: number;

340

};

341

};

342

```

343

344

### Typed Array Utilities

345

346

Utilities for working with typed arrays and memory management.

347

348

```javascript { .api }

349

/**

350

* Typed array manipulation utilities

351

*/

352

const typedArray = {

353

/**

354

* Concatenate multiple typed arrays

355

* @param arrays - Arrays to concatenate

356

* @returns New concatenated array

357

*/

358

concat(...arrays: Uint8Array[]): Uint8Array;

359

360

/**

361

* Slice typed array (similar to Array.slice)

362

* @param array - Source array

363

* @param start - Start index

364

* @param end - End index (exclusive)

365

* @returns New sliced array

366

*/

367

slice(array: Uint8Array, start: number, end?: number): Uint8Array;

368

369

/**

370

* Compare two typed arrays for equality

371

* @param a - First array

372

* @param b - Second array

373

* @returns True if arrays are equal

374

*/

375

equal(a: Uint8Array, b: Uint8Array): boolean;

376

377

/**

378

* Find byte pattern in array

379

* @param haystack - Array to search in

380

* @param needle - Pattern to find

381

* @param start - Start search index

382

* @returns Index of pattern or -1 if not found

383

*/

384

indexOf(haystack: Uint8Array, needle: Uint8Array, start?: number): number;

385

};

386

```

387

388

### Number Utilities

389

390

Mathematical utilities for bit operations and number manipulation.

391

392

```javascript { .api }

393

/**

394

* Number and bit manipulation utilities

395

*/

396

const numbers = {

397

/**

398

* Convert number to hexadecimal string

399

* @param num - Number to convert

400

* @param padding - Minimum string length with zero padding

401

* @returns Hexadecimal string

402

*/

403

toHex(num: number, padding?: number): string;

404

405

/**

406

* Extract bits from number

407

* @param value - Source value

408

* @param offset - Bit offset from right (0-based)

409

* @param length - Number of bits to extract

410

* @returns Extracted bits as number

411

*/

412

getBits(value: number, offset: number, length: number): number;

413

414

/**

415

* Set bits in number

416

* @param target - Target value

417

* @param offset - Bit offset from right (0-based)

418

* @param length - Number of bits to set

419

* @param value - Value to set

420

* @returns Modified number

421

*/

422

setBits(target: number, offset: number, length: number, value: number): number;

423

424

/**

425

* Count leading zeros in 32-bit integer

426

* @param value - Input value

427

* @returns Number of leading zeros

428

*/

429

clz32(value: number): number;

430

};

431

```

432

433

## Advanced Usage

434

435

### Custom Stream Implementation

436

437

```javascript

438

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

439

440

// Advanced custom stream with buffering and error handling

441

class BufferedProcessorStream extends muxjs.utils.Stream {

442

constructor(options = {}) {

443

super();

444

this.bufferSize = options.bufferSize || 1024;

445

this.buffer = new Uint8Array(this.bufferSize);

446

this.bufferFill = 0;

447

this.processingOptions = options;

448

}

449

450

push(data) {

451

try {

452

// Buffer incoming data

453

if (this.bufferFill + data.length > this.bufferSize) {

454

this.processBuffer();

455

}

456

457

this.buffer.set(data, this.bufferFill);

458

this.bufferFill += data.length;

459

460

// Process if buffer is full

461

if (this.bufferFill >= this.bufferSize) {

462

this.processBuffer();

463

}

464

} catch (error) {

465

this.trigger('error', error);

466

}

467

}

468

469

flush() {

470

if (this.bufferFill > 0) {

471

this.processBuffer();

472

}

473

this.trigger('done');

474

}

475

476

processBuffer() {

477

if (this.bufferFill === 0) return;

478

479

const dataToProcess = this.buffer.subarray(0, this.bufferFill);

480

const processedData = this.processData(dataToProcess);

481

482

if (processedData) {

483

this.trigger('data', processedData);

484

}

485

486

this.bufferFill = 0;

487

}

488

489

processData(data) {

490

// Override in subclasses

491

return data;

492

}

493

494

reset() {

495

this.bufferFill = 0;

496

super.reset();

497

}

498

}

499

```

500

501

### Time Synchronization Helper

502

503

```javascript

504

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

505

506

class TimestampSync {

507

constructor() {

508

this.audioTimebase = null;

509

this.videoTimebase = null;

510

this.syncOffset = 0;

511

}

512

513

setAudioTimebase(sampleRate) {

514

this.audioTimebase = sampleRate;

515

}

516

517

setVideoTimebase() {

518

this.videoTimebase = 90000; // Standard video timebase

519

}

520

521

syncTimestamps(audioTs, videoTs) {

522

if (!this.audioTimebase || !this.videoTimebase) {

523

throw new Error('Timebases not set');

524

}

525

526

// Convert both to common timebase (video)

527

const audioInVideoTs = muxjs.utils.clock.audioTsToVideoTs(audioTs, this.audioTimebase);

528

529

// Calculate sync offset

530

this.syncOffset = videoTs - audioInVideoTs;

531

532

return {

533

audioSync: audioInVideoTs + this.syncOffset,

534

videoSync: videoTs,

535

offset: this.syncOffset

536

};

537

}

538

539

adjustAudioTimestamp(audioTs) {

540

const audioInVideoTs = muxjs.utils.clock.audioTsToVideoTs(audioTs, this.audioTimebase);

541

return audioInVideoTs + this.syncOffset;

542

}

543

}

544

```

545

546

## Error Handling

547

548

Utility functions provide detailed error information:

549

550

```javascript

551

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

552

553

// Stream error handling

554

const customStream = new muxjs.utils.Stream();

555

556

customStream.on('error', function(error) {

557

console.error('Stream error:', error.message);

558

console.error('Stack trace:', error.stack);

559

});

560

561

// Binary data parsing with error checking

562

try {

563

const value = muxjs.utils.bin.readUint32BE(data, offset);

564

console.log('Parsed value:', value);

565

} catch (error) {

566

console.error('Binary parsing error:', error.message);

567

// Common errors: insufficient data, invalid offset

568

}

569

570

// Exponential Golomb parsing with error handling

571

try {

572

const expGolomb = new muxjs.utils.ExpGolomb(spsData);

573

const value = expGolomb.readUnsignedExpGolomb();

574

} catch (error) {

575

console.error('ExpGolomb parsing error:', error.message);

576

// Common errors: truncated data, invalid encoding

577

}

578

```