Unpromise many input track methods

This commit is contained in:
Vanilagy
2025-02-08 16:32:34 +01:00
parent 1d823805cf
commit cd30c9faec
10 changed files with 150 additions and 160 deletions
+29 -35
View File
@@ -257,8 +257,7 @@ class Conversion {
continue;
}
const type = track.getType();
if (this.addedCounts[type] === outputTrackCounts[type].max) {
if (this.addedCounts[track.type] === outputTrackCounts[track.type].max) {
this.result.discardedTracks.push({
track,
reason: 'maxTrackCountOfTypeReached',
@@ -310,9 +309,7 @@ class Conversion {
}
async processVideoTrack(track: InputVideoTrack) {
const trackId = track.getId();
const sourceCodec = await track.getCodec();
const sourceCodec = track.codec;
if (!sourceCodec) {
this.result.discardedTracks.push({
track,
@@ -323,8 +320,8 @@ class Conversion {
let videoSource: VideoSource;
const originalWidth = await track.getCodedWidth();
const originalHeight = await track.getCodedHeight();
const originalWidth = track.codedWidth;
const originalHeight = track.codedHeight;
const originalAspectRatio = originalWidth / originalHeight;
let width = originalWidth;
@@ -368,16 +365,16 @@ class Conversion {
const meta: EncodedVideoChunkMetadata = { decoderConfig: decoderConfig ?? undefined };
for await (const sample of sink.samples(undefined, this.endTimestamp)) {
if (this.synchronizer.shouldWait(trackId, sample.timestamp)) {
if (this.synchronizer.shouldWait(track.id, sample.timestamp)) {
await this.synchronizer.wait(sample.timestamp);
}
await source.digest(sample, meta);
this.reportProgress(trackId, sample.timestamp + sample.duration);
this.reportProgress(track.id, sample.timestamp + sample.duration);
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
} else {
// We need to decode & reencode the video
@@ -396,8 +393,8 @@ class Conversion {
}
const encodableCodecs = await getEncodableVideoCodecs(videoCodecs, {
width: needsResize ? width : await track.getCodedWidth(),
height: needsResize ? height : await track.getCodedHeight(),
width: needsResize ? width : track.codedWidth,
height: needsResize ? height : track.codedHeight,
});
if (encodableCodecs.length === 0) {
this.result.discardedTracks.push({
@@ -410,7 +407,7 @@ class Conversion {
const encodingConfig: VideoEncodingConfig = {
codec: encodableCodecs[0]!,
bitrate: this.options.video?.bitrate ?? QUALITY_HIGH,
onEncodedSample: sample => this.reportProgress(trackId, sample.timestamp + sample.duration),
onEncodedSample: sample => this.reportProgress(track.id, sample.timestamp + sample.duration),
};
if (needsResize) {
@@ -432,7 +429,7 @@ class Conversion {
const iterator = sink.canvases(this.startTimestamp, this.endTimestamp);
for await (const { canvas, timestamp, duration } of iterator) {
if (this.synchronizer.shouldWait(trackId, timestamp)) {
if (this.synchronizer.shouldWait(track.id, timestamp)) {
await this.synchronizer.wait(timestamp);
}
@@ -458,7 +455,7 @@ class Conversion {
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
} else {
const source = new VideoFrameSource(encodingConfig);
@@ -470,7 +467,7 @@ class Conversion {
const sink = new VideoFrameSink(track);
for await (const { frame, timestamp } of sink.frames(this.startTimestamp, this.endTimestamp)) {
if (this.synchronizer.shouldWait(trackId, timestamp)) {
if (this.synchronizer.shouldWait(track.id, timestamp)) {
await this.synchronizer.wait(timestamp);
}
@@ -483,16 +480,16 @@ class Conversion {
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
}
}
// Rotation metadata is reset if we do resizing
const baseRotation = needsResize ? 0 : await track.getRotation();
const baseRotation = needsResize ? 0 : track.rotation;
this.output.addVideoTrack(videoSource, {
languageCode: await track.getLanguageCode(),
languageCode: track.languageCode,
rotation: (baseRotation + (this.options.video?.rotate ?? 0)) % 360 as Rotation,
});
this.addedCounts.video++;
@@ -502,9 +499,7 @@ class Conversion {
}
async processAudioTrack(track: InputAudioTrack) {
const trackId = track.getId();
const sourceCodec = await track.getCodec();
const sourceCodec = track.codec;
if (!sourceCodec) {
this.result.discardedTracks.push({
track,
@@ -515,8 +510,8 @@ class Conversion {
let audioSource: AudioSource;
const originalNumberOfChannels = await track.getNumberOfChannels();
const originalSampleRate = await track.getSampleRate();
const originalNumberOfChannels = track.numberOfChannels;
const originalSampleRate = track.sampleRate;
let numberOfChannels = this.options.audio?.numberOfChannels ?? originalNumberOfChannels;
let sampleRate = this.options.audio?.sampleRate ?? originalSampleRate;
@@ -545,16 +540,16 @@ class Conversion {
const meta: EncodedAudioChunkMetadata = { decoderConfig: decoderConfig ?? undefined };
for await (const sample of sink.samples(undefined, this.endTimestamp)) {
if (this.synchronizer.shouldWait(trackId, sample.timestamp)) {
if (this.synchronizer.shouldWait(track.id, sample.timestamp)) {
await this.synchronizer.wait(sample.timestamp);
}
await source.digest(sample, meta);
this.reportProgress(trackId, sample.timestamp + sample.duration);
this.reportProgress(track.id, sample.timestamp + sample.duration);
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
} else {
// We need to decode & reencode the audio
@@ -621,7 +616,7 @@ class Conversion {
const source = new AudioDataSource({
codec: codecOfChoice,
bitrate: this.options.audio?.bitrate ?? QUALITY_HIGH,
onEncodedSample: sample => this.reportProgress(trackId, sample.timestamp + sample.duration),
onEncodedSample: sample => this.reportProgress(track.id, sample.timestamp + sample.duration),
});
audioSource = source;
@@ -630,7 +625,7 @@ class Conversion {
const sink = new AudioDataSink(track);
for await (const { data, timestamp } of sink.data(undefined, this.startTimestamp)) {
if (this.synchronizer.shouldWait(trackId, timestamp)) {
if (this.synchronizer.shouldWait(track.id, timestamp)) {
await this.synchronizer.wait(timestamp);
}
@@ -639,13 +634,13 @@ class Conversion {
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
}
}
this.output.addAudioTrack(audioSource, {
languageCode: await track.getLanguageCode(),
languageCode: track.languageCode,
});
this.addedCounts.audio++;
this.totalTrackCount++;
@@ -663,11 +658,10 @@ class Conversion {
targetNumberOfChannels: number,
targetSampleRate: number,
) {
const trackId = track.getId();
const source = new AudioBufferSource({
codec,
bitrate: this.options.audio?.bitrate ?? QUALITY_HIGH,
onEncodedSample: sample => this.reportProgress(trackId, sample.timestamp + sample.duration),
onEncodedSample: sample => this.reportProgress(track.id, sample.timestamp + sample.duration),
});
this.trackPromises.push((async () => {
@@ -690,7 +684,7 @@ class Conversion {
const sink = new AudioBufferSink(track);
for await (const { buffer, timestamp, duration } of sink.buffers(this.startTimestamp, this.endTimestamp)) {
if (this.synchronizer.shouldWait(trackId, timestamp)) {
if (this.synchronizer.shouldWait(track.id, timestamp)) {
await this.synchronizer.wait(timestamp);
}
@@ -746,7 +740,7 @@ class Conversion {
}
await source.close();
this.synchronizer.closeTrack(trackId);
this.synchronizer.closeTrack(track.id);
})());
return source;
+38 -38
View File
@@ -7,11 +7,11 @@ import { EncodedAudioSample, EncodedVideoSample } from './sample';
export interface InputTrackBacking {
getId(): number;
getCodec(): Promise<MediaCodec | null>;
getCodec(): MediaCodec | null;
getLanguageCode(): string;
getTimeResolution(): number;
getFirstTimestamp(): Promise<number>;
computeDuration(): Promise<number>;
getLanguageCode(): Promise<string>;
getTimeResolution(): Promise<number>;
}
/** @public */
@@ -24,8 +24,8 @@ export abstract class InputTrack {
this._backing = backing;
}
abstract getType(): TrackType;
abstract getCodec(): Promise<MediaCodec | null>;
abstract get type(): TrackType;
abstract get codec(): MediaCodec | null;
abstract getCodecMimeType(): Promise<string | null>;
abstract canDecode(): Promise<boolean>;
abstract computeSampleStats(): Promise<SampleStats>;
@@ -38,10 +38,18 @@ export abstract class InputTrack {
return this instanceof InputAudioTrack;
}
getId() {
get id() {
return this._backing.getId();
}
get languageCode() {
return this._backing.getLanguageCode();
}
get timeResolution() {
return this._backing.getTimeResolution();
}
getFirstTimestamp() {
return this._backing.getFirstTimestamp();
}
@@ -49,21 +57,13 @@ export abstract class InputTrack {
computeDuration() {
return this._backing.computeDuration();
}
getLanguageCode() {
return this._backing.getLanguageCode();
}
getTimeResolution() {
return this._backing.getTimeResolution();
}
}
export interface InputVideoTrackBacking extends InputTrackBacking {
getCodec(): Promise<VideoCodec | null>;
getCodedWidth(): Promise<number>;
getCodedHeight(): Promise<number>;
getRotation(): Promise<Rotation>;
getCodec(): VideoCodec | null;
getCodedWidth(): number;
getCodedHeight(): number;
getRotation(): Rotation;
getColorSpace(): Promise<VideoColorSpaceInit>;
getDecoderConfig(): Promise<VideoDecoderConfig | null>;
getFirstSample(options: SampleRetrievalOptions): Promise<EncodedVideoSample | null>;
@@ -85,33 +85,33 @@ export class InputVideoTrack extends InputTrack {
this._backing = backing;
}
getType(): TrackType {
get type(): TrackType {
return 'video';
}
getCodec(): Promise<VideoCodec | null> {
get codec() {
return this._backing.getCodec();
}
getCodedWidth() {
get codedWidth() {
return this._backing.getCodedWidth();
}
getCodedHeight() {
get codedHeight() {
return this._backing.getCodedHeight();
}
getRotation() {
get rotation() {
return this._backing.getRotation();
}
async getDisplayWidth() {
const rotation = await this._backing.getRotation();
get displayWidth() {
const rotation = this._backing.getRotation();
return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight();
}
async getDisplayHeight() {
const rotation = await this._backing.getRotation();
get displayHeight() {
const rotation = this._backing.getRotation();
return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth();
}
@@ -132,7 +132,7 @@ export class InputVideoTrack extends InputTrack {
}
async getCodecMimeType() {
const decoderConfig = await this.getDecoderConfig();
const decoderConfig = await this._backing.getDecoderConfig();
return decoderConfig?.codec ?? null;
}
@@ -143,7 +143,7 @@ export class InputVideoTrack extends InputTrack {
return false;
}
const codec = await this.getCodec();
const codec = this._backing.getCodec();
assert(codec !== null);
if (customVideoDecoders.some(x => x.supports(codec, decoderConfig))) {
@@ -168,9 +168,9 @@ export class InputVideoTrack extends InputTrack {
}
export interface InputAudioTrackBacking extends InputTrackBacking {
getCodec(): Promise<AudioCodec | null>;
getNumberOfChannels(): Promise<number>;
getSampleRate(): Promise<number>;
getCodec(): AudioCodec | null;
getNumberOfChannels(): number;
getSampleRate(): number;
getDecoderConfig(): Promise<AudioDecoderConfig | null>;
getFirstSample(options: SampleRetrievalOptions): Promise<EncodedAudioSample | null>;
getSample(timestamp: number, options: SampleRetrievalOptions): Promise<EncodedAudioSample | null>;
@@ -191,19 +191,19 @@ export class InputAudioTrack extends InputTrack {
this._backing = backing;
}
getType(): TrackType {
get type(): TrackType {
return 'audio';
}
getCodec(): Promise<AudioCodec | null> {
get codec(): AudioCodec | null {
return this._backing.getCodec();
}
getNumberOfChannels() {
get numberOfChannels() {
return this._backing.getNumberOfChannels();
}
getSampleRate() {
get sampleRate() {
return this._backing.getSampleRate();
}
@@ -212,7 +212,7 @@ export class InputAudioTrack extends InputTrack {
}
async getCodecMimeType() {
const decoderConfig = await this.getDecoderConfig();
const decoderConfig = await this._backing.getDecoderConfig();
return decoderConfig?.codec ?? null;
}
@@ -223,7 +223,7 @@ export class InputAudioTrack extends InputTrack {
return false;
}
const codec = await this.getCodec();
const codec = this._backing.getCodec();
assert(codec !== null);
if (customAudioDecoders.some(x => x.supports(codec, decoderConfig))) {
+28 -30
View File
@@ -1725,28 +1725,28 @@ abstract class IsobmffTrackBacking<
return this.internalTrack.id;
}
getCodec(): Promise<MediaCodec | null> {
getCodec(): MediaCodec | null {
throw new Error('Not implemented on base class.');
}
getLanguageCode() {
return this.internalTrack.languageCode;
}
getTimeResolution() {
return this.internalTrack.timescale;
}
async computeDuration() {
const lastSample = await this.getSample(Infinity, { metadataOnly: true });
return (lastSample?.timestamp ?? 0) + (lastSample?.duration ?? 0);
}
async getLanguageCode() {
return this.internalTrack.languageCode;
}
async getFirstTimestamp() {
const firstSample = await this.getFirstSample({ metadataOnly: true });
return firstSample?.timestamp ?? 0;
}
async getTimeResolution() {
return this.internalTrack.timescale;
}
abstract createSample(
data: Uint8Array,
byteLength: number,
@@ -2264,19 +2264,19 @@ class IsobmffVideoTrackBacking extends IsobmffTrackBacking<EncodedVideoSample> i
this.internalTrack = internalTrack;
}
override async getCodec(): Promise<VideoCodec | null> {
override getCodec(): VideoCodec | null {
return this.internalTrack.info.codec;
}
async getCodedWidth() {
getCodedWidth() {
return this.internalTrack.info.width;
}
async getCodedHeight() {
getCodedHeight() {
return this.internalTrack.info.height;
}
async getRotation() {
getRotation() {
return this.internalTrack.rotation;
}
@@ -2294,12 +2294,12 @@ class IsobmffVideoTrackBacking extends IsobmffTrackBacking<EncodedVideoSample> i
return null;
}
if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {
const firstSample = await this.getFirstSample({});
this.internalTrack.info.vp9CodecInfo = firstSample && extractVp9CodecInfoFromFrame(firstSample.data);
}
return this.decoderConfigPromise ??= (async (): Promise<VideoDecoderConfig> => {
if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {
const firstSample = await this.getFirstSample({});
this.internalTrack.info.vp9CodecInfo = firstSample && extractVp9CodecInfoFromFrame(firstSample.data);
}
return {
codec: extractVideoCodecString(this.internalTrack.info),
codedWidth: this.internalTrack.info.width,
@@ -2323,22 +2323,22 @@ class IsobmffVideoTrackBacking extends IsobmffTrackBacking<EncodedVideoSample> i
class IsobmffAudioTrackBacking extends IsobmffTrackBacking<EncodedAudioSample> implements InputAudioTrackBacking {
override internalTrack: InternalAudioTrack;
decoderConfigPromise: Promise<AudioDecoderConfig> | null = null;
decoderConfig: AudioDecoderConfig | null = null;
constructor(internalTrack: InternalAudioTrack) {
super(internalTrack);
this.internalTrack = internalTrack;
}
override async getCodec(): Promise<AudioCodec | null> {
override getCodec(): AudioCodec | null {
return this.internalTrack.info.codec;
}
async getNumberOfChannels() {
getNumberOfChannels() {
return this.internalTrack.info.numberOfChannels;
}
async getSampleRate() {
getSampleRate() {
return this.internalTrack.info.sampleRate;
}
@@ -2347,14 +2347,12 @@ class IsobmffAudioTrackBacking extends IsobmffTrackBacking<EncodedAudioSample> i
return null;
}
return this.decoderConfigPromise ??= (async (): Promise<AudioDecoderConfig> => {
return {
codec: extractAudioCodecString(this.internalTrack.info),
numberOfChannels: this.internalTrack.info.numberOfChannels,
sampleRate: this.internalTrack.info.sampleRate,
description: this.internalTrack.info.codecDescription ?? undefined,
};
})();
return this.decoderConfig ??= {
codec: extractAudioCodecString(this.internalTrack.info),
numberOfChannels: this.internalTrack.info.numberOfChannels,
sampleRate: this.internalTrack.info.sampleRate,
description: this.internalTrack.info.codecDescription ?? undefined,
};
}
createSample(
+21 -23
View File
@@ -980,7 +980,7 @@ abstract class MatroskaTrackBacking<
return this.internalTrack.id;
}
getCodec(): Promise<MediaCodec | null> {
getCodec(): MediaCodec | null {
throw new Error('Not implemented on base class.');
}
@@ -989,7 +989,7 @@ abstract class MatroskaTrackBacking<
return (lastSample?.timestamp ?? 0) + (lastSample?.duration ?? 0);
}
async getLanguageCode() {
getLanguageCode() {
return this.internalTrack.languageCode;
}
@@ -998,7 +998,7 @@ abstract class MatroskaTrackBacking<
return firstSample?.timestamp ?? 0;
}
async getTimeResolution() {
getTimeResolution() {
return this.internalTrack.segment.timestampFactor;
}
@@ -1439,19 +1439,19 @@ class MatroskaVideoTrackBacking extends MatroskaTrackBacking<EncodedVideoSample>
this.internalTrack = internalTrack;
}
override async getCodec(): Promise<VideoCodec | null> {
override getCodec(): VideoCodec | null {
return this.internalTrack.info.codec;
}
async getCodedWidth() {
getCodedWidth() {
return this.internalTrack.info.width;
}
async getCodedHeight() {
getCodedHeight() {
return this.internalTrack.info.height;
}
async getRotation() {
getRotation() {
return this.internalTrack.info.rotation;
}
@@ -1513,22 +1513,22 @@ class MatroskaVideoTrackBacking extends MatroskaTrackBacking<EncodedVideoSample>
class MatroskaAudioTrackBacking extends MatroskaTrackBacking<EncodedAudioSample> implements InputAudioTrackBacking {
override internalTrack: InternalAudioTrack;
decoderConfigPromise: Promise<AudioDecoderConfig> | null = null;
decoderConfig: AudioDecoderConfig | null = null;
constructor(internalTrack: InternalAudioTrack) {
super(internalTrack);
this.internalTrack = internalTrack;
}
override async getCodec(): Promise<AudioCodec | null> {
override getCodec(): AudioCodec | null {
return this.internalTrack.info.codec;
}
async getNumberOfChannels() {
getNumberOfChannels() {
return this.internalTrack.info.numberOfChannels;
}
async getSampleRate() {
getSampleRate() {
return this.internalTrack.info.sampleRate;
}
@@ -1537,18 +1537,16 @@ class MatroskaAudioTrackBacking extends MatroskaTrackBacking<EncodedAudioSample>
return null;
}
return this.decoderConfigPromise ??= (async (): Promise<AudioDecoderConfig> => {
return {
codec: extractAudioCodecString({
codec: this.internalTrack.info.codec,
codecDescription: this.internalTrack.codecPrivate,
aacCodecInfo: this.internalTrack.info.aacCodecInfo,
}),
numberOfChannels: this.internalTrack.info.numberOfChannels,
sampleRate: this.internalTrack.info.sampleRate,
description: this.internalTrack.codecPrivate ?? undefined,
};
})();
return this.decoderConfig ??= {
codec: extractAudioCodecString({
codec: this.internalTrack.info.codec,
codecDescription: this.internalTrack.codecPrivate,
aacCodecInfo: this.internalTrack.info.aacCodecInfo,
}),
numberOfChannels: this.internalTrack.info.numberOfChannels,
sampleRate: this.internalTrack.info.sampleRate,
description: this.internalTrack.codecPrivate ?? undefined,
};
}
createSample(
+15 -15
View File
@@ -693,9 +693,9 @@ export class VideoFrameSink extends BaseMediaFrameSink<EncodedVideoSample, Video
);
}
const codec = await this._videoTrack.getCodec();
const codec = this._videoTrack.codec;
const decoderConfig = await this._videoTrack.getDecoderConfig();
const timeResolution = await this._videoTrack.getTimeResolution();
const timeResolution = this._videoTrack.timeResolution;
assert(codec && decoderConfig);
return new VideoDecoderWrapper(onFrame, onError, codec, decoderConfig, timeResolution);
@@ -727,14 +727,14 @@ export class VideoFrameSink extends BaseMediaFrameSink<EncodedVideoSample, Video
frames(startTimestamp = 0, endTimestamp = Infinity) {
return mapAsyncGenerator(
this.mediaFramesInRange(startTimestamp, endTimestamp),
async frame => this._wrappedFrameToWrappedVideoFrame(frame),
frame => this._wrappedFrameToWrappedVideoFrame(frame),
);
}
framesAtTimestamps(timestamps: AnyIterable<number>) {
return mapAsyncGenerator(
this.mediaFramesAtTimestamps(timestamps),
async frame => frame && this._wrappedFrameToWrappedVideoFrame(frame),
frame => frame && this._wrappedFrameToWrappedVideoFrame(frame),
);
}
}
@@ -775,10 +775,10 @@ export class CanvasSink {
}
/** @internal */
async _videoFrameToWrappedCanvas(frame: WrappedVideoFrame): Promise<WrappedCanvas> {
const width = this._dimensions?.width ?? await this._videoTrack.getDisplayWidth();
const height = this._dimensions?.height ?? await this._videoTrack.getDisplayHeight();
const rotation = await this._videoTrack.getRotation();
_videoFrameToWrappedCanvas(frame: WrappedVideoFrame): WrappedCanvas {
const width = this._dimensions?.width ?? this._videoTrack.displayWidth;
const height = this._dimensions?.height ?? this._videoTrack.displayHeight;
const rotation = this._videoTrack.rotation;
const canvas = document.createElement('canvas');
canvas.width = width;
@@ -822,7 +822,7 @@ export class CanvasSink {
canvasesAtTimestamps(timestamps: AnyIterable<number>) {
return mapAsyncGenerator(
this._videoFrameSink.framesAtTimestamps(timestamps),
async frame => frame && this._videoFrameToWrappedCanvas(frame),
frame => frame && this._videoFrameToWrappedCanvas(frame),
);
}
}
@@ -1161,14 +1161,14 @@ export class AudioDataSink extends BaseMediaFrameSink<EncodedAudioSample, AudioD
);
}
const codec = await this._audioTrack.getCodec();
const codec = this._audioTrack.codec;
const decoderConfig = await this._audioTrack.getDecoderConfig();
assert(codec && decoderConfig);
if ((PCM_AUDIO_CODECS as readonly string[]).includes(decoderConfig.codec)) {
return new PcmAudioDecoderWrapper(onData, onError, decoderConfig);
} else {
const timeResolution = await this._audioTrack.getTimeResolution();
const timeResolution = this._audioTrack.timeResolution;
return new AudioDecoderWrapper(onData, onError, codec, decoderConfig, timeResolution);
}
}
@@ -1199,14 +1199,14 @@ export class AudioDataSink extends BaseMediaFrameSink<EncodedAudioSample, AudioD
data(startTimestamp = 0, endTimestamp = Infinity) {
return mapAsyncGenerator(
this.mediaFramesInRange(startTimestamp, endTimestamp),
async data => this._wrappedFrameToWrappedAudioData(data),
data => this._wrappedFrameToWrappedAudioData(data),
);
}
dataAtTimestamps(timestamps: AnyIterable<number>) {
return mapAsyncGenerator(
this.mediaFramesAtTimestamps(timestamps),
async data => data && this._wrappedFrameToWrappedAudioData(data),
data => data && this._wrappedFrameToWrappedAudioData(data),
);
}
}
@@ -1267,14 +1267,14 @@ export class AudioBufferSink {
buffers(startTimestamp = 0, endTimestamp = Infinity) {
return mapAsyncGenerator(
this._audioDataSink.data(startTimestamp, endTimestamp),
async data => this._audioDataToWrappedArrayBuffer(data),
data => this._audioDataToWrappedArrayBuffer(data),
);
}
buffersAtTimestamps(timestamps: AnyIterable<number>) {
return mapAsyncGenerator(
this._audioDataSink.dataAtTimestamps(timestamps),
async data => data && this._audioDataToWrappedArrayBuffer(data),
data => data && this._audioDataToWrappedArrayBuffer(data),
);
}
}
+2 -2
View File
@@ -335,7 +335,7 @@ export const setInt24 = (view: DataView, byteOffset: number, value: number, litt
*/
export const mapAsyncGenerator = <T, U>(
generator: AsyncGenerator<T, void, unknown>,
map: (t: T) => Promise<U>,
map: (t: T) => U,
): AsyncGenerator<U, void, unknown> => {
return {
async next() {
@@ -343,7 +343,7 @@ export const mapAsyncGenerator = <T, U>(
if (result.done) {
return { value: undefined, done: true };
} else {
return { value: await map(result.value), done: false };
return { value: map(result.value), done: false };
}
},
return() {
+5 -5
View File
@@ -119,7 +119,7 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
return 0;
}
async getTimeResolution() {
getTimeResolution() {
assert(this.demuxer.firstFrameHeader);
return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;
}
@@ -128,20 +128,20 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
return this.demuxer.computeDuration();
}
async getLanguageCode() {
getLanguageCode() {
return UNDETERMINED_LANGUAGE;
}
async getCodec(): Promise<AudioCodec> {
getCodec(): AudioCodec {
return 'mp3';
}
async getNumberOfChannels() {
getNumberOfChannels() {
assert(this.demuxer.firstFrameHeader);
return this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2;
}
async getSampleRate() {
getSampleRate() {
assert(this.demuxer.firstFrameHeader);
return this.demuxer.firstFrameHeader.sampleRate;
}
+5 -5
View File
@@ -410,19 +410,19 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
return this.bitstream.serialNumber;
}
async getNumberOfChannels() {
getNumberOfChannels() {
return this.bitstream.numberOfChannels;
}
async getSampleRate() {
getSampleRate() {
return this.bitstream.sampleRate;
}
async getTimeResolution() {
getTimeResolution() {
return this.bitstream.sampleRate;
}
async getCodec() {
getCodec() {
return this.bitstream.codec;
}
@@ -437,7 +437,7 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
};
}
async getLanguageCode() {
getLanguageCode() {
return UNDETERMINED_LANGUAGE;
}
+5 -5
View File
@@ -187,7 +187,7 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
return 1;
}
async getCodec() {
getCodec() {
return this.demuxer.getCodec();
}
@@ -209,22 +209,22 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
return this.demuxer.computeDuration();
}
async getNumberOfChannels() {
getNumberOfChannels() {
assert(this.demuxer.audioInfo);
return this.demuxer.audioInfo.numberOfChannels;
}
async getSampleRate() {
getSampleRate() {
assert(this.demuxer.audioInfo);
return this.demuxer.audioInfo.sampleRate;
}
async getTimeResolution() {
getTimeResolution() {
assert(this.demuxer.audioInfo);
return this.demuxer.audioInfo.sampleRate;
}
async getLanguageCode() {
getLanguageCode() {
return UNDETERMINED_LANGUAGE;
}