init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,3 @@
import type { MediaParserController } from '../controller/media-parser-controller';
import type { WorkerRequestPayload } from './worker-types';
export declare const forwardMediaParserControllerToWorker: (controller: MediaParserController) => ((message: WorkerRequestPayload) => void);

View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.forwardMediaParserControllerToWorker = void 0;
const log_1 = require("../log");
const forwardMediaParserControllerToWorker = (controller) => {
return (message) => {
if (message.type === 'request-pause') {
controller.pause();
return;
}
if (message.type === 'request-seek') {
controller.seek(message.payload);
return;
}
if (message.type === 'request-get-seeking-hints') {
controller
.getSeekingHints()
.then((hints) => {
postMessage({
type: 'response-get-seeking-hints',
payload: hints,
});
})
.catch((error) => {
postMessage({
type: 'response-error',
payload: error,
});
});
return;
}
if (message.type === 'request-simulate-seek') {
controller
.simulateSeek(message.payload)
.then((resolution) => {
postMessage({
type: 'response-simulate-seek',
nonce: message.nonce,
payload: resolution,
});
})
.catch((err) => {
postMessage({
type: 'response-error',
payload: err,
});
});
return;
}
if (message.type === 'request-resume') {
controller.resume();
return;
}
if (message.type === 'request-abort') {
controller.abort();
return;
}
const msg = `Unknown message type: ${message.type}`;
log_1.Log.error(msg);
throw new Error(msg);
};
};
exports.forwardMediaParserControllerToWorker = forwardMediaParserControllerToWorker;

View File

@@ -0,0 +1,9 @@
import type { MediaParserLogLevel } from '../log';
import type { SeekingHints } from '../seeking-hints';
import type { ResponseError } from './worker-types';
export declare const serializeError: ({ error, logLevel, seekingHints, }: {
error: Error;
logLevel: MediaParserLogLevel;
seekingHints: SeekingHints | null;
}) => ResponseError;
export declare const deserializeError: (error: ResponseError) => Error;

View File

@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deserializeError = exports.serializeError = void 0;
const errors_1 = require("../errors");
const log_1 = require("../log");
const serializeError = ({ error, logLevel, seekingHints, }) => {
var _a, _b, _c, _d, _e, _f, _g;
if (error instanceof errors_1.IsAnImageError) {
return {
type: 'response-error',
errorName: 'IsAnImageError',
dimensions: error.dimensions,
errorMessage: error.message,
errorStack: (_a = error.stack) !== null && _a !== void 0 ? _a : '',
fileName: error.fileName,
imageType: error.imageType,
mimeType: error.mimeType,
sizeInBytes: error.sizeInBytes,
};
}
if (error instanceof errors_1.IsAPdfError) {
return {
type: 'response-error',
errorName: 'IsAPdfError',
errorMessage: error.message,
errorStack: (_b = error.stack) !== null && _b !== void 0 ? _b : '',
mimeType: error.mimeType,
sizeInBytes: error.sizeInBytes,
fileName: error.fileName,
};
}
if (error instanceof errors_1.MediaParserAbortError) {
return {
type: 'response-error',
errorName: 'MediaParserAbortError',
errorMessage: error.message,
errorStack: (_c = error.stack) !== null && _c !== void 0 ? _c : '',
seekingHints,
};
}
if (error instanceof TypeError) {
return {
type: 'response-error',
errorName: 'TypeError',
errorMessage: error.message,
errorStack: (_d = error.stack) !== null && _d !== void 0 ? _d : '',
};
}
if (error.name === 'AbortError') {
return {
type: 'response-error',
errorName: 'AbortError',
errorMessage: error.message,
errorStack: (_e = error.stack) !== null && _e !== void 0 ? _e : '',
};
}
if (error.name === 'NotReadableError') {
return {
type: 'response-error',
errorName: 'NotReadableError',
errorMessage: error.message,
errorStack: (_f = error.stack) !== null && _f !== void 0 ? _f : '',
};
}
if (error.name !== 'Error') {
log_1.Log.warn(logLevel, `Original error was of type ${error.name} did not properly propagate`);
}
return {
type: 'response-error',
errorName: 'Error',
errorMessage: error.message,
errorStack: (_g = error.stack) !== null && _g !== void 0 ? _g : '',
};
};
exports.serializeError = serializeError;
const deserializeError = (error) => {
switch (error.errorName) {
case 'IsAnImageError':
return new errors_1.IsAnImageError({
dimensions: error.dimensions,
fileName: error.fileName,
imageType: error.imageType,
mimeType: error.mimeType,
sizeInBytes: error.sizeInBytes,
message: error.errorMessage,
});
case 'IsAPdfError':
return new errors_1.IsAPdfError({
fileName: error.fileName,
mimeType: error.mimeType,
sizeInBytes: error.sizeInBytes,
message: error.errorMessage,
});
case 'IsAnUnsupportedFileTypeError':
return new errors_1.IsAnUnsupportedFileTypeError({
fileName: error.fileName,
mimeType: error.mimeType,
sizeInBytes: error.sizeInBytes,
message: error.errorMessage,
});
case 'MediaParserAbortError':
return new errors_1.MediaParserAbortError(error.errorMessage);
case 'Error':
return new Error(error.errorMessage);
case 'AbortError':
return new Error(error.errorMessage);
// TODO: Document 2GB limit
case 'NotReadableError':
return new Error(error.errorMessage);
case 'TypeError':
return new TypeError(error.errorMessage);
default:
throw new Error(`Unknown error name: ${error}`);
}
};
exports.deserializeError = deserializeError;

View File

@@ -0,0 +1,283 @@
import type { M3uAssociatedPlaylist, M3uStream } from '../containers/m3u/get-streams';
import type { SelectM3uAssociatedPlaylistsFnOptions, SelectM3uStreamFnOptions } from '../containers/m3u/select-stream';
import type { ImageType } from '../errors';
import type { Options, ParseMediaFields } from '../fields';
import type { MediaParserDimensions } from '../get-dimensions';
import type { MediaParserLocation } from '../get-location';
import type { MediaParserAudioCodec, MediaParserTrack, MediaParserVideoCodec } from '../get-tracks';
import type { MediaParserMetadataEntry } from '../metadata/get-metadata';
import type { MediaParserContainer, MediaParserKeyframe, ParseMediaProgress, ParseMediaResult, ParseMediaSrc, SerializeableOptionalParseMediaParams } from '../options';
import type { MediaParserStructureUnstable } from '../parse-result';
import type { SeekingHints } from '../seeking-hints';
import type { MediaParserEmbeddedImage } from '../state/images';
import type { InternalStats } from '../state/parser-state';
import type { MediaParserAudioSample, MediaParserOnAudioTrackParams, MediaParserOnVideoTrackParams, MediaParserVideoSample } from '../webcodec-sample-types';
import type { SeekResolution } from '../work-on-seek-request';
export type ParseMediaOnWorkerPayload = {
type: 'request-worker';
src: ParseMediaSrc;
payload: Partial<SerializeableOptionalParseMediaParams<Options<ParseMediaFields>>>;
postAudioCodec: boolean;
postContainer: boolean;
postDimensions: boolean;
postUnrotatedDimensions: boolean;
postVideoCodec: boolean;
postFps: boolean;
postImages: boolean;
postInternalStats: boolean;
postIsHdr: boolean;
postKeyframes: boolean;
postLocation: boolean;
postM3uStreams: boolean;
postMetadata: boolean;
postMimeType: boolean;
postName: boolean;
postNumberOfAudioChannels: boolean;
postRotation: boolean;
postSampleRate: boolean;
postSize: boolean;
postSlowAudioBitrate: boolean;
postSlowDurationInSeconds: boolean;
postSlowFps: boolean;
postSlowKeyframes: boolean;
postSlowNumberOfFrames: boolean;
postSlowVideoBitrate: boolean;
postSlowStructure: boolean;
postTracks: boolean;
postDurationInSeconds: boolean;
postParseProgress: boolean;
postM3uStreamSelection: boolean;
postM3uAssociatedPlaylistsSelection: boolean;
postOnAudioTrack: boolean;
postOnVideoTrack: boolean;
};
type RequestPause = {
type: 'request-pause';
};
type RequestSeek = {
type: 'request-seek';
payload: number;
};
type RequestResume = {
type: 'request-resume';
};
type RequestGetSeekingHints = {
type: 'request-get-seeking-hints';
};
type RequestSimulateSeek = {
type: 'request-simulate-seek';
payload: number;
nonce: string;
};
type RequestAbort = {
type: 'request-abort';
};
type ResponseDone = {
type: 'response-done';
payload: ParseMediaResult<Options<ParseMediaFields>>;
seekingHints: SeekingHints | null;
};
type ResponseGetSeekingHints = {
type: 'response-get-seeking-hints';
payload: SeekingHints;
};
type ResponseSimulateSeek = {
type: 'response-simulate-seek';
nonce: string;
payload: SeekResolution;
};
type BaseError = {
errorStack: string;
errorMessage: string;
};
type AbortError = BaseError & {
errorName: 'AbortError';
};
type GenericError = BaseError & {
errorName: 'Error';
};
type NotReadableError = BaseError & {
errorName: 'NotReadableError';
};
type TypeError = BaseError & {
errorName: 'TypeError';
};
type IsAnImageError = BaseError & {
errorName: 'IsAnImageError';
imageType: ImageType;
dimensions: MediaParserDimensions | null;
mimeType: string | null;
sizeInBytes: number | null;
fileName: string | null;
};
type IsAPdfError = BaseError & {
errorName: 'IsAPdfError';
mimeType: string | null;
sizeInBytes: number | null;
fileName: string | null;
};
type IsAnUnsupportedFileTypeError = BaseError & {
errorName: 'IsAnUnsupportedFileTypeError';
mimeType: string | null;
sizeInBytes: number | null;
fileName: string | null;
};
type MediaParserAbortError = BaseError & {
errorName: 'MediaParserAbortError';
seekingHints: SeekingHints | null;
};
type AnyError = GenericError | IsAnImageError | IsAPdfError | IsAnUnsupportedFileTypeError | MediaParserAbortError | AbortError | NotReadableError | TypeError;
export type ResponseError = {
type: 'response-error';
} & AnyError;
export type ResponseCallbackPayload = {
callbackType: 'audio-codec';
value: MediaParserAudioCodec | null;
} | {
callbackType: 'container';
value: MediaParserContainer;
} | {
callbackType: 'dimensions';
value: MediaParserDimensions | null;
} | {
callbackType: 'unrotated-dimensions';
value: MediaParserDimensions | null;
} | {
callbackType: 'video-codec';
value: MediaParserVideoCodec | null;
} | {
callbackType: 'fps';
value: number | null;
} | {
callbackType: 'images';
value: MediaParserEmbeddedImage[];
} | {
callbackType: 'internal-stats';
value: InternalStats;
} | {
callbackType: 'is-hdr';
value: boolean;
} | {
callbackType: 'keyframes';
value: MediaParserKeyframe[] | null;
} | {
callbackType: 'location';
value: MediaParserLocation | null;
} | {
callbackType: 'm3u-streams';
value: M3uStream[] | null;
} | {
callbackType: 'metadata';
value: MediaParserMetadataEntry[];
} | {
callbackType: 'mime-type';
value: string | null;
} | {
callbackType: 'name';
value: string;
} | {
callbackType: 'number-of-audio-channels';
value: number | null;
} | {
callbackType: 'rotation';
value: number | null;
} | {
callbackType: 'sample-rate';
value: number | null;
} | {
callbackType: 'size';
value: number | null;
} | {
callbackType: 'slow-audio-bitrate';
value: number | null;
} | {
callbackType: 'slow-duration-in-seconds';
value: number;
} | {
callbackType: 'slow-fps';
value: number;
} | {
callbackType: 'slow-keyframes';
value: MediaParserKeyframe[];
} | {
callbackType: 'slow-number-of-frames';
value: number;
} | {
callbackType: 'slow-video-bitrate';
value: number | null;
} | {
callbackType: 'slow-structure';
value: MediaParserStructureUnstable;
} | {
callbackType: 'tracks';
value: MediaParserTrack[];
} | {
callbackType: 'unrotated-dimensions';
value: MediaParserDimensions | null;
} | {
callbackType: 'video-codec';
value: MediaParserVideoCodec | null;
} | {
callbackType: 'duration-in-seconds';
value: number | null;
} | {
callbackType: 'parse-progress';
value: ParseMediaProgress;
} | {
callbackType: 'm3u-stream-selection';
value: SelectM3uStreamFnOptions;
} | {
callbackType: 'on-audio-track';
value: MediaParserOnAudioTrackParams;
} | {
callbackType: 'on-video-track';
value: MediaParserOnVideoTrackParams;
} | {
callbackType: 'on-audio-sample';
value: MediaParserAudioSample;
trackId: number;
} | {
callbackType: 'on-video-sample';
value: MediaParserVideoSample;
trackId: number;
} | {
callbackType: 'track-done';
trackId: number;
} | {
callbackType: 'm3u-associated-playlists-selection';
value: SelectM3uAssociatedPlaylistsFnOptions;
};
export type ResponseOnCallbackRequest = {
type: 'response-on-callback-request';
nonce: string;
payload: ResponseCallbackPayload;
};
export type AcknowledgePayload = {
payloadType: 'void';
} | {
payloadType: 'm3u-stream-selection';
value: number;
} | {
payloadType: 'm3u-associated-playlists-selection';
value: M3uAssociatedPlaylist[];
} | {
payloadType: 'on-audio-track-response';
registeredCallback: boolean;
} | {
payloadType: 'on-video-track-response';
registeredCallback: boolean;
} | {
payloadType: 'on-sample-response';
registeredTrackDoneCallback: boolean;
};
export type AcknowledgeCallback = {
type: 'acknowledge-callback';
nonce: string;
} & AcknowledgePayload;
export type SignalErrorInCallback = {
type: 'signal-error-in-callback';
nonce: string;
};
export type WorkerRequestPayload = ParseMediaOnWorkerPayload | RequestResume | RequestPause | RequestAbort | RequestSeek | RequestGetSeekingHints | RequestSimulateSeek | AcknowledgeCallback | SignalErrorInCallback;
export type WorkerResponsePayload = ResponseDone | ResponseError | ResponseOnCallbackRequest | ResponseGetSeekingHints | ResponseSimulateSeek;
export {};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });