diff --git a/dev/player.html b/dev/player.html
index 7dd4d8f..4fbbe07 100644
--- a/dev/player.html
+++ b/dev/player.html
@@ -41,7 +41,7 @@ const input = new Metamuxer.Input({
source
});
-console.log(await input.getMimeType())
+console.log(await input.getMimeType());
let videoTrack = await input.getPrimaryVideoTrack();
let audioTrack = await input.getPrimaryAudioTrack();
diff --git a/src/index.ts b/src/index.ts
index 84a0be1..d30c020 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -68,7 +68,7 @@ export {
} from './codec';
export { Target, BufferTarget, StreamTarget, StreamTargetChunk, StreamTargetOptions } from './target';
export { Rotation, TransformationMatrix, AnyIterable, setVideoFrameTiming } from './misc';
-export { Source, BufferSource, BlobSource, UrlSource } from './source';
+export { Source, BufferSource, StreamSource, StreamSourceOptions, BlobSource, UrlSource } from './source';
export {
InputFormat,
IsobmffInputFormat,
diff --git a/src/source.ts b/src/source.ts
index 9357b76..28a06e5 100644
--- a/src/source.ts
+++ b/src/source.ts
@@ -32,16 +32,54 @@ export class BufferSource extends Source {
}
/** @internal */
- override async _read(start: number, end: number) {
+ async _read(start: number, end: number) {
return this._bytes.subarray(start, end);
}
/** @internal */
- override async _retrieveSize() {
+ async _retrieveSize() {
return this._bytes.byteLength;
}
}
+/** @public */
+export type StreamSourceOptions = {
+ read: (start: number, end: number) => Uint8Array | Promise;
+ getSize: () => number | Promise;
+};
+
+/** @public */
+export class StreamSource extends Source {
+ /** @internal */
+ _options: StreamSourceOptions;
+
+ constructor(options: StreamSourceOptions) {
+ if (!options || typeof options !== 'object') {
+ throw new TypeError('options must be an object.');
+ }
+ if (typeof options.read !== 'function') {
+ throw new TypeError('options.read must be a function.');
+ }
+ if (typeof options.getSize !== 'function') {
+ throw new TypeError('options.getSize must be a function.');
+ }
+
+ super();
+
+ this._options = options;
+ }
+
+ /** @internal */
+ async _read(start: number, end: number) {
+ return this._options.read(start, end);
+ }
+
+ /** @internal */
+ async _retrieveSize() {
+ return this._options.getSize();
+ }
+}
+
/** @public */
export class BlobSource extends Source {
/** @internal */
@@ -58,14 +96,14 @@ export class BlobSource extends Source {
}
/** @internal */
- override async _read(start: number, end: number) {
+ async _read(start: number, end: number) {
const slice = this._blob.slice(start, end);
const buffer = await slice.arrayBuffer();
return new Uint8Array(buffer);
}
/** @internal */
- override async _retrieveSize() {
+ async _retrieveSize() {
return this._blob.size;
}
}
@@ -140,7 +178,7 @@ export class UrlSource extends Source {
}
/** @internal */
- override async _read(start: number, end: number): Promise {
+ async _read(start: number, end: number): Promise {
if (this._fullData) {
return new Uint8Array(this._fullData, start, end - start);
}
@@ -158,7 +196,7 @@ export class UrlSource extends Source {
}
/** @internal */
- override async _retrieveSize(): Promise {
+ async _retrieveSize(): Promise {
if (this._fullData) {
return this._fullData.byteLength;
}
diff --git a/todo.txt b/todo.txt
index c37bc4b..03447b2 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,3 +1,2 @@
-- A stream source?? Or like a callback-driven source
- onHeader, etc callbacks for Matroska
- https://github.com/Vanilagy/mp4-muxer/issues/83 tell him it's possible now
\ No newline at end of file