mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 10:53:50 +02:00
* add a test * recognize as input format * scaffold flac demuxer * implement getting metadata * Implement mime type * read all metadata + deduplicate stubs * Read first packet * copyright headers * read the first packet * Get entire first packet, work on advancing * iterate over all samples * testable with bun * stub out metadata support * parse descriptive metadata * All in 1 file seems more appropriate to the philosophy * some parameters are not needed anymore all within 1 class * skip over bytes we are sure are not the syncword * run prettier * timestamp is determined based on passed blocks, not maximumBlockSize * no binary search needed! * simplifications * Finish demuxer reading sequentially * more tests + add a file with a seektable * don't throw if (this.audioInfo.minimumBlockSize !== this.audioInfo.maximumBlockSize * Add docs * Update format compatibility table * Simplification * confirm conversion is working * Finish * Resolve TODO comment * Support images (read-only) * Returning description as Uint8Array * Cleanup of demuxer * Misc renames * Object on same line * Resolve first batch of comments * Throw errors on corrupt blocks, correctly use requestSlice() * Fix description field * Explain why last frame is a bit shorter * Add FLAC to README * Put track backings below demuxer * convert to methods * Reorder container checking * getBlockSize() -> readBlockSize() * bitStream -> bitstream * better naming for bytes * use .skip() * Don't return blockSize twice in readFlacFrameHeader * Use enum + switch to distinguish Flac block types * Use else-if * Use else-if * Compressed switch statement * readCodedNumber * Update flac-misc.ts * We don't need the bits variable at all * reorder functions in flac-demuxer * Handle gracefully not being able to load another sample * Update flac-demuxer.ts * blockingbit null * use async instead of promise.resolve * use binary search * Replace recursion with while loop * Add mutex to getPacket() * Load more data not in getPacketAtIndex, but outside * Apply suggestion from @Vanilagy Co-authored-by: David P. <[email protected]> * computeDuration() reads last packet * Update flac-demuxer.ts * share vorbis comment reading logic * reuse vorbis comment writing logic, set vendor always to "Mediabunny" * flush after writign * Use FileSlice.tempFromBytes * assert !== null * fixing nitpicks * apply suggestions * fix ogg * We are now muxing images * apply suggestion * Update src/flac/flac-muxer.ts Co-authored-by: David P. <[email protected]> * apply suggestion * readSampleRate() * seek outside writeHeader() * mention vorbis metadata + add to metadatatags comment * should be able to -> can * Add test in metadata tags * Add test for packets being byte identical after remuxing * compare to null * no casting to uint8array * make test pass * Update flac-muxer.ts * Call validateAudioChunkMetadata() and validateAndNormalizeTimestamp() * `onFrame` option * emit frames using onFrame * Run prettier over files * Fix FLAC PICTURE block logic, small other changes * Update docs * Remove .only modifier * fix remuxing and add test * Don't throw error if parsing fails in header, since hitting a syncword might just be coincidential * Fix remaining type errors --------- Co-authored-by: David P. <[email protected]>
100 lines
3.4 KiB
Markdown
100 lines
3.4 KiB
Markdown
# Input formats
|
|
|
|
Mediabunny supports a wide variety of commonly used container formats for reading input files. These *input formats* are used in two ways:
|
|
- When creating an `Input`, they are used to specify the list of supported container formats. See [Creating a new input](./reading-media-files#creating-a-new-input) for more.
|
|
- Given an existing `Input`, its `getFormat` method returns the *actual* format of the file as an `InputFormat`.
|
|
|
|
## Input format properties
|
|
|
|
Retrieve the full written name of the format like this:
|
|
```ts
|
|
inputFormat.name; // => 'MP4'
|
|
```
|
|
|
|
You can also retrieve the format's base MIME type:
|
|
```ts
|
|
inputFormat.mimeType; // => 'video/mp4'
|
|
```
|
|
|
|
If you want a file's full MIME type, which depends on track codecs, use [`getMimeType`](./reading-media-files#reading-file-metadata) on `Input` instead.
|
|
|
|
## Input format singletons
|
|
|
|
Since input formats don't require any additional configuration, each input format is directly available as an exported singleton instance:
|
|
```ts
|
|
import {
|
|
MP4, // MP4 input format singleton
|
|
QTFF, // QuickTime File Format input format singleton
|
|
MATROSKA, // Matroska input format singleton
|
|
WEBM, // WebM input format singleton
|
|
MP3, // MP3 input format singleton
|
|
WAVE, // WAVE input format singleton
|
|
OGG, // Ogg input format singleton
|
|
ADTS, // ADTS input format singleton
|
|
FLAC, // FLAC input format singleton
|
|
} from 'mediabunny';
|
|
```
|
|
|
|
You can use these singletons when creating an input:
|
|
```ts
|
|
import { Input, MP3, WAVE, OGG } from 'mediabunny';
|
|
|
|
const input = new Input({
|
|
formats: [MP3, WAVE, OGG],
|
|
// ...
|
|
});
|
|
```
|
|
|
|
You can also use them for checking the actual format of an `Input`:
|
|
```ts
|
|
import { MP3 } from 'mediabunny';
|
|
|
|
const isMp3 = (await input.getFormat()) === MP3;
|
|
```
|
|
|
|
There is a special `ALL_FORMATS` constant exported by Mediabunny which contains every input format singleton. Use this constant if you want to support as many formats as possible:
|
|
```ts
|
|
import { Input, ALL_FORMATS } from 'mediabunny';
|
|
|
|
const input = new Input({
|
|
formats: ALL_FORMATS,
|
|
// ...
|
|
});
|
|
```
|
|
|
|
::: info
|
|
Using `ALL_FORMATS` means [demuxers](https://en.wikipedia.org/wiki/Demultiplexer_(media_file)) for all formats must be included in the bundle, which can increase the bundle size significantly. Use it only if you need to support all formats.
|
|
:::
|
|
|
|
## Input format class hierarchy
|
|
|
|
In addition to singletons, input format classes are structured hierarchically:
|
|
- `InputFormat` (abstract)
|
|
- `IsobmffInputFormat` (abstract)
|
|
- `Mp4InputFormat`
|
|
- `QuickTimeInputFormat`
|
|
- `MatroskaInputFormat`
|
|
- `WebMInputFormat`
|
|
- `Mp3InputFormat`
|
|
- `WaveInputFormat`
|
|
- `OggInputFormat`
|
|
- `AdtsInputFormat`
|
|
- `FlacInputFormat`
|
|
|
|
This means you can also perform input format checks using `instanceof` instead of `===` comparisons. For example:
|
|
```ts
|
|
import { Mp3InputFormat } from 'mediabunny';
|
|
|
|
// Check if the file is MP3:
|
|
(await input.getFormat()) instanceof Mp3InputFormat;
|
|
|
|
// Check if the file is Matroska (MKV + WebM):
|
|
(await input.getFormat()) instanceof MatroskaInputFormat;
|
|
|
|
// Check if the file is MP4 or QuickTime:
|
|
(await input.getFormat()) instanceof IsobmffInputFormat;
|
|
```
|
|
|
|
::: info
|
|
Well, actually 🤓☝️, the QuickTime File Format is technically not an instance of the ISO Base Media File Format (ISOBMFF) - instead, ISOBMFF is a standard originally inspired by QTFF. However, as the two are extremely similar and are used in the same way, we consider QTFF an instance of `IsobmffInputFormat` for convenience.
|
|
::: |