mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-28 11:23:45 +02:00
Make computeDuration and getFirstTimestamp have the same implementations across the board
This commit is contained in:
@@ -151,15 +151,6 @@ export class AdtsDemuxer extends Demuxer {
|
||||
return this.tracks;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
await this.readMetadata();
|
||||
|
||||
const track = this.tracks[0];
|
||||
assert(track);
|
||||
|
||||
return track.computeDuration();
|
||||
}
|
||||
|
||||
async getMetadataTags() {
|
||||
const release = await this.readingMutex.acquire();
|
||||
|
||||
@@ -210,20 +201,11 @@ class AdtsAudioTrackBacking implements InputAudioTrackBacking {
|
||||
return 1;
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
getTimeResolution() {
|
||||
const sampleRate = this.getSampleRate();
|
||||
return sampleRate / SAMPLES_PER_AAC_FRAME;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,6 @@ export class InputAggregateDemuxer extends Demuxer {
|
||||
this.subInputs = subInputs;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const durations = await Promise.all(this.subInputs.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...durations);
|
||||
}
|
||||
|
||||
async getMetadataTags(): Promise<MetadataTags> {
|
||||
return {}; // todo?
|
||||
}
|
||||
@@ -112,14 +107,6 @@ class InputAggregateTrackBacking implements InputTrackBacking {
|
||||
return this.source.getVariant();
|
||||
}
|
||||
|
||||
getFirstTimestamp() {
|
||||
return this.source.getFirstTimestamp();
|
||||
}
|
||||
|
||||
computeDuration() {
|
||||
return this.source.computeDuration();
|
||||
}
|
||||
|
||||
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
|
||||
return this.source.getFirstPacket(options);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ export abstract class Demuxer {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
abstract computeDuration(): Promise<number>;
|
||||
abstract getTracks(): Promise<InputTrack[]>;
|
||||
abstract getMimeType(): Promise<string>;
|
||||
abstract getMetadataTags(): Promise<MetadataTags>;
|
||||
|
||||
@@ -86,12 +86,6 @@ export class FlacDemuxer extends Demuxer {
|
||||
this.reader = input._reader;
|
||||
}
|
||||
|
||||
override async computeDuration(): Promise<number> {
|
||||
await this.readMetadata();
|
||||
assert(this.track);
|
||||
return this.track.computeDuration();
|
||||
}
|
||||
|
||||
override async getMetadataTags(): Promise<MetadataTags> {
|
||||
await this.readMetadata();
|
||||
return this.metadataTags;
|
||||
@@ -546,11 +540,6 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
||||
return this.demuxer.audioInfo.numberOfChannels;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
getSampleRate() {
|
||||
assert(this.demuxer.audioInfo);
|
||||
return this.demuxer.audioInfo.sampleRate;
|
||||
@@ -579,10 +568,6 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
||||
return null;
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
async getDecoderConfig(): Promise<AudioDecoderConfig | null> {
|
||||
assert(this.demuxer.audioInfo);
|
||||
|
||||
|
||||
+6
-7
@@ -42,9 +42,6 @@ export interface InputTrackBacking {
|
||||
getDisposition(): TrackDisposition;
|
||||
getVariant(): ManifestInputVariant | null;
|
||||
|
||||
getFirstTimestamp(): Promise<number>;
|
||||
computeDuration(): Promise<number>;
|
||||
|
||||
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
||||
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
||||
getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
||||
@@ -158,13 +155,15 @@ export abstract class InputTrack {
|
||||
* may be positive or even negative. A negative starting timestamp means the track's timing has been offset. Samples
|
||||
* with a negative timestamp should not be presented.
|
||||
*/
|
||||
getFirstTimestamp() {
|
||||
return this._backing.getFirstTimestamp();
|
||||
async getFirstTimestamp() {
|
||||
const firstPacket = await this._backing.getFirstPacket({ metadataOnly: true });
|
||||
return firstPacket?.timestamp ?? 0;
|
||||
}
|
||||
|
||||
/** Returns the end timestamp of the last packet of this track, in seconds. */
|
||||
computeDuration() {
|
||||
return this._backing.computeDuration();
|
||||
async computeDuration() {
|
||||
const lastPacket = await this._backing.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-2
@@ -114,8 +114,13 @@ export class Input<S extends Source = Source> implements Disposable {
|
||||
* all tracks.
|
||||
*/
|
||||
async computeDuration() {
|
||||
const demuxer = await this._getDemuxer();
|
||||
return demuxer.computeDuration();
|
||||
const tracks = await this.getTracks();
|
||||
if (tracks.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const tracksDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(...tracksDurations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -260,12 +260,6 @@ export class IsobmffDemuxer extends Demuxer {
|
||||
this.reader = input._reader;
|
||||
}
|
||||
|
||||
override async computeDuration() {
|
||||
const tracks = await this.getTracks();
|
||||
const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...trackDurations);
|
||||
}
|
||||
|
||||
override async getTracks() {
|
||||
await this.readMetadata();
|
||||
return this.tracks.map(track => track.inputTrack!);
|
||||
@@ -2382,16 +2376,6 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
||||
return null;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
const firstPacket = await this.getFirstPacket({ metadataOnly: true });
|
||||
return firstPacket?.timestamp ?? 0;
|
||||
}
|
||||
|
||||
async getFirstPacket(options: PacketRetrievalOptions) {
|
||||
const regularPacket = await this.fetchPacketForSampleIndex(0, options);
|
||||
if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
|
||||
|
||||
@@ -99,12 +99,6 @@ class ManifestInputVariantDemuxer extends Demuxer {
|
||||
this.variant = variant;
|
||||
}
|
||||
|
||||
async computeDuration(): Promise<number> {
|
||||
const tracks = await this.getTracks();
|
||||
const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...trackDurations);
|
||||
}
|
||||
|
||||
async getMetadataTags(): Promise<MetadataTags> {
|
||||
return {}; // todo?
|
||||
}
|
||||
@@ -257,16 +251,6 @@ class ManifestInputVariantInputTrackBacking implements InputTrackBacking {
|
||||
return this.demuxer.variant;
|
||||
}
|
||||
|
||||
async getFirstTimestamp(): Promise<number> {
|
||||
const firstPacket = await this.getFirstPacket({ metadataOnly: true });
|
||||
return firstPacket?.timestamp ?? 0;
|
||||
}
|
||||
|
||||
async computeDuration(): Promise<number> {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
async createAdjustedPacket(packet: EncodedPacket, segment: ManifestInputSegment, track: InputTrack) {
|
||||
const mediaOffset = await this.demuxer.getMediaOffset(segment, track.input);
|
||||
|
||||
|
||||
@@ -266,12 +266,6 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
this.reader = input._reader;
|
||||
}
|
||||
|
||||
override async computeDuration() {
|
||||
const tracks = await this.getTracks();
|
||||
const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...trackDurations);
|
||||
}
|
||||
|
||||
async getTracks() {
|
||||
await this.readMetadata();
|
||||
return this.segments.flatMap(segment => segment.tracks.map(track => track.inputTrack!));
|
||||
@@ -1888,11 +1882,6 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
||||
return this.internalTrack.codecId;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
getName() {
|
||||
return this.internalTrack.name;
|
||||
}
|
||||
@@ -1901,11 +1890,6 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
||||
return this.internalTrack.languageCode;
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
const firstPacket = await this.getFirstPacket({ metadataOnly: true });
|
||||
return firstPacket?.timestamp ?? 0;
|
||||
}
|
||||
|
||||
getVariant() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -147,15 +147,6 @@ export class Mp3Demuxer extends Demuxer {
|
||||
return this.tracks;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
await this.readMetadata();
|
||||
|
||||
const track = this.tracks[0];
|
||||
assert(track);
|
||||
|
||||
return track.computeDuration();
|
||||
}
|
||||
|
||||
async getMetadataTags() {
|
||||
const release = await this.readingMutex.acquire();
|
||||
|
||||
@@ -221,20 +212,11 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
|
||||
return 1;
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
getTimeResolution() {
|
||||
assert(this.demuxer.firstFrameHeader);
|
||||
return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -485,12 +485,6 @@ export class MpegTsDemuxer extends Demuxer {
|
||||
return {}; // Nothing for now
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const tracks = await this.getTracks();
|
||||
const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...trackDurations);
|
||||
}
|
||||
|
||||
async getMimeType(): Promise<string> {
|
||||
await this.readMetadata();
|
||||
|
||||
@@ -846,16 +840,6 @@ export abstract class MpegTsTrackBacking implements InputTrackBacking {
|
||||
return null;
|
||||
}
|
||||
|
||||
async computeDuration(): Promise<number> {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
async getFirstTimestamp(): Promise<number> {
|
||||
const firstPacket = await this.getFirstPacket({ metadataOnly: true });
|
||||
return firstPacket?.timestamp ?? 0;
|
||||
}
|
||||
|
||||
abstract allPacketsAreKeyPackets(): boolean;
|
||||
abstract getReorderSize(): number;
|
||||
|
||||
|
||||
@@ -391,12 +391,6 @@ export class OggDemuxer extends Demuxer {
|
||||
return this.tracks;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const tracks = await this.getTracks();
|
||||
const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
|
||||
return Math.max(0, ...trackDurations);
|
||||
}
|
||||
|
||||
async getMetadataTags() {
|
||||
await this.readMetadata();
|
||||
return this.metadataTags;
|
||||
@@ -487,15 +481,6 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
||||
};
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
granulePositionToTimestampInSamples(granulePosition: number) {
|
||||
if (this.bitstream.codecInfo.codec === 'opus') {
|
||||
assert(this.bitstream.codecInfo.opusInfo);
|
||||
|
||||
@@ -327,15 +327,6 @@ export class WaveDemuxer extends Demuxer {
|
||||
return 'audio/wav';
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
await this.readMetadata();
|
||||
|
||||
const track = this.tracks[0];
|
||||
assert(track);
|
||||
|
||||
return track.computeDuration();
|
||||
}
|
||||
|
||||
async getTracks() {
|
||||
await this.readMetadata();
|
||||
return this.tracks;
|
||||
@@ -383,11 +374,6 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
||||
};
|
||||
}
|
||||
|
||||
async computeDuration() {
|
||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
||||
}
|
||||
|
||||
getNumberOfChannels() {
|
||||
assert(this.demuxer.audioInfo);
|
||||
return this.demuxer.audioInfo.numberOfChannels;
|
||||
@@ -421,10 +407,6 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
||||
};
|
||||
}
|
||||
|
||||
async getFirstTimestamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async getPacketAtIndex(
|
||||
packetIndex: number,
|
||||
options: PacketRetrievalOptions,
|
||||
|
||||
Reference in New Issue
Block a user