mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-03 13:53:53 +02:00
Renaming
This commit is contained in:
@@ -44,7 +44,7 @@ import {
|
||||
Sample,
|
||||
} from './isobmff-muxer';
|
||||
import { parseOpusIdentificationHeader } from '../codec-data';
|
||||
import { MediaMetadata, RichImageData } from '../metadata';
|
||||
import { MetadataTags, RichImageData } from '../tags';
|
||||
|
||||
export class IsobmffBoxWriter {
|
||||
private helper = new Uint8Array(8);
|
||||
@@ -1274,11 +1274,11 @@ export const vtta = (notes: string) => box('vtta', [...textEncoder.encode(notes)
|
||||
const udta = (muxer: IsobmffMuxer) => {
|
||||
const boxes: Box[] = [];
|
||||
|
||||
// Depending on the format, metadata is written differently
|
||||
// Depending on the format, metadata tags are written differently
|
||||
if (muxer.isQuickTime) {
|
||||
addQuickTimeMetadataboxes(boxes, muxer.output._metadata);
|
||||
addQuickTimeMetadataTagBoxes(boxes, muxer.output._metadataTags);
|
||||
} else {
|
||||
const metaBox = meta(muxer.output._metadata);
|
||||
const metaBox = meta(muxer.output._metadataTags);
|
||||
if (metaBox) {
|
||||
boxes.push(metaBox);
|
||||
}
|
||||
@@ -1291,46 +1291,46 @@ const udta = (muxer: IsobmffMuxer) => {
|
||||
return box('udta', undefined, boxes);
|
||||
};
|
||||
|
||||
const addQuickTimeMetadataboxes = (boxes: Box[], metadata: MediaMetadata) => {
|
||||
const addQuickTimeMetadataTagBoxes = (boxes: Box[], tags: MetadataTags) => {
|
||||
// https://exiftool.org/TagNames/QuickTime.html (QuickTime UserData Tags)
|
||||
// For QuickTime files, metadata is dumped into the udta box
|
||||
// For QuickTime files, metadata tags are dumped into the udta box
|
||||
|
||||
for (const { key, value } of keyValueIterator(metadata)) {
|
||||
for (const { key, value } of keyValueIterator(tags)) {
|
||||
switch (key) {
|
||||
case 'title': {
|
||||
boxes.push(metadataStringBoxShort('©nam', value));
|
||||
boxes.push(metadataTagStringBoxShort('©nam', value));
|
||||
}; break;
|
||||
|
||||
case 'description': {
|
||||
boxes.push(metadataStringBoxShort('©des', value));
|
||||
boxes.push(metadataTagStringBoxShort('©des', value));
|
||||
}; break;
|
||||
|
||||
case 'artist': {
|
||||
boxes.push(metadataStringBoxShort('©ART', value));
|
||||
boxes.push(metadataTagStringBoxShort('©ART', value));
|
||||
}; break;
|
||||
|
||||
case 'album': {
|
||||
boxes.push(metadataStringBoxShort('©alb', value));
|
||||
boxes.push(metadataTagStringBoxShort('©alb', value));
|
||||
}; break;
|
||||
|
||||
case 'albumArtist': {
|
||||
boxes.push(metadataStringBoxShort('albr', value));
|
||||
boxes.push(metadataTagStringBoxShort('albr', value));
|
||||
}; break;
|
||||
|
||||
case 'genre': {
|
||||
boxes.push(metadataStringBoxShort('©gen', value));
|
||||
boxes.push(metadataTagStringBoxShort('©gen', value));
|
||||
}; break;
|
||||
|
||||
case 'date': {
|
||||
boxes.push(metadataStringBoxShort('©day', value.toISOString().slice(0, 10)));
|
||||
boxes.push(metadataTagStringBoxShort('©day', value.toISOString().slice(0, 10)));
|
||||
}; break;
|
||||
|
||||
case 'comment': {
|
||||
boxes.push(metadataStringBoxShort('©cmt', value));
|
||||
boxes.push(metadataTagStringBoxShort('©cmt', value));
|
||||
}; break;
|
||||
|
||||
case 'lyrics': {
|
||||
boxes.push(metadataStringBoxShort('©lyr', value));
|
||||
boxes.push(metadataTagStringBoxShort('©lyr', value));
|
||||
}; break;
|
||||
|
||||
case 'raw': {
|
||||
@@ -1338,9 +1338,9 @@ const addQuickTimeMetadataboxes = (boxes: Box[], metadata: MediaMetadata) => {
|
||||
}; break;
|
||||
|
||||
case 'discNumber':
|
||||
case 'discNumberMax':
|
||||
case 'discsTotal':
|
||||
case 'trackNumber':
|
||||
case 'trackNumberMax':
|
||||
case 'tracksTotal':
|
||||
case 'images': {
|
||||
// Not written for QuickTime (common Apple L)
|
||||
}; break;
|
||||
@@ -1349,15 +1349,15 @@ const addQuickTimeMetadataboxes = (boxes: Box[], metadata: MediaMetadata) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.raw) {
|
||||
for (const key in metadata.raw) {
|
||||
const value = metadata.raw[key];
|
||||
if (tags.raw) {
|
||||
for (const key in tags.raw) {
|
||||
const value = tags.raw[key];
|
||||
if (value == null || key.length !== 4 || boxes.some(x => x.type === key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
boxes.push(metadataStringBoxShort(key, value));
|
||||
boxes.push(metadataTagStringBoxShort(key, value));
|
||||
} else if (value instanceof Uint8Array) {
|
||||
boxes.push(box(key, Array.from(value)));
|
||||
}
|
||||
@@ -1365,7 +1365,7 @@ const addQuickTimeMetadataboxes = (boxes: Box[], metadata: MediaMetadata) => {
|
||||
}
|
||||
};
|
||||
|
||||
const metadataStringBoxShort = (name: string, value: string) => {
|
||||
const metadataTagStringBoxShort = (name: string, value: string) => {
|
||||
const encoded = textEncoder.encode(value);
|
||||
|
||||
return box(name, [
|
||||
@@ -1382,48 +1382,48 @@ const DATA_BOX_MIME_TYPE_MAP: Record<string, number> = {
|
||||
};
|
||||
|
||||
/** Metadata Box */
|
||||
const meta = (metadata: MediaMetadata) => {
|
||||
const meta = (tags: MetadataTags) => {
|
||||
const boxes: Box[] = [];
|
||||
|
||||
// https://exiftool.org/TagNames/QuickTime.html (QuickTime ItemList Tags)
|
||||
// This is the metadata format used for MP4 files
|
||||
|
||||
for (const { key, value } of keyValueIterator(metadata)) {
|
||||
for (const { key, value } of keyValueIterator(tags)) {
|
||||
switch (key) {
|
||||
case 'title': {
|
||||
boxes.push(metadataStringBoxLong('©nam', value));
|
||||
boxes.push(metadataTagStringBoxLong('©nam', value));
|
||||
}; break;
|
||||
|
||||
case 'description': {
|
||||
boxes.push(metadataStringBoxLong('©des', value));
|
||||
boxes.push(metadataTagStringBoxLong('©des', value));
|
||||
}; break;
|
||||
|
||||
case 'artist': {
|
||||
boxes.push(metadataStringBoxLong('©ART', value));
|
||||
boxes.push(metadataTagStringBoxLong('©ART', value));
|
||||
}; break;
|
||||
|
||||
case 'album': {
|
||||
boxes.push(metadataStringBoxLong('©alb', value));
|
||||
boxes.push(metadataTagStringBoxLong('©alb', value));
|
||||
}; break;
|
||||
|
||||
case 'albumArtist': {
|
||||
boxes.push(metadataStringBoxLong('aART', value));
|
||||
boxes.push(metadataTagStringBoxLong('aART', value));
|
||||
}; break;
|
||||
|
||||
case 'comment': {
|
||||
boxes.push(metadataStringBoxLong('©cmt', value));
|
||||
boxes.push(metadataTagStringBoxLong('©cmt', value));
|
||||
}; break;
|
||||
|
||||
case 'genre': {
|
||||
boxes.push(metadataStringBoxLong('©gen', value));
|
||||
boxes.push(metadataTagStringBoxLong('©gen', value));
|
||||
}; break;
|
||||
|
||||
case 'lyrics': {
|
||||
boxes.push(metadataStringBoxLong('©lyr', value));
|
||||
boxes.push(metadataTagStringBoxLong('©lyr', value));
|
||||
}; break;
|
||||
|
||||
case 'date': {
|
||||
boxes.push(metadataStringBoxLong('©day', value.toISOString().slice(0, 10)));
|
||||
boxes.push(metadataTagStringBoxLong('©day', value.toISOString().slice(0, 10)));
|
||||
}; break;
|
||||
|
||||
case 'images': {
|
||||
@@ -1449,7 +1449,7 @@ const meta = (metadata: MediaMetadata) => {
|
||||
u32(0),
|
||||
u16(0), // Empty
|
||||
u16(value),
|
||||
u16(metadata.trackNumberMax ?? 0),
|
||||
u16(tags.tracksTotal ?? 0),
|
||||
u16(0), // Empty
|
||||
]),
|
||||
]));
|
||||
@@ -1462,14 +1462,14 @@ const meta = (metadata: MediaMetadata) => {
|
||||
u32(0),
|
||||
u16(0), // Empty
|
||||
u16(value),
|
||||
u16(metadata.discNumberMax ?? 0),
|
||||
u16(tags.discsTotal ?? 0),
|
||||
u16(0), // Empty
|
||||
]),
|
||||
]));
|
||||
}; break;
|
||||
|
||||
case 'trackNumberMax':
|
||||
case 'discNumberMax':{
|
||||
case 'tracksTotal':
|
||||
case 'discsTotal':{
|
||||
// These are included with 'trackNumber' and 'discNumber' respectively
|
||||
}; break;
|
||||
|
||||
@@ -1481,15 +1481,15 @@ const meta = (metadata: MediaMetadata) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.raw) {
|
||||
for (const key in metadata.raw) {
|
||||
const value = metadata.raw[key];
|
||||
if (tags.raw) {
|
||||
for (const key in tags.raw) {
|
||||
const value = tags.raw[key];
|
||||
if (value == null || key.length !== 4 || boxes.some(x => x.type === key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
boxes.push(metadataStringBoxLong(key, value));
|
||||
boxes.push(metadataTagStringBoxLong(key, value));
|
||||
} else if (value instanceof Uint8Array) {
|
||||
boxes.push(box(key, undefined, [
|
||||
box('data', [
|
||||
@@ -1520,7 +1520,7 @@ const meta = (metadata: MediaMetadata) => {
|
||||
]);
|
||||
};
|
||||
|
||||
const metadataStringBoxLong = (name: string, value: string) => {
|
||||
const metadataTagStringBoxLong = (name: string, value: string) => {
|
||||
return box(name, undefined, [
|
||||
box('data', [
|
||||
u32(1), // Type indicator (UTF-8)
|
||||
|
||||
@@ -86,7 +86,7 @@ import {
|
||||
readU8,
|
||||
readAscii,
|
||||
} from '../reader';
|
||||
import { MediaMetadata, RichImageData } from '../metadata';
|
||||
import { MetadataTags, RichImageData } from '../tags';
|
||||
|
||||
// https://exiftool.org/TagNames/QuickTime.html
|
||||
const UDTA_STRING_KEYS = new Set([
|
||||
@@ -249,7 +249,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
movieTimescale = -1;
|
||||
movieDurationInTimescale = -1;
|
||||
isQuickTime = false;
|
||||
metadata: MediaMetadata = {};
|
||||
metadataTags: MetadataTags = {};
|
||||
currentMetadataKeys: Map<number, string> | null = null;
|
||||
|
||||
isFragmented = false;
|
||||
@@ -288,9 +288,9 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
});
|
||||
}
|
||||
|
||||
async getMetadata() {
|
||||
async getMetadataTags() {
|
||||
await this.readMetadata();
|
||||
return this.metadata;
|
||||
return this.metadataTags;
|
||||
}
|
||||
|
||||
readMetadata() {
|
||||
@@ -2057,12 +2057,12 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
for (const { boxInfo, slice } of iterator) {
|
||||
if (boxInfo.name !== 'meta' && !this.currentTrack) {
|
||||
const startPos = slice.filePos;
|
||||
this.metadata.raw ??= {};
|
||||
this.metadataTags.raw ??= {};
|
||||
|
||||
if (UDTA_STRING_KEYS.has(boxInfo.name)) {
|
||||
this.metadata.raw[boxInfo.name] ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.raw[boxInfo.name] ??= readMetadataStringShort(slice);
|
||||
} else {
|
||||
this.metadata.raw[boxInfo.name] ??= readBytes(slice, boxInfo.contentSize);
|
||||
this.metadataTags.raw[boxInfo.name] ??= readBytes(slice, boxInfo.contentSize);
|
||||
}
|
||||
|
||||
slice.filePos = startPos;
|
||||
@@ -2079,37 +2079,37 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
if (this.currentTrack) {
|
||||
this.currentTrack.name = textDecoder.decode(readBytes(slice, boxInfo.contentSize));
|
||||
} else {
|
||||
this.metadata.title ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.title ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©des': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.description ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.description ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©ART': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.artist ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.artist ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©alb': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.album ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.album ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case 'albr': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.albumArtist ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.albumArtist ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©gen': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.genre ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.genre ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2117,20 +2117,20 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
if (!this.currentTrack) {
|
||||
const date = new Date(readMetadataStringShort(slice));
|
||||
if (!Number.isNaN(date.getTime())) {
|
||||
this.metadata.date ??= date;
|
||||
this.metadataTags.date ??= date;
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©cmt': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.comment ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.comment ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©lyr': {
|
||||
if (!this.currentTrack) {
|
||||
this.metadata.lyrics ??= readMetadataStringShort(slice);
|
||||
this.metadataTags.lyrics ??= readMetadataStringShort(slice);
|
||||
}
|
||||
}; break;
|
||||
}
|
||||
@@ -2199,8 +2199,8 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
|
||||
const data = readDataBox(slice);
|
||||
|
||||
this.metadata.raw ??= {};
|
||||
this.metadata.raw[metadataKey] ??= data;
|
||||
this.metadataTags.raw ??= {};
|
||||
this.metadataTags.raw[metadataKey] ??= data;
|
||||
|
||||
switch (metadataKey) {
|
||||
case '©nam':
|
||||
@@ -2208,7 +2208,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.title':
|
||||
case 'title': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.title ??= data;
|
||||
this.metadataTags.title ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2218,7 +2218,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.description':
|
||||
case 'description': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.description ??= data;
|
||||
this.metadataTags.description ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2226,7 +2226,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.artist':
|
||||
case 'artist': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.artist ??= data;
|
||||
this.metadataTags.artist ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2235,14 +2235,14 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.album':
|
||||
case 'album': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.album ??= data;
|
||||
this.metadataTags.album ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
case 'aART':
|
||||
case 'album_artist': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.albumArtist ??= data;
|
||||
this.metadataTags.albumArtist ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2250,7 +2250,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.comment':
|
||||
case 'comment': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.comment ??= data;
|
||||
this.metadataTags.comment ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2259,14 +2259,14 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'com.apple.quicktime.genre':
|
||||
case 'genre': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.genre ??= data;
|
||||
this.metadataTags.genre ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
case '©lyr':
|
||||
case 'lyrics': {
|
||||
if (typeof data === 'string') {
|
||||
this.metadata.lyrics ??= data;
|
||||
this.metadataTags.lyrics ??= data;
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -2277,7 +2277,7 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
if (typeof data === 'string') {
|
||||
const date = new Date(data);
|
||||
if (!Number.isNaN(date.getTime())) {
|
||||
this.metadata.date ??= date;
|
||||
this.metadataTags.date ??= date;
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
@@ -2285,15 +2285,15 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
case 'covr':
|
||||
case 'com.apple.quicktime.artwork': {
|
||||
if (data instanceof RichImageData) {
|
||||
this.metadata.images ??= [];
|
||||
this.metadata.images.push({
|
||||
this.metadataTags.images ??= [];
|
||||
this.metadataTags.images.push({
|
||||
data: data.data,
|
||||
kind: 'coverFront',
|
||||
mimeType: data.mimeType,
|
||||
});
|
||||
} else if (data instanceof Uint8Array) {
|
||||
this.metadata.images ??= [];
|
||||
this.metadata.images.push({
|
||||
this.metadataTags.images ??= [];
|
||||
this.metadataTags.images.push({
|
||||
data,
|
||||
kind: 'coverFront',
|
||||
mimeType: 'image/*',
|
||||
@@ -2306,13 +2306,13 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
const view = toDataView(data);
|
||||
|
||||
const trackNumber = view.getUint16(2, false);
|
||||
const trackNumberMax = view.getUint16(4, false);
|
||||
const tracksTotal = view.getUint16(4, false);
|
||||
|
||||
if (trackNumber > 0) {
|
||||
this.metadata.trackNumber ??= trackNumber;
|
||||
this.metadataTags.trackNumber ??= trackNumber;
|
||||
}
|
||||
if (trackNumberMax > 0) {
|
||||
this.metadata.trackNumberMax ??= trackNumberMax;
|
||||
if (tracksTotal > 0) {
|
||||
this.metadataTags.tracksTotal ??= tracksTotal;
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
@@ -2326,10 +2326,10 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
const discNumberMax = view.getUint16(4, false);
|
||||
|
||||
if (discNumber > 0) {
|
||||
this.metadata.discNumber ??= discNumber;
|
||||
this.metadataTags.discNumber ??= discNumber;
|
||||
}
|
||||
if (discNumberMax > 0) {
|
||||
this.metadata.discNumberMax ??= discNumberMax;
|
||||
this.metadataTags.discsTotal ??= discNumberMax;
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { RichImageData } from '../metadata';
|
||||
import { RichImageData } from '../tags';
|
||||
import { textDecoder } from '../misc';
|
||||
import { FileSlice, readAscii, readBytes, readI32Be, readU16Be, readU32Be, readU64Be, readU8 } from '../reader';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user