This commit is contained in:
Vanilagy
2025-09-05 18:59:13 +02:00
parent dd7804e5ab
commit b58476b1b0
19 changed files with 393 additions and 395 deletions
+32 -32
View File
@@ -30,7 +30,7 @@ import {
InputVideoTrack,
InputVideoTrackBacking,
} from '../input-track';
import { MediaMetadata } from '../metadata';
import { MetadataTags } from '../tags';
import { PacketRetrievalOptions } from '../media-sink';
import {
assert,
@@ -94,8 +94,8 @@ type Segment = {
clusters: Cluster[];
clusterLookupMutex: AsyncMutex;
metadata: MediaMetadata;
metadataCollected: boolean;
metadataTags: MetadataTags;
metadataTagsCollected: boolean;
};
type SeekEntry = {
@@ -246,25 +246,25 @@ export class MatroskaDemuxer extends Demuxer {
});
}
async getMetadata() {
async getMetadataTags() {
await this.readMetadata();
// Load metadata from each segment lazily (only once)
// Load metadata tags from each segment lazily (only once)
for (const segment of this.segments) {
if (!segment.metadataCollected) {
if (!segment.metadataTagsCollected) {
await this.loadSegmentMetadata(segment);
segment.metadataCollected = true;
segment.metadataTagsCollected = true;
}
}
// This is kinda handwavy, and how we handle multiple segments isn't suuuuper well-defined anyway; so we just
// shallow-merge metadata from all (usually just one) segments.
let metadata: MediaMetadata = {};
// shallow-merge metadata tags from all (usually just one) segments.
let metadataTags: MetadataTags = {};
for (const segment of this.segments) {
metadata = { ...metadata, ...segment.metadata };
metadataTags = { ...metadataTags, ...segment.metadataTags };
}
return metadata;
return metadataTags;
}
readMetadata() {
@@ -365,8 +365,8 @@ export class MatroskaDemuxer extends Demuxer {
clusters: [],
clusterLookupMutex: new AsyncMutex(),
metadata: {},
metadataCollected: false,
metadataTags: {},
metadataTagsCollected: false,
};
this.segments.push(this.currentSegment);
@@ -1426,8 +1426,8 @@ export class MatroskaDemuxer extends Demuxer {
}
}
this.currentSegment.metadata.images ??= [];
this.currentSegment.metadata.images.push({
this.currentSegment.metadataTags.images ??= [];
this.currentSegment.metadataTags.images.push({
data: this.currentAttachedFile.fileData,
mimeType: this.currentAttachedFile.fileMediaType,
kind,
@@ -1469,50 +1469,50 @@ export class MatroskaDemuxer extends Demuxer {
}
processTagValue(name: string, value: string | Uint8Array) {
if (!this.currentSegment?.metadata) return;
if (!this.currentSegment?.metadataTags) return;
const metadata = this.currentSegment.metadata;
metadata.raw ??= {};
metadata.raw[name] ??= value;
const metadataTags = this.currentSegment.metadataTags;
metadataTags.raw ??= {};
metadataTags.raw[name] ??= value;
if (typeof value === 'string') {
switch (name.toLowerCase()) {
case 'title': {
metadata.title ??= value;
metadataTags.title ??= value;
}; break;
case 'description': {
metadata.description ??= value;
metadataTags.description ??= value;
}; break;
case 'artist': {
metadata.artist ??= value;
metadataTags.artist ??= value;
}; break;
case 'album': {
metadata.album ??= value;
metadataTags.album ??= value;
}; break;
case 'album_artist': {
metadata.albumArtist ??= value;
metadataTags.albumArtist ??= value;
}; break;
case 'genre': {
metadata.genre ??= value;
metadataTags.genre ??= value;
}; break;
case 'comment': {
metadata.comment ??= value;
metadataTags.comment ??= value;
}; break;
case 'lyrics': {
metadata.lyrics ??= value;
metadataTags.lyrics ??= value;
}; break;
case 'date': {
const date = new Date(value);
if (!Number.isNaN(date.getTime())) {
metadata.date ??= date;
metadataTags.date ??= date;
}
}; break;
@@ -1523,10 +1523,10 @@ export class MatroskaDemuxer extends Demuxer {
const trackNumMax = parts[1] && Number.parseInt(parts[1], 10);
if (Number.isInteger(trackNum) && trackNum > 0) {
metadata.trackNumber ??= trackNum;
metadataTags.trackNumber ??= trackNum;
}
if (trackNumMax && Number.isInteger(trackNumMax) && trackNumMax > 0) {
metadata.trackNumberMax ??= trackNumMax;
metadataTags.tracksTotal ??= trackNumMax;
}
}; break;
@@ -1537,10 +1537,10 @@ export class MatroskaDemuxer extends Demuxer {
const discNumMax = discParts[1] && Number.parseInt(discParts[1], 10);
if (Number.isInteger(discNum) && discNum > 0) {
metadata.discNumber ??= discNum;
metadataTags.discNumber ??= discNum;
}
if (discNumMax && Number.isInteger(discNumMax) && discNumMax > 0) {
metadata.discNumberMax ??= discNumMax;
metadataTags.discsTotal ??= discNumMax;
}
}; break;
}
+14 -14
View File
@@ -424,10 +424,10 @@ export class MatroskaMuxer extends Muxer {
] });
};
const metadata = this.output._metadata;
const metadataTags = this.output._metadataTags;
const writtenTags = new Set<string>();
for (const { key, value } of keyValueIterator(metadata)) {
for (const { key, value } of keyValueIterator(metadataTags)) {
switch (key) {
case 'title': {
addSimpleTag('TITLE', value);
@@ -475,8 +475,8 @@ export class MatroskaMuxer extends Muxer {
}; break;
case 'trackNumber': {
const string = metadata.trackNumberMax !== undefined
? `${value}/${metadata.trackNumberMax}`
const string = metadataTags.tracksTotal !== undefined
? `${value}/${metadataTags.tracksTotal}`
: value.toString();
addSimpleTag('PART_NUMBER', string);
@@ -484,16 +484,16 @@ export class MatroskaMuxer extends Muxer {
}; break;
case 'discNumber': {
const string = metadata.discNumberMax !== undefined
? `${value}/${metadata.discNumberMax}`
const string = metadataTags.discsTotal !== undefined
? `${value}/${metadataTags.discsTotal}`
: value.toString();
addSimpleTag('DISC', string);
writtenTags.add('DISC');
}; break;
case 'trackNumberMax':
case 'discNumberMax': {
case 'tracksTotal':
case 'discsTotal': {
// Handled with trackNumber and discNumber respectively
}; break;
@@ -506,9 +506,9 @@ export class MatroskaMuxer extends Muxer {
}
}
if (metadata.raw) {
for (const key in metadata.raw) {
const value = metadata.raw[key]!;
if (metadataTags.raw) {
for (const key in metadataTags.raw) {
const value = metadataTags.raw[key]!;
if (value == null || writtenTags.has(key)) {
continue;
}
@@ -536,14 +536,14 @@ export class MatroskaMuxer extends Muxer {
}
private maybeCreateAttachments() {
const metadata = this.output._metadata;
if (!metadata.images || metadata.images.length === 0) {
const metadataTags = this.output._metadataTags;
if (!metadataTags.images || metadataTags.images.length === 0) {
return;
}
const existingFileUids = new Set<number>();
this.attachmentsElement = { id: EBMLId.Attachments, data: metadata.images.map((image): EBMLElement => {
this.attachmentsElement = { id: EBMLId.Attachments, data: metadataTags.images.map((image): EBMLElement => {
let imageName = image.name;
if (imageName === undefined) {
const baseName = image.kind === 'coverFront' ? 'cover' : image.kind === 'coverBack' ? 'back' : 'image';