mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-29 03:43:50 +02:00
FLAC container support (#95)
* 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]>
This commit is contained in:
+40
-1
@@ -28,6 +28,7 @@ import { WaveDemuxer } from './wave/wave-demuxer';
|
||||
import { MAX_FRAME_HEADER_SIZE, MIN_FRAME_HEADER_SIZE, readFrameHeader } from './adts/adts-reader';
|
||||
import { AdtsDemuxer } from './adts/adts-demuxer';
|
||||
import { readAscii } from './reader';
|
||||
import { FlacDemuxer } from './flac/flac-demuxer';
|
||||
|
||||
/**
|
||||
* Base class representing an input media file format.
|
||||
@@ -394,6 +395,37 @@ export class OggInputFormat extends InputFormat {
|
||||
return 'application/ogg';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* FLAC file format.
|
||||
*
|
||||
* Do not instantiate this class; use the {@link FLAC} singleton instead.
|
||||
*
|
||||
* @group Input formats
|
||||
* @public
|
||||
*/
|
||||
export class FlacInputFormat extends InputFormat {
|
||||
/** @internal */
|
||||
async _canReadInput(input: Input) {
|
||||
let slice = input._reader.requestSlice(0, 4);
|
||||
if (slice instanceof Promise) slice = await slice;
|
||||
if (!slice) return false;
|
||||
|
||||
return readAscii(slice, 4) === 'fLaC';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'FLAC';
|
||||
}
|
||||
|
||||
get mimeType() {
|
||||
return 'audio/flac';
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_createDemuxer(input: Input): Demuxer {
|
||||
return new FlacDemuxer(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ADTS file format.
|
||||
@@ -492,10 +524,17 @@ export const OGG = new OggInputFormat();
|
||||
*/
|
||||
export const ADTS = new AdtsInputFormat();
|
||||
|
||||
/**
|
||||
* FLAC input format singleton.
|
||||
* @group Input formats
|
||||
* @public
|
||||
*/
|
||||
export const FLAC = new FlacInputFormat();
|
||||
|
||||
/**
|
||||
* List of all input format singletons. If you don't need to support all input formats, you should specify the
|
||||
* formats individually for better tree shaking.
|
||||
* @group Input formats
|
||||
* @public
|
||||
*/
|
||||
export const ALL_FORMATS: InputFormat[] = [MP4, QTFF, MATROSKA, WEBM, WAVE, OGG, MP3, ADTS];
|
||||
export const ALL_FORMATS: InputFormat[] = [MP4, QTFF, MATROSKA, WEBM, WAVE, OGG, FLAC, MP3, ADTS];
|
||||
|
||||
Reference in New Issue
Block a user