diff --git a/dev/convert.html b/dev/convert.html
index 7824830..ea8de68 100644
--- a/dev/convert.html
+++ b/dev/convert.html
@@ -47,23 +47,6 @@
format: outputFormat,
target
});
- output.setMetadataTags({
- title: 'Bigggy',
- artist: 'Buck Bunny',
- images: [{
- data: blobData,
- kind: 'coverFront',
- mimeType: 'image/jpeg'
- }],
- trackNumber: 4,
- tracksTotal: 10,
- discNumber: 5,
- discNumberMax: 8,
- lyrics: "There's no way\nThat it's not going there",
- raw: {
- 'ENCODER': 'Mediabunny epic own encoder'
- }
- });
const conversion = await Mediabunny.Conversion.init({
input: new Mediabunny.Input({
@@ -109,16 +92,16 @@
*/
video: () => ({
//discard: true,
- crop: {
- left: 0,
- top: 0,
- width: 500,
- height: 500,
- },
- rotate: 90,
- width: 200,
- height: 500,
- fit: 'contain',
+ //crop: {
+ // left: 0,
+ // top: 0,
+ // width: 500,
+ // height: 500,
+ //},
+ //rotate: 90,
+ //width: 200,
+ //height: 500,
+ //fit: 'contain',
//forceTranscode: true,
//codec: 'avc',
//fit: 'contain',
@@ -141,6 +124,23 @@
//width: 200,
//height: 100,
}),
+ tags: {
+ title: 'Bigggy',
+ artist: 'Buck Bunny',
+ images: [{
+ data: blobData,
+ kind: 'coverFront',
+ mimeType: 'image/jpeg'
+ }],
+ trackNumber: 4,
+ tracksTotal: 10,
+ discNumber: 5,
+ discsTotal: 8,
+ lyrics: "There's no way\nThat it's not going there",
+ raw: {
+ 'AIGC': 'Mediabunny epic own encoder'
+ }
+ },
trim: {
start: 10,
end: 20
diff --git a/dev/demux.html b/dev/demux.html
index b844f7d..7df202b 100644
--- a/dev/demux.html
+++ b/dev/demux.html
@@ -14,12 +14,7 @@
source: new Mediabunny.BlobSource(file),
});
- const audioTrack = await input.getPrimaryAudioTrack();
- const sink = new Mediabunny.EncodedPacketSink(audioTrack);
-
- for await (const packet of sink.packets()) {
- console.log(packet);
- }
+ console.log(await input.getMetadataTags())
/*
const sink = new Mediabunny.EncodedPacketSink(videoTrack);
diff --git a/docs/guide/converting-media-files.md b/docs/guide/converting-media-files.md
index 91a3aae..164963d 100644
--- a/docs/guide/converting-media-files.md
+++ b/docs/guide/converting-media-files.md
@@ -49,7 +49,7 @@ await conversion.execute();
That's it! A `Conversion` simply takes an instance of `Input` and `Output`, then reads the data from the input and writes it to the output. If you're unfamiliar with [`Input`](./reading-media-files) and [`Output`](./writing-media-files), check out their respective guides.
::: info
-The `Output` passed to the `Conversion` must be *fresh*; that is, it must have no added tracks and be in the `'pending'` state (not started yet).
+The `Output` passed to the `Conversion` must be *fresh*; that is, it must have no added tracks or metadata tags and be in the `'pending'` state (not started yet).
:::
Unconfigured, the conversion process handles all the details automatically, such as:
@@ -299,17 +299,17 @@ By default, any [descriptive metadata tags](../api/MetadataTags.md) of the input
// Set your own metadata:
const conversion = await Conversion.init({
// ...
- tags: () => ({
+ tags: {
title: 're:Turning',
artist: 'Alexander Panos',
- }),
+ },
// ...
});
// Or, augment the input's metadata:
const conversion = await Conversion.init({
// ...
- tags: inputTags => ({
+ tags: (inputTags) => ({
...inputTags, // Keep the existing metadata
images: [{ // And add cover art
data: new Uint8Array(...),
@@ -324,7 +324,7 @@ const conversion = await Conversion.init({
// Or, remove all metadata
const conversion = await Conversion.init({
// ...
- tags: () => ({}),
+ tags: {},
// ...
});
```
diff --git a/src/conversion.ts b/src/conversion.ts
index 10eb8f8..066a392 100644
--- a/src/conversion.ts
+++ b/src/conversion.ts
@@ -89,13 +89,13 @@ export type ConversionOptions = {
};
/**
- * A callback that returns or resolves to the descriptive metadata tags that should be written to the output file.
- * As input, this function will be passed the tags of the input file, allowing you to modify, augment or extend
- * them.
+ * An object or a callback that returns or resolves to an object containing the descriptive metadata tags that
+ * should be written to the output file. If a function is passed, it will be passed the tags of the input file as
+ * its first argument, allowing you to modify, augment or extend them.
*
* If no function is set, the input's metadata tags will be copied to the output.
*/
- tags?: (inputTags: MetadataTags) => MaybePromise;
+ tags?: MetadataTags | ((inputTags: MetadataTags) => MaybePromise);
};
/**
@@ -395,8 +395,12 @@ export class Conversion {
if (!(options.output instanceof Output)) {
throw new TypeError('options.output must be an Output.');
}
- if (options.output._tracks.length > 0 || options.output.state !== 'pending') {
- throw new TypeError('options.output must be fresh: no tracks added and not started.');
+ if (
+ options.output._tracks.length > 0
+ || Object.keys(options.output._metadataTags).length > 0
+ || options.output.state !== 'pending'
+ ) {
+ throw new TypeError('options.output must be fresh: no tracks or metadata tags added and not started.');
}
if (typeof options.video !== 'function') {
@@ -426,8 +430,15 @@ export class Conversion {
&& options.trim.start >= options.trim.end) {
throw new TypeError('options.trim.start must be less than options.trim.end.');
}
- if (options.tags !== undefined && typeof options.tags !== 'function') {
- throw new TypeError('options.tags, when provided, must be a function.');
+ if (
+ options.tags !== undefined
+ && (typeof options.tags !== 'object' || !options.tags)
+ && typeof options.tags !== 'function'
+ ) {
+ throw new TypeError('options.tags, when provided, must be an object or a function.');
+ }
+ if (typeof options.tags === 'object') {
+ validateMetadataTags(options.tags);
}
this._options = options;
@@ -519,7 +530,9 @@ export class Conversion {
let outputTags: MetadataTags;
if (this._options.tags) {
- const result = await this._options.tags(inputTags);
+ const result = typeof this._options.tags === 'function'
+ ? await this._options.tags(inputTags)
+ : this._options.tags;
validateMetadataTags(result);
outputTags = result;