* 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]>
3.4 KiB
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 for more. - Given an existing
Input, itsgetFormatmethod returns the actual format of the file as anInputFormat.
Input format properties
Retrieve the full written name of the format like this:
inputFormat.name; // => 'MP4'
You can also retrieve the format's base MIME type:
inputFormat.mimeType; // => 'video/mp4'
If you want a file's full MIME type, which depends on track codecs, use getMimeType 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:
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:
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:
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:
import { Input, ALL_FORMATS } from 'mediabunny';
const input = new Input({
formats: ALL_FORMATS,
// ...
});
::: info
Using ALL_FORMATS means demuxers 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)Mp4InputFormatQuickTimeInputFormat
MatroskaInputFormatWebMInputFormat
Mp3InputFormatWaveInputFormatOggInputFormatAdtsInputFormatFlacInputFormat
This means you can also perform input format checks using instanceof instead of === comparisons. For example:
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.
:::