mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 19:03:46 +02:00
Add getMimeType to Output & other small adjustments
This commit is contained in:
+5
-10
@@ -7,7 +7,7 @@ import { PacketRetrievalOptions } from '../media-sink';
|
||||
import { assert, AsyncMutex, findLast, roundToPrecision, toDataView, UNDETERMINED_LANGUAGE } from '../misc';
|
||||
import { EncodedPacket, PLACEHOLDER_DATA } from '../packet';
|
||||
import { Reader } from '../reader';
|
||||
import { computeOggPageCrc, extractSampleMetadata, OggCodecInfo } from './ogg-misc';
|
||||
import { buildOggMimeType, computeOggPageCrc, extractSampleMetadata, OggCodecInfo } from './ogg-misc';
|
||||
import { MAX_PAGE_HEADER_SIZE, MAX_PAGE_SIZE, MIN_PAGE_HEADER_SIZE, OggReader, Page } from './ogg-reader';
|
||||
|
||||
type LogicalBitstream = {
|
||||
@@ -366,16 +366,11 @@ export class OggDemuxer extends Demuxer {
|
||||
async getMimeType() {
|
||||
await this.readMetadata();
|
||||
|
||||
let string = 'audio/ogg';
|
||||
const codecStrings = await Promise.all(this.tracks.map(x => x.getCodecParameterString()));
|
||||
|
||||
if (this.tracks.length > 0) {
|
||||
const codecMimeTypes = await Promise.all(this.tracks.map(x => x.getCodecParameterString()));
|
||||
const uniqueCodecMimeTypes = [...new Set(codecMimeTypes.filter(Boolean))];
|
||||
|
||||
string += `; codecs="${uniqueCodecMimeTypes.join(', ')}"`;
|
||||
}
|
||||
|
||||
return string;
|
||||
return buildOggMimeType({
|
||||
codecStrings: codecStrings.filter(Boolean) as string[],
|
||||
});
|
||||
}
|
||||
|
||||
async getTracks() {
|
||||
|
||||
@@ -93,3 +93,16 @@ export const extractSampleMetadata = (
|
||||
vorbisBlockSize: currentBlocksize,
|
||||
};
|
||||
};
|
||||
|
||||
export const buildOggMimeType = (info: {
|
||||
codecStrings: string[];
|
||||
}) => {
|
||||
let string = 'audio/ogg';
|
||||
|
||||
if (info.codecStrings) {
|
||||
const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
|
||||
string += `; codecs="${uniqueCodecMimeTypes.join(', ')}"`;
|
||||
}
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
+34
-5
@@ -1,12 +1,13 @@
|
||||
import { OPUS_INTERNAL_SAMPLE_RATE, validateAudioChunkMetadata } from '../codec';
|
||||
import { parseModesFromVorbisSetupPacket, parseOpusIdentificationHeader } from '../codec-data';
|
||||
import { assert, setInt64, toDataView, toUint8Array } from '../misc';
|
||||
import { assert, promiseWithResolvers, setInt64, toDataView, toUint8Array } from '../misc';
|
||||
import { Muxer } from '../muxer';
|
||||
import { Output, OutputAudioTrack } from '../output';
|
||||
import { OggOutputFormat } from '../output-format';
|
||||
import { EncodedPacket } from '../packet';
|
||||
import { Writer } from '../writer';
|
||||
import {
|
||||
buildOggMimeType,
|
||||
computeOggPageCrc,
|
||||
extractSampleMetadata,
|
||||
OggCodecInfo,
|
||||
@@ -46,6 +47,7 @@ export class OggMuxer extends Muxer {
|
||||
|
||||
private trackDatas: OggTrackData[] = [];
|
||||
private bosPagesWritten = false;
|
||||
private allTracksKnown = promiseWithResolvers();
|
||||
|
||||
private pageBytes = new Uint8Array(MAX_PAGE_SIZE);
|
||||
private pageView = new DataView(this.pageBytes.buffer);
|
||||
@@ -63,6 +65,14 @@ export class OggMuxer extends Muxer {
|
||||
// Nothin'
|
||||
}
|
||||
|
||||
async getMimeType() {
|
||||
await this.allTracksKnown.promise;
|
||||
|
||||
return buildOggMimeType({
|
||||
codecStrings: this.trackDatas.map(x => x.codecInfo.codec!),
|
||||
});
|
||||
}
|
||||
|
||||
addEncodedVideoPacket(): never {
|
||||
throw new Error('Video tracks are not supported.');
|
||||
}
|
||||
@@ -112,6 +122,11 @@ export class OggMuxer extends Muxer {
|
||||
this.queueHeaderPackets(newTrackData, meta);
|
||||
|
||||
this.trackDatas.push(newTrackData);
|
||||
|
||||
if (this.allTracksAreKnown()) {
|
||||
this.allTracksKnown.resolve();
|
||||
}
|
||||
|
||||
return newTrackData;
|
||||
}
|
||||
|
||||
@@ -250,12 +265,20 @@ export class OggMuxer extends Muxer {
|
||||
throw new Error('Subtitle tracks are not supported.');
|
||||
}
|
||||
|
||||
allTracksAreKnown() {
|
||||
for (const track of this.output._tracks) {
|
||||
if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
|
||||
return false; // We haven't seen a sample from this open track yet
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async interleavePages(isFinalCall = false) {
|
||||
if (!this.bosPagesWritten) {
|
||||
for (const track of this.output._tracks) {
|
||||
if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
|
||||
return; // We haven't seen a sample from this open track yet
|
||||
}
|
||||
if (!this.allTracksAreKnown()) {
|
||||
return; // We can't interleave yet as we don't yet know how many tracks we'll truly have
|
||||
}
|
||||
|
||||
// Write the header page for all bitstreams
|
||||
@@ -421,6 +444,10 @@ export class OggMuxer extends Muxer {
|
||||
override async onTrackClose() {
|
||||
const release = await this.mutex.acquire();
|
||||
|
||||
if (this.allTracksAreKnown()) {
|
||||
this.allTracksKnown.resolve();
|
||||
}
|
||||
|
||||
// Since a track is now closed, we may be able to write out chunks that were previously waiting
|
||||
await this.interleavePages();
|
||||
|
||||
@@ -430,6 +457,8 @@ export class OggMuxer extends Muxer {
|
||||
async finalize() {
|
||||
const release = await this.mutex.acquire();
|
||||
|
||||
this.allTracksKnown.resolve();
|
||||
|
||||
await this.interleavePages(true);
|
||||
|
||||
for (const trackData of this.trackDatas) {
|
||||
|
||||
Reference in New Issue
Block a user