feat: temp save
This commit is contained in:
@@ -2,7 +2,6 @@ import {
|
||||
type EbmlTagType,
|
||||
EbmlTagIdEnum,
|
||||
EbmlTagPosition,
|
||||
type EbmlCuePointTagType,
|
||||
type EbmlTracksTagType,
|
||||
type EbmlInfoTagType,
|
||||
type EbmlCuesTagType,
|
||||
@@ -127,13 +126,11 @@ export class TrackEntry extends TagWithArktype({
|
||||
}),
|
||||
}) {}
|
||||
|
||||
const TracksSchema = type({
|
||||
tracks: type.instanceOf(TrackEntry).array(),
|
||||
});
|
||||
|
||||
export class Tracks extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.Tracks,
|
||||
schema: TracksSchema,
|
||||
schema: type({
|
||||
tracks: type.instanceOf(TrackEntry).array(),
|
||||
}),
|
||||
extract: simpleMasterExtractor({
|
||||
[EbmlTagIdEnum.TrackEntry]: {
|
||||
key: 'tracks',
|
||||
@@ -148,13 +145,11 @@ export interface EbmlSeekEntry {
|
||||
seekPosition: number;
|
||||
}
|
||||
|
||||
export class EbmlHead {
|
||||
head: EbmlTagType;
|
||||
|
||||
constructor(head: EbmlTagType) {
|
||||
this.head = head;
|
||||
}
|
||||
}
|
||||
export class MHead extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.EBML,
|
||||
schema: type({}),
|
||||
extract: () => ({}),
|
||||
}) {}
|
||||
|
||||
export class SimpleBlock extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.SimpleBlock,
|
||||
@@ -166,6 +161,12 @@ export class SimpleBlock extends TagWithArktype({
|
||||
}),
|
||||
}) {}
|
||||
|
||||
export class Block extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.Block,
|
||||
schema: type({}),
|
||||
extract: () => ({}),
|
||||
}) {}
|
||||
|
||||
export class Cluster extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.Cluster,
|
||||
schema: type({
|
||||
@@ -191,88 +192,16 @@ export class Cluster extends TagWithArktype({
|
||||
}),
|
||||
}) {}
|
||||
|
||||
export interface TrackPositions {
|
||||
track: number;
|
||||
clusterPosition: number;
|
||||
relativePosition?: number;
|
||||
duration?: number;
|
||||
}
|
||||
export type CuePointType = typeof CuePoint.infer;
|
||||
|
||||
export class CuePoint {
|
||||
node: EbmlCuePointTagType;
|
||||
_timestamp: number;
|
||||
trackPositions: TrackPositions[];
|
||||
export class Cues {
|
||||
cues: CuePointType[];
|
||||
|
||||
get timestamp(): number {
|
||||
return this._timestamp;
|
||||
}
|
||||
constructor(
|
||||
public readonly tag: EbmlCuesTagType,
|
||||
cues: CuePointType[]
|
||||
) {}
|
||||
|
||||
get position(): number {
|
||||
return Math.max(...this.trackPositions.map((t) => t.clusterPosition));
|
||||
}
|
||||
|
||||
constructor(node: EbmlCuePointTagType) {
|
||||
this.node = node;
|
||||
this._timestamp = node.children.find((c) => c.id === EbmlTagIdEnum.CueTime)
|
||||
?.data as number;
|
||||
this.trackPositions = node.children
|
||||
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
|
||||
.map((t) => {
|
||||
if (
|
||||
t.id === EbmlTagIdEnum.CueTrackPositions &&
|
||||
t.position === EbmlTagPosition.End
|
||||
) {
|
||||
let track!: number;
|
||||
let clusterPosition!: number;
|
||||
let relativePosition: number | undefined;
|
||||
let duration: number | undefined;
|
||||
|
||||
for (const c of t.children) {
|
||||
if (c.id === EbmlTagIdEnum.CueTrack) {
|
||||
track = c.data as number;
|
||||
}
|
||||
if (c.id === EbmlTagIdEnum.CueClusterPosition) {
|
||||
clusterPosition = c.data as number;
|
||||
}
|
||||
if (c.id === EbmlTagIdEnum.CueRelativePosition) {
|
||||
relativePosition = c.data as number;
|
||||
}
|
||||
if (c.id === EbmlTagIdEnum.CueDuration) {
|
||||
duration = c.data as number;
|
||||
}
|
||||
}
|
||||
|
||||
if (track! >= 0 && clusterPosition! >= 0) {
|
||||
return {
|
||||
track: track!,
|
||||
clusterPosition: clusterPosition!,
|
||||
relativePosition,
|
||||
duration,
|
||||
} as TrackPositions;
|
||||
}
|
||||
throw new Error(
|
||||
`Tracking positions missing track of cluster position at ${t.startOffset}`
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((a): a is TrackPositions => !!a);
|
||||
}
|
||||
}
|
||||
|
||||
export class Cues extends TagWithArktype({
|
||||
id: EbmlTagIdEnum.Cues,
|
||||
schema: type({
|
||||
cues: type.instanceOf(CuePoint).array(),
|
||||
}),
|
||||
extract: simpleMasterExtractor({
|
||||
[EbmlTagIdEnum.CuePoint]: {
|
||||
key: 'cues',
|
||||
multi: true,
|
||||
extract: (t) => new CuePoint(t),
|
||||
},
|
||||
}),
|
||||
}) {
|
||||
findClosestCue(seekTime: number): CuePoint | null {
|
||||
const cues = this.cues;
|
||||
if (!cues || cues.length === 0) {
|
||||
@@ -282,22 +211,22 @@ export class Cues extends TagWithArktype({
|
||||
let left = 0;
|
||||
let right = cues.length - 1;
|
||||
|
||||
if (seekTime <= cues[0].timestamp) {
|
||||
if (seekTime <= cues[0].CueTime) {
|
||||
return cues[0];
|
||||
}
|
||||
|
||||
if (seekTime >= cues[right].timestamp) {
|
||||
if (seekTime >= cues[right].CueTime) {
|
||||
return cues[right];
|
||||
}
|
||||
|
||||
while (left <= right) {
|
||||
const mid = Math.floor((left + right) / 2);
|
||||
|
||||
if (cues[mid].timestamp === seekTime) {
|
||||
if (cues[mid].CueTime === seekTime) {
|
||||
return cues[mid];
|
||||
}
|
||||
|
||||
if (cues[mid].timestamp < seekTime) {
|
||||
if (cues[mid].CueTime < seekTime) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
|
||||
0
apps/playground/src/media/mkv/schema.ts
Normal file
0
apps/playground/src/media/mkv/schema.ts
Normal file
@@ -4,65 +4,56 @@ import type { EbmlMasterTagType, EbmlTagIdEnum, EbmlTagType } from 'konoebml';
|
||||
export type InferType<T> = T extends Type<infer U> ? U : never;
|
||||
|
||||
export interface TagWithArktypeOptions<
|
||||
I extends EbmlTagType['id'],
|
||||
T extends EbmlTagType,
|
||||
S extends Type<any>,
|
||||
> {
|
||||
id: I;
|
||||
id: T['id'];
|
||||
schema: S;
|
||||
extract: (tag: Extract<EbmlTagType, { id: I }>, schema: S) => InferType<S>;
|
||||
extract: (tag: T, schema: S) => InferType<S>;
|
||||
}
|
||||
|
||||
export type TagWithArktypeClassInstance<
|
||||
I extends EbmlTagType['id'],
|
||||
T extends EbmlTagType,
|
||||
S extends Type<any>,
|
||||
> = InferType<S> & {
|
||||
tag: Extract<EbmlTagType, { id: I }>;
|
||||
tag: T;
|
||||
};
|
||||
|
||||
export interface TagWithArktypeClass<
|
||||
I extends EbmlTagType['id'],
|
||||
T extends EbmlTagType,
|
||||
S extends Type<any>,
|
||||
> {
|
||||
new (
|
||||
tag: Extract<EbmlTagType, { id: I }>,
|
||||
validatedTag: InferType<S>
|
||||
): TagWithArktypeClassInstance<I, S>;
|
||||
new (tag: T, validatedTag: InferType<S>): TagWithArktypeClassInstance<T, S>;
|
||||
|
||||
fromTag<R extends TagWithArktypeClassInstance<I, S>>(
|
||||
fromTag<R extends TagWithArktypeClassInstance<T, S>>(
|
||||
this: new (
|
||||
tag: Extract<EbmlTagType, { id: I }>,
|
||||
tag: T,
|
||||
validatedTag: InferType<S>
|
||||
) => TagWithArktypeClassInstance<I, S>,
|
||||
tag: Extract<EbmlTagType, { id: I }>
|
||||
) => TagWithArktypeClassInstance<T, S>,
|
||||
tag: T
|
||||
): R;
|
||||
|
||||
id: I;
|
||||
id: T['id'];
|
||||
schema: S;
|
||||
}
|
||||
|
||||
export function TagWithArktype<
|
||||
I extends EbmlTagType['id'],
|
||||
S extends Type<any>,
|
||||
>({
|
||||
export function TagWithArktype<T extends EbmlTagType, S extends Type<any>>({
|
||||
id,
|
||||
schema,
|
||||
extract,
|
||||
}: TagWithArktypeOptions<I, S>): TagWithArktypeClass<I, S> {
|
||||
}: TagWithArktypeOptions<T, S>): TagWithArktypeClass<T, S> {
|
||||
const tagWithArktypeImpl = class TagWithArktypeImpl {
|
||||
static id = id;
|
||||
static schema = schema;
|
||||
|
||||
tag: Extract<EbmlTagType, { id: I }>;
|
||||
tag: T;
|
||||
|
||||
constructor(
|
||||
tag: Extract<EbmlTagType, { id: I }>,
|
||||
validatedTag: InferType<S>
|
||||
) {
|
||||
constructor(tag: T, validatedTag: InferType<S>) {
|
||||
Object.assign(this, validatedTag);
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
static fromTag(tag: Extract<EbmlTagType, { id: I }>) {
|
||||
static fromTag(tag: T) {
|
||||
const extractedData = extract(tag, schema);
|
||||
const validatedExtractedData = schema(extractedData);
|
||||
// biome-ignore lint/complexity/noThisInStatic: <explanation>
|
||||
@@ -70,7 +61,7 @@ export function TagWithArktype<
|
||||
}
|
||||
};
|
||||
|
||||
return tagWithArktypeImpl as unknown as TagWithArktypeClass<I, S>;
|
||||
return tagWithArktypeImpl as unknown as TagWithArktypeClass<T, S>;
|
||||
}
|
||||
|
||||
export type PredicateIdExtract<T, K> = Extract<T, { id: K }>;
|
||||
|
||||
Reference in New Issue
Block a user