Socket
Socket
Sign inDemoInstall

webm-muxer

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webm-muxer - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

8

build/webm-muxer.d.ts

@@ -11,2 +11,8 @@ /**

*
* If the target is a function, it will be called each time data is output by the muxer - this is useful if you want
* to stream the data. The function will be called with three arguments: the data to write, the offset in bytes at
* which to write the data and a boolean indicating whether the muxer is done writing data. Note that the same
* segment of bytes might be written to multiple times and therefore you need to write the data in the same order
* the function gave it to you.
*
* If the target is of type `FileSystemWritableFileStream`, the file will be written directly to disk as it is being

@@ -16,3 +22,3 @@ * muxed. The benefit of this target is the ability to write out very large files, easily exceeding the RAM of the

*/
target: 'buffer' | FileSystemWritableFileStream,
target: 'buffer' | ((data: Uint8Array, offset: number, done: boolean) => void) | FileSystemWritableFileStream,
/**

@@ -19,0 +25,0 @@ * Specifies the docType of the muxed multimedia file. This property is optional and defaults to `'webm'`, which is

318

build/webm-muxer.js

@@ -61,41 +61,49 @@ "use strict";

};
var measureUnsignedInt = (value) => {
if (value < 1 << 8) {
return 1;
} else if (value < 1 << 16) {
return 2;
} else if (value < 1 << 24) {
return 3;
} else if (value < __pow(2, 32)) {
return 4;
} else if (value < __pow(2, 40)) {
return 5;
} else {
return 6;
}
};
var measureEBMLVarInt = (value) => {
if (value < (1 << 7) - 1) {
return 1;
} else if (value < (1 << 14) - 1) {
return 2;
} else if (value < (1 << 21) - 1) {
return 3;
} else if (value < (1 << 28) - 1) {
return 4;
} else if (value < __pow(2, 35) - 1) {
return 5;
} else if (value < __pow(2, 42) - 1) {
return 6;
} else {
throw new Error("EBML VINT size not supported " + value);
}
};
// src/write_target.ts
var _helper, _helperView, _writeFloat32, writeFloat32_fn, _writeFloat64, writeFloat64_fn, _writeUnsignedInt, writeUnsignedInt_fn, _writeString, writeString_fn;
var WriteTarget = class {
constructor() {
__privateAdd(this, _writeFloat32);
__privateAdd(this, _writeFloat64);
__privateAdd(this, _writeUnsignedInt);
__privateAdd(this, _writeString);
this.pos = 0;
this.helper = new Uint8Array(8);
this.helperView = new DataView(this.helper.buffer);
__privateAdd(this, _helper, new Uint8Array(8));
__privateAdd(this, _helperView, new DataView(__privateGet(this, _helper).buffer));
this.offsets = /* @__PURE__ */ new WeakMap();
this.dataOffsets = /* @__PURE__ */ new WeakMap();
}
writeFloat32(value) {
this.helperView.setFloat32(0, value, false);
this.write(this.helper.subarray(0, 4));
}
writeFloat64(value) {
this.helperView.setFloat64(0, value, false);
this.write(this.helper);
}
writeUnsignedInt(value, width = measureUnsignedInt(value)) {
let pos = 0;
switch (width) {
case 6:
this.helperView.setUint8(pos++, value / __pow(2, 40) | 0);
case 5:
this.helperView.setUint8(pos++, value / __pow(2, 32) | 0);
case 4:
this.helperView.setUint8(pos++, value >> 24);
case 3:
this.helperView.setUint8(pos++, value >> 16);
case 2:
this.helperView.setUint8(pos++, value >> 8);
case 1:
this.helperView.setUint8(pos++, value);
break;
default:
throw new Error("Bad UINT size " + width);
}
this.write(this.helper.subarray(0, pos));
}
writeEBMLVarInt(value, width = measureEBMLVarInt(value)) {

@@ -105,33 +113,33 @@ let pos = 0;

case 1:
this.helperView.setUint8(pos++, 1 << 7 | value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 7 | value);
break;
case 2:
this.helperView.setUint8(pos++, 1 << 6 | value >> 8);
this.helperView.setUint8(pos++, value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 6 | value >> 8);
__privateGet(this, _helperView).setUint8(pos++, value);
break;
case 3:
this.helperView.setUint8(pos++, 1 << 5 | value >> 16);
this.helperView.setUint8(pos++, value >> 8);
this.helperView.setUint8(pos++, value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 5 | value >> 16);
__privateGet(this, _helperView).setUint8(pos++, value >> 8);
__privateGet(this, _helperView).setUint8(pos++, value);
break;
case 4:
this.helperView.setUint8(pos++, 1 << 4 | value >> 24);
this.helperView.setUint8(pos++, value >> 16);
this.helperView.setUint8(pos++, value >> 8);
this.helperView.setUint8(pos++, value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 4 | value >> 24);
__privateGet(this, _helperView).setUint8(pos++, value >> 16);
__privateGet(this, _helperView).setUint8(pos++, value >> 8);
__privateGet(this, _helperView).setUint8(pos++, value);
break;
case 5:
this.helperView.setUint8(pos++, 1 << 3 | value / __pow(2, 32) & 7);
this.helperView.setUint8(pos++, value >> 24);
this.helperView.setUint8(pos++, value >> 16);
this.helperView.setUint8(pos++, value >> 8);
this.helperView.setUint8(pos++, value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 3 | value / __pow(2, 32) & 7);
__privateGet(this, _helperView).setUint8(pos++, value >> 24);
__privateGet(this, _helperView).setUint8(pos++, value >> 16);
__privateGet(this, _helperView).setUint8(pos++, value >> 8);
__privateGet(this, _helperView).setUint8(pos++, value);
break;
case 6:
this.helperView.setUint8(pos++, 1 << 2 | value / __pow(2, 40) & 3);
this.helperView.setUint8(pos++, value / __pow(2, 32) | 0);
this.helperView.setUint8(pos++, value >> 24);
this.helperView.setUint8(pos++, value >> 16);
this.helperView.setUint8(pos++, value >> 8);
this.helperView.setUint8(pos++, value);
__privateGet(this, _helperView).setUint8(pos++, 1 << 2 | value / __pow(2, 40) & 3);
__privateGet(this, _helperView).setUint8(pos++, value / __pow(2, 32) | 0);
__privateGet(this, _helperView).setUint8(pos++, value >> 24);
__privateGet(this, _helperView).setUint8(pos++, value >> 16);
__privateGet(this, _helperView).setUint8(pos++, value >> 8);
__privateGet(this, _helperView).setUint8(pos++, value);
break;

@@ -141,7 +149,4 @@ default:

}
this.write(this.helper.subarray(0, pos));
this.write(__privateGet(this, _helper).subarray(0, pos));
}
writeString(str) {
this.write(new Uint8Array(str.split("").map((x) => x.charCodeAt(0))));
}
writeEBML(data) {

@@ -157,3 +162,3 @@ var _a, _b;

this.offsets.set(data, this.pos);
this.writeUnsignedInt(data.id);
__privateMethod(this, _writeUnsignedInt, writeUnsignedInt_fn).call(this, data.id);
if (Array.isArray(data.data)) {

@@ -174,6 +179,6 @@ let sizePos = this.pos;

this.writeEBMLVarInt(size);
this.writeUnsignedInt(data.data, size);
__privateMethod(this, _writeUnsignedInt, writeUnsignedInt_fn).call(this, data.data, size);
} else if (typeof data.data === "string") {
this.writeEBMLVarInt(data.data.length);
this.writeString(data.data);
__privateMethod(this, _writeString, writeString_fn).call(this, data.data);
} else if (data.data instanceof Uint8Array) {

@@ -184,6 +189,6 @@ this.writeEBMLVarInt(data.data.byteLength, data.size);

this.writeEBMLVarInt(4);
this.writeFloat32(data.data.value);
__privateMethod(this, _writeFloat32, writeFloat32_fn).call(this, data.data.value);
} else if (data.data instanceof EBMLFloat64) {
this.writeEBMLVarInt(8);
this.writeFloat64(data.data.value);
__privateMethod(this, _writeFloat64, writeFloat64_fn).call(this, data.data.value);
}

@@ -193,55 +198,62 @@ }

};
var measureUnsignedInt = (value) => {
if (value < 1 << 8) {
return 1;
} else if (value < 1 << 16) {
return 2;
} else if (value < 1 << 24) {
return 3;
} else if (value < __pow(2, 32)) {
return 4;
} else if (value < __pow(2, 40)) {
return 5;
} else {
return 6;
}
_helper = new WeakMap();
_helperView = new WeakMap();
_writeFloat32 = new WeakSet();
writeFloat32_fn = function(value) {
__privateGet(this, _helperView).setFloat32(0, value, false);
this.write(__privateGet(this, _helper).subarray(0, 4));
};
var measureEBMLVarInt = (value) => {
if (value < (1 << 7) - 1) {
return 1;
} else if (value < (1 << 14) - 1) {
return 2;
} else if (value < (1 << 21) - 1) {
return 3;
} else if (value < (1 << 28) - 1) {
return 4;
} else if (value < __pow(2, 35) - 1) {
return 5;
} else if (value < __pow(2, 42) - 1) {
return 6;
} else {
throw new Error("EBML VINT size not supported " + value);
_writeFloat64 = new WeakSet();
writeFloat64_fn = function(value) {
__privateGet(this, _helperView).setFloat64(0, value, false);
this.write(__privateGet(this, _helper));
};
_writeUnsignedInt = new WeakSet();
writeUnsignedInt_fn = function(value, width = measureUnsignedInt(value)) {
let pos = 0;
switch (width) {
case 6:
__privateGet(this, _helperView).setUint8(pos++, value / __pow(2, 40) | 0);
case 5:
__privateGet(this, _helperView).setUint8(pos++, value / __pow(2, 32) | 0);
case 4:
__privateGet(this, _helperView).setUint8(pos++, value >> 24);
case 3:
__privateGet(this, _helperView).setUint8(pos++, value >> 16);
case 2:
__privateGet(this, _helperView).setUint8(pos++, value >> 8);
case 1:
__privateGet(this, _helperView).setUint8(pos++, value);
break;
default:
throw new Error("Bad UINT size " + width);
}
this.write(__privateGet(this, _helper).subarray(0, pos));
};
_writeString = new WeakSet();
writeString_fn = function(str) {
this.write(new Uint8Array(str.split("").map((x) => x.charCodeAt(0))));
};
var _buffer, _bytes;
var ArrayBufferWriteTarget = class extends WriteTarget {
constructor() {
super();
this.buffer = new ArrayBuffer(__pow(2, 16));
this.bytes = new Uint8Array(this.buffer);
__privateAdd(this, _buffer, new ArrayBuffer(__pow(2, 16)));
__privateAdd(this, _bytes, new Uint8Array(__privateGet(this, _buffer)));
}
ensureSize(size) {
let newLength = this.buffer.byteLength;
let newLength = __privateGet(this, _buffer).byteLength;
while (newLength < size)
newLength *= 2;
if (newLength === this.buffer.byteLength)
if (newLength === __privateGet(this, _buffer).byteLength)
return;
let newBuffer = new ArrayBuffer(newLength);
let newBytes = new Uint8Array(newBuffer);
newBytes.set(this.bytes, 0);
this.buffer = newBuffer;
this.bytes = newBytes;
newBytes.set(__privateGet(this, _bytes), 0);
__privateSet(this, _buffer, newBuffer);
__privateSet(this, _bytes, newBytes);
}
write(data) {
this.ensureSize(this.pos + data.byteLength);
this.bytes.set(data, this.pos);
__privateGet(this, _bytes).set(data, this.pos);
this.pos += data.byteLength;

@@ -254,12 +266,16 @@ }

this.ensureSize(this.pos);
return this.buffer.slice(0, this.pos);
return __privateGet(this, _buffer).slice(0, this.pos);
}
};
_buffer = new WeakMap();
_bytes = new WeakMap();
var FILE_CHUNK_SIZE = __pow(2, 24);
var MAX_CHUNKS_AT_ONCE = 2;
var _stream, _chunks;
var FileSystemWritableFileStreamWriteTarget = class extends WriteTarget {
constructor(stream) {
super();
this.chunks = [];
this.stream = stream;
__privateAdd(this, _stream, void 0);
__privateAdd(this, _chunks, []);
__privateSet(this, _stream, stream);
}

@@ -272,6 +288,6 @@ write(data) {

writeDataIntoChunks(data, position) {
let chunkIndex = this.chunks.findIndex((x) => x.start <= position && position < x.start + FILE_CHUNK_SIZE);
let chunkIndex = __privateGet(this, _chunks).findIndex((x) => x.start <= position && position < x.start + FILE_CHUNK_SIZE);
if (chunkIndex === -1)
chunkIndex = this.createChunk(position);
let chunk = this.chunks[chunkIndex];
let chunk = __privateGet(this, _chunks)[chunkIndex];
let relativePosition = position - chunk.start;

@@ -288,5 +304,5 @@ let toWrite = data.subarray(0, Math.min(FILE_CHUNK_SIZE - relativePosition, data.byteLength));

}
if (this.chunks.length > MAX_CHUNKS_AT_ONCE) {
for (let i = 0; i < this.chunks.length - 1; i++) {
this.chunks[i].shouldFlush = true;
if (__privateGet(this, _chunks).length > MAX_CHUNKS_AT_ONCE) {
for (let i = 0; i < __privateGet(this, _chunks).length - 1; i++) {
__privateGet(this, _chunks)[i].shouldFlush = true;
}

@@ -307,13 +323,13 @@ this.flushChunks();

};
this.chunks.push(chunk);
this.chunks.sort((a, b) => a.start - b.start);
return this.chunks.indexOf(chunk);
__privateGet(this, _chunks).push(chunk);
__privateGet(this, _chunks).sort((a, b) => a.start - b.start);
return __privateGet(this, _chunks).indexOf(chunk);
}
flushChunks(force = false) {
for (let i = 0; i < this.chunks.length; i++) {
let chunk = this.chunks[i];
for (let i = 0; i < __privateGet(this, _chunks).length; i++) {
let chunk = __privateGet(this, _chunks)[i];
if (!chunk.shouldFlush && !force)
continue;
for (let section of chunk.written) {
this.stream.write({
__privateGet(this, _stream).write({
type: "write",

@@ -324,3 +340,3 @@ data: chunk.data.subarray(section.start, section.end),

}
this.chunks.splice(i--, 1);
__privateGet(this, _chunks).splice(i--, 1);
}

@@ -335,2 +351,4 @@ }

};
_stream = new WeakMap();
_chunks = new WeakMap();
var insertSectionIntoFileChunk = (chunk, section) => {

@@ -357,2 +375,56 @@ let low = 0;

};
var _sections, _onFlush;
var StreamingWriteTarget = class extends WriteTarget {
constructor(onFlush) {
super();
__privateAdd(this, _sections, []);
__privateAdd(this, _onFlush, void 0);
__privateSet(this, _onFlush, onFlush);
}
write(data) {
__privateGet(this, _sections).push({
data: data.slice(),
start: this.pos
});
this.pos += data.byteLength;
}
seek(newPos) {
this.pos = newPos;
}
flush(done) {
if (__privateGet(this, _sections).length === 0)
return;
let chunks = [];
let sorted = [...__privateGet(this, _sections)].sort((a, b) => a.start - b.start);
chunks.push({
start: sorted[0].start,
size: sorted[0].data.byteLength
});
for (let i = 1; i < sorted.length; i++) {
let lastChunk = chunks[chunks.length - 1];
let section = sorted[i];
if (section.start <= lastChunk.start + lastChunk.size) {
lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
} else {
chunks.push({
start: section.start,
size: section.data.byteLength
});
}
}
for (let chunk of chunks) {
chunk.data = new Uint8Array(chunk.size);
for (let section of __privateGet(this, _sections)) {
if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
chunk.data.set(section.data, section.start - chunk.start);
}
}
let isLastFlush = done && chunk === chunks[chunks.length - 1];
__privateGet(this, _onFlush).call(this, chunk.data, chunk.start, isLastFlush);
}
__privateGet(this, _sections).length = 0;
}
};
_sections = new WeakMap();
_onFlush = new WeakMap();

@@ -369,3 +441,3 @@ // src/main.ts

var CLUSTER_SIZE_BYTES = 5;
var _target, _options, _segment, _segmentInfo, _seekHead, _tracksElement, _segmentDuration, _colourElement, _videoCodecPrivate, _audioCodecPrivate, _cues, _currentCluster, _currentClusterTimestamp, _duration, _videoChunkQueue, _audioChunkQueue, _lastVideoTimestamp, _lastAudioTimestamp, _colorSpace, _finalized, _validateOptions, validateOptions_fn, _createFileHeader, createFileHeader_fn, _writeEBMLHeader, writeEBMLHeader_fn, _createSeekHead, createSeekHead_fn, _createSegmentInfo, createSegmentInfo_fn, _createTracks, createTracks_fn, _createSegment, createSegment_fn, _createCues, createCues_fn, _segmentDataOffset, segmentDataOffset_get, _writeVideoDecoderConfig, writeVideoDecoderConfig_fn, _fixVP9ColorSpace, fixVP9ColorSpace_fn, _createInternalChunk, createInternalChunk_fn, _writeSimpleBlock, writeSimpleBlock_fn, _writeCodecPrivate, writeCodecPrivate_fn, _createNewCluster, createNewCluster_fn, _finalizeCurrentCluster, finalizeCurrentCluster_fn, _ensureNotFinalized, ensureNotFinalized_fn;
var _target, _options, _segment, _segmentInfo, _seekHead, _tracksElement, _segmentDuration, _colourElement, _videoCodecPrivate, _audioCodecPrivate, _cues, _currentCluster, _currentClusterTimestamp, _duration, _videoChunkQueue, _audioChunkQueue, _lastVideoTimestamp, _lastAudioTimestamp, _colorSpace, _finalized, _validateOptions, validateOptions_fn, _createFileHeader, createFileHeader_fn, _writeEBMLHeader, writeEBMLHeader_fn, _createSeekHead, createSeekHead_fn, _createSegmentInfo, createSegmentInfo_fn, _createTracks, createTracks_fn, _createSegment, createSegment_fn, _createCues, createCues_fn, _maybeFlushStreamingTarget, maybeFlushStreamingTarget_fn, _segmentDataOffset, segmentDataOffset_get, _writeVideoDecoderConfig, writeVideoDecoderConfig_fn, _fixVP9ColorSpace, fixVP9ColorSpace_fn, _createInternalChunk, createInternalChunk_fn, _writeSimpleBlock, writeSimpleBlock_fn, _writeCodecPrivate, writeCodecPrivate_fn, _createNewCluster, createNewCluster_fn, _finalizeCurrentCluster, finalizeCurrentCluster_fn, _ensureNotFinalized, ensureNotFinalized_fn;
var WebMMuxer = class {

@@ -381,2 +453,3 @@ constructor(options) {

__privateAdd(this, _createCues);
__privateAdd(this, _maybeFlushStreamingTarget);
__privateAdd(this, _segmentDataOffset);

@@ -415,4 +488,8 @@ __privateAdd(this, _writeVideoDecoderConfig);

__privateSet(this, _target, new ArrayBufferWriteTarget());
} else if (options.target instanceof FileSystemWritableFileStream) {
__privateSet(this, _target, new FileSystemWritableFileStreamWriteTarget(options.target));
} else if (typeof options.target === "function") {
__privateSet(this, _target, new StreamingWriteTarget(options.target));
} else {
__privateSet(this, _target, new FileSystemWritableFileStreamWriteTarget(options.target));
throw new Error(`Invalid target: ${options.target}`);
}

@@ -445,2 +522,3 @@ __privateMethod(this, _createFileHeader, createFileHeader_fn).call(this);

}
__privateMethod(this, _maybeFlushStreamingTarget, maybeFlushStreamingTarget_fn).call(this);
}

@@ -470,2 +548,3 @@ addAudioChunk(chunk, meta, timestamp) {

}
__privateMethod(this, _maybeFlushStreamingTarget, maybeFlushStreamingTarget_fn).call(this);
}

@@ -497,2 +576,4 @@ finalize() {

__privateGet(this, _target).finalize();
} else if (__privateGet(this, _target) instanceof StreamingWriteTarget) {
__privateGet(this, _target).flush(true);
}

@@ -536,2 +617,3 @@ return null;

__privateMethod(this, _createCues, createCues_fn).call(this);
__privateMethod(this, _maybeFlushStreamingTarget, maybeFlushStreamingTarget_fn).call(this);
};

@@ -642,2 +724,8 @@ _writeEBMLHeader = new WeakSet();

};
_maybeFlushStreamingTarget = new WeakSet();
maybeFlushStreamingTarget_fn = function() {
if (__privateGet(this, _target) instanceof StreamingWriteTarget) {
__privateGet(this, _target).flush(false);
}
};
_segmentDataOffset = new WeakSet();

@@ -644,0 +732,0 @@ segmentDataOffset_get = function() {

{
"name": "webm-muxer",
"version": "1.2.0",
"version": "1.2.1",
"description": "WebM multiplexer in pure TypeScript with support for WebCodecs API, video & audio.",

@@ -5,0 +5,0 @@ "main": "./build/webm-muxer.js",

@@ -68,2 +68,3 @@ # webm-muxer - JavaScript WebM multiplexer

## Usage
### Initialization
For each WebM file you wish to create, create an instance of `WebMMuxer` like so:

@@ -76,9 +77,8 @@ ```js

interface WebMMuxerOptions {
// When 'buffer' is used, the muxed file is written to a buffer in
// memory. When a FileSystemWritableFileStream acquired through
// the File System Access API (see example below) is used, the
// muxed file is written directly to disk, allowing for files way
// larger than what would fit in RAM.
target: 'buffer' | FileSystemWritableFileStream,
type?: 'webm' | 'matroska', // Optional - see Details for more
target: 'buffer'
| ((data: Uint8Array, offset: number, done: boolean) => void)
| FileSystemWritableFileStream
type?: 'webm' | 'matroska',
video?: {

@@ -90,2 +90,3 @@ codec: string,

},
audio?: {

@@ -99,55 +100,75 @@ codec: string,

```
Codecs supported by WebM are `V_VP8`, `V_VP9`, `V_AV1`, `A_OPUS` and `A_VORBIS`.
Codecs officially supported by WebM are `V_VP8`, `V_VP9`, `V_AV1`, `A_OPUS` and `A_VORBIS`.
#### `target`
This option specifies what will happens with the data created by the muxer. The options are:
- `'buffer'`: The file data will be written into a single, large buffer which is then returned by `finalize`.
Some examples:
```js
// Create a muxer with a video track running the VP9 codec, and no
// audio track. The muxed file is written to a buffer in memory.
let muxer1 = new WebMMuxer({
target: 'buffer',
video: {
codec: 'V_VP9',
width: 1280,
height: 720
}
});
```js
let muxer = new WebMMuxer({
target: 'buffer',
video: {
codec: 'V_VP9',
width: 1280,
height: 720
}
});
// Create a muxer with a video track running the VP9 codec, and an
// audio track running the Opus codec. The muxed file is written
// directly to a file on disk, using the File System Access API.
let fileHandle = await window.showSaveFilePicker({
suggestedName: `video.webm`,
types: [{
description: 'Video File',
accept: { 'video/webm': ['.webm'] }
}],
});
let fileWritableStream = await fileHandle.createWritable();
let muxer2 = new WebMMuxer({
target: fileWritableStream,
video: {
codec: 'V_VP9',
width: 1920,
height: 1080,
frameRate: 60
},
audio: {
codec: 'A_OPUS',
numberOfChannels: 2,
sampleRate: 48000
}
});
// ...
// Create a muxer running only an Opus-coded audio track, and
// no video. Writes to a buffer in memory.
let muxer3 = new WebMMuxer({
target: 'buffer',
audio: {
codec: 'A_OPUS',
numberOfChannels: 1,
sampleRate: 44100
}
});
```
let buffer = muxer.finalize();
```
- `function`: If the target is a function, it will be called each time data is output by the muxer - this is useful if
you want to stream the data. The function will be called with three arguments: the data to write, the offset in
bytes at which to write the data and a boolean indicating whether the muxer is done writing data. Note that the same
segment of bytes might be written to multiple times and therefore you need to write the data in the same order the
function gave it to you.
```js
let muxer = new WebMMuxer({
target: (data, offset, done) => {
// Do something with the data
},
audio: {
codec: 'A_OPUS',
numberOfChannels: 1,
sampleRate: 44100
}
});
```
- `FileSystemWritableFileStream`: When acquired through the File System Access API, the
muxed file is written directly to disk, allowing for files way larger than what would fit in RAM. This functionality could also be manually emulated by passing a `function` instead, however, this library has some built-in write batching optimization which will be used when passing a FileSystemWritableFileStream.
```js
let fileHandle = await window.showSaveFilePicker({
suggestedName: `video.webm`,
types: [{
description: 'Video File',
accept: { 'video/webm': ['.webm'] }
}],
});
let fileWritableStream = await fileHandle.createWritable();
let muxer = new WebMMuxer({
target: fileWritableStream,
video: {
codec: 'V_VP9',
width: 1920,
height: 1080,
frameRate: 60
},
audio: {
codec: 'A_OPUS',
numberOfChannels: 2,
sampleRate: 48000
}
});
```
#### `type`
As WebM is a subset of the more general Matroska multimedia container format, this library muxes both WebM and Matroska
files. WebM, according to the official specification, supports only a small subset of the codecs supported by Matroska.
It is likely, however, that most players will successfully play back a WebM file with codecs other than the ones
supported in the spec. To be on the safe side, however, you can set the `type` option to `'matroska'`, which
will internally label the file as a general Matroska file. If you do this, your output file should also have the .mkv
extension.
### Muxing media chunks
Then, with VideoEncoder and AudioEncoder set up, send encoded chunks to the muxer like so:

@@ -190,2 +211,3 @@ ```js

### Finishing up
When encoding is finished, call `finalize` on the `WebMMuxer` instance to finalize the WebM file. When using

@@ -219,10 +241,2 @@ `target: 'buffer'`, the resulting file's buffer is returned by this method:

### WebM vs Matroska DocType
As WebM is a subset of the more general Matroska multimedia container format, this library muxes both WebM and Matroska
files. WebM, according to the official specification, supports only a small subset of the codecs supported by Matroska.
It is likely, however, that most players will successfully play back a WebM file with codecs other than the ones
supported in the spec. To be on the safe side, however, you can set the options' `type` property to `'matroska'`, which
will internally label the file as a general Matroska file. If you do this, your output file should also have the .mkv
extension.
### Size "limits"

@@ -229,0 +243,0 @@ This library can mux WebM files up to a total size of ~4398 GB and with a Matroska Cluster size of ~34 GB.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc