mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-03 13:53:53 +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;
|
return this.tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
await this.readMetadata();
|
|
||||||
|
|
||||||
const track = this.tracks[0];
|
|
||||||
assert(track);
|
|
||||||
|
|
||||||
return track.computeDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMetadataTags() {
|
async getMetadataTags() {
|
||||||
const release = await this.readingMutex.acquire();
|
const release = await this.readingMutex.acquire();
|
||||||
|
|
||||||
@@ -210,20 +201,11 @@ class AdtsAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimeResolution() {
|
getTimeResolution() {
|
||||||
const sampleRate = this.getSampleRate();
|
const sampleRate = this.getSampleRate();
|
||||||
return sampleRate / SAMPLES_PER_AAC_FRAME;
|
return sampleRate / SAMPLES_PER_AAC_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
|
||||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ export class InputAggregateDemuxer extends Demuxer {
|
|||||||
this.subInputs = subInputs;
|
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> {
|
async getMetadataTags(): Promise<MetadataTags> {
|
||||||
return {}; // todo?
|
return {}; // todo?
|
||||||
}
|
}
|
||||||
@@ -112,14 +107,6 @@ class InputAggregateTrackBacking implements InputTrackBacking {
|
|||||||
return this.source.getVariant();
|
return this.source.getVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
getFirstTimestamp() {
|
|
||||||
return this.source.getFirstTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
computeDuration() {
|
|
||||||
return this.source.computeDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
|
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
|
||||||
return this.source.getFirstPacket(options);
|
return this.source.getFirstPacket(options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ export abstract class Demuxer {
|
|||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract computeDuration(): Promise<number>;
|
|
||||||
abstract getTracks(): Promise<InputTrack[]>;
|
abstract getTracks(): Promise<InputTrack[]>;
|
||||||
abstract getMimeType(): Promise<string>;
|
abstract getMimeType(): Promise<string>;
|
||||||
abstract getMetadataTags(): Promise<MetadataTags>;
|
abstract getMetadataTags(): Promise<MetadataTags>;
|
||||||
|
|||||||
@@ -86,12 +86,6 @@ export class FlacDemuxer extends Demuxer {
|
|||||||
this.reader = input._reader;
|
this.reader = input._reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async computeDuration(): Promise<number> {
|
|
||||||
await this.readMetadata();
|
|
||||||
assert(this.track);
|
|
||||||
return this.track.computeDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
override async getMetadataTags(): Promise<MetadataTags> {
|
override async getMetadataTags(): Promise<MetadataTags> {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
return this.metadataTags;
|
return this.metadataTags;
|
||||||
@@ -546,11 +540,6 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return this.demuxer.audioInfo.numberOfChannels;
|
return this.demuxer.audioInfo.numberOfChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
|
||||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSampleRate() {
|
getSampleRate() {
|
||||||
assert(this.demuxer.audioInfo);
|
assert(this.demuxer.audioInfo);
|
||||||
return this.demuxer.audioInfo.sampleRate;
|
return this.demuxer.audioInfo.sampleRate;
|
||||||
@@ -579,10 +568,6 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDecoderConfig(): Promise<AudioDecoderConfig | null> {
|
async getDecoderConfig(): Promise<AudioDecoderConfig | null> {
|
||||||
assert(this.demuxer.audioInfo);
|
assert(this.demuxer.audioInfo);
|
||||||
|
|
||||||
|
|||||||
+6
-7
@@ -42,9 +42,6 @@ export interface InputTrackBacking {
|
|||||||
getDisposition(): TrackDisposition;
|
getDisposition(): TrackDisposition;
|
||||||
getVariant(): ManifestInputVariant | null;
|
getVariant(): ManifestInputVariant | null;
|
||||||
|
|
||||||
getFirstTimestamp(): Promise<number>;
|
|
||||||
computeDuration(): Promise<number>;
|
|
||||||
|
|
||||||
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
||||||
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null>;
|
||||||
getNextPacket(packet: EncodedPacket, 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
|
* 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.
|
* with a negative timestamp should not be presented.
|
||||||
*/
|
*/
|
||||||
getFirstTimestamp() {
|
async getFirstTimestamp() {
|
||||||
return this._backing.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. */
|
/** Returns the end timestamp of the last packet of this track, in seconds. */
|
||||||
computeDuration() {
|
async computeDuration() {
|
||||||
return this._backing.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.
|
* all tracks.
|
||||||
*/
|
*/
|
||||||
async computeDuration() {
|
async computeDuration() {
|
||||||
const demuxer = await this._getDemuxer();
|
const tracks = await this.getTracks();
|
||||||
return demuxer.computeDuration();
|
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;
|
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() {
|
override async getTracks() {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
return this.tracks.map(track => track.inputTrack!);
|
return this.tracks.map(track => track.inputTrack!);
|
||||||
@@ -2382,16 +2376,6 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
|||||||
return null;
|
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) {
|
async getFirstPacket(options: PacketRetrievalOptions) {
|
||||||
const regularPacket = await this.fetchPacketForSampleIndex(0, options);
|
const regularPacket = await this.fetchPacketForSampleIndex(0, options);
|
||||||
if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
|
if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
|
||||||
|
|||||||
@@ -99,12 +99,6 @@ class ManifestInputVariantDemuxer extends Demuxer {
|
|||||||
this.variant = variant;
|
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> {
|
async getMetadataTags(): Promise<MetadataTags> {
|
||||||
return {}; // todo?
|
return {}; // todo?
|
||||||
}
|
}
|
||||||
@@ -257,16 +251,6 @@ class ManifestInputVariantInputTrackBacking implements InputTrackBacking {
|
|||||||
return this.demuxer.variant;
|
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) {
|
async createAdjustedPacket(packet: EncodedPacket, segment: ManifestInputSegment, track: InputTrack) {
|
||||||
const mediaOffset = await this.demuxer.getMediaOffset(segment, track.input);
|
const mediaOffset = await this.demuxer.getMediaOffset(segment, track.input);
|
||||||
|
|
||||||
|
|||||||
@@ -266,12 +266,6 @@ export class MatroskaDemuxer extends Demuxer {
|
|||||||
this.reader = input._reader;
|
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() {
|
async getTracks() {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
return this.segments.flatMap(segment => segment.tracks.map(track => track.inputTrack!));
|
return this.segments.flatMap(segment => segment.tracks.map(track => track.inputTrack!));
|
||||||
@@ -1888,11 +1882,6 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
|||||||
return this.internalTrack.codecId;
|
return this.internalTrack.codecId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
|
|
||||||
return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
return this.internalTrack.name;
|
return this.internalTrack.name;
|
||||||
}
|
}
|
||||||
@@ -1901,11 +1890,6 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
|||||||
return this.internalTrack.languageCode;
|
return this.internalTrack.languageCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
|
||||||
const firstPacket = await this.getFirstPacket({ metadataOnly: true });
|
|
||||||
return firstPacket?.timestamp ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getVariant() {
|
getVariant() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,15 +147,6 @@ export class Mp3Demuxer extends Demuxer {
|
|||||||
return this.tracks;
|
return this.tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
await this.readMetadata();
|
|
||||||
|
|
||||||
const track = this.tracks[0];
|
|
||||||
assert(track);
|
|
||||||
|
|
||||||
return track.computeDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMetadataTags() {
|
async getMetadataTags() {
|
||||||
const release = await this.readingMutex.acquire();
|
const release = await this.readingMutex.acquire();
|
||||||
|
|
||||||
@@ -221,20 +212,11 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimeResolution() {
|
getTimeResolution() {
|
||||||
assert(this.demuxer.firstFrameHeader);
|
assert(this.demuxer.firstFrameHeader);
|
||||||
return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;
|
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() {
|
getName() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -485,12 +485,6 @@ export class MpegTsDemuxer extends Demuxer {
|
|||||||
return {}; // Nothing for now
|
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> {
|
async getMimeType(): Promise<string> {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
|
|
||||||
@@ -846,16 +840,6 @@ export abstract class MpegTsTrackBacking implements InputTrackBacking {
|
|||||||
return null;
|
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 allPacketsAreKeyPackets(): boolean;
|
||||||
abstract getReorderSize(): number;
|
abstract getReorderSize(): number;
|
||||||
|
|
||||||
|
|||||||
@@ -391,12 +391,6 @@ export class OggDemuxer extends Demuxer {
|
|||||||
return this.tracks;
|
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() {
|
async getMetadataTags() {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
return this.metadataTags;
|
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) {
|
granulePositionToTimestampInSamples(granulePosition: number) {
|
||||||
if (this.bitstream.codecInfo.codec === 'opus') {
|
if (this.bitstream.codecInfo.codec === 'opus') {
|
||||||
assert(this.bitstream.codecInfo.opusInfo);
|
assert(this.bitstream.codecInfo.opusInfo);
|
||||||
|
|||||||
@@ -327,15 +327,6 @@ export class WaveDemuxer extends Demuxer {
|
|||||||
return 'audio/wav';
|
return 'audio/wav';
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
|
||||||
await this.readMetadata();
|
|
||||||
|
|
||||||
const track = this.tracks[0];
|
|
||||||
assert(track);
|
|
||||||
|
|
||||||
return track.computeDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTracks() {
|
async getTracks() {
|
||||||
await this.readMetadata();
|
await this.readMetadata();
|
||||||
return this.tracks;
|
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() {
|
getNumberOfChannels() {
|
||||||
assert(this.demuxer.audioInfo);
|
assert(this.demuxer.audioInfo);
|
||||||
return this.demuxer.audioInfo.numberOfChannels;
|
return this.demuxer.audioInfo.numberOfChannels;
|
||||||
@@ -421,10 +407,6 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getPacketAtIndex(
|
private async getPacketAtIndex(
|
||||||
packetIndex: number,
|
packetIndex: number,
|
||||||
options: PacketRetrievalOptions,
|
options: PacketRetrievalOptions,
|
||||||
|
|||||||
Reference in New Issue
Block a user