mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 13:23:51 +02:00
Drain -> Sink
This commit is contained in:
+4
-4
@@ -55,7 +55,7 @@
|
|||||||
const audioTrack = await input.getPrimaryAudioTrack();
|
const audioTrack = await input.getPrimaryAudioTrack();
|
||||||
const videoTrack = await input.getPrimaryVideoTrack();
|
const videoTrack = await input.getPrimaryVideoTrack();
|
||||||
|
|
||||||
const drain = new Metamuxer.EncodedAudioSampleDrain(audioTrack);
|
const sink = new Metamuxer.EncodedAudioSampleSink(audioTrack);
|
||||||
|
|
||||||
const decoderConfig = await audioTrack.getDecoderConfig();
|
const decoderConfig = await audioTrack.getDecoderConfig();
|
||||||
const sampleSource = new Metamuxer.EncodedAudioSampleSource(await audioTrack.getCodec());
|
const sampleSource = new Metamuxer.EncodedAudioSampleSource(await audioTrack.getCodec());
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for await (const sample of drain.samples()) {
|
for await (const sample of sink.samples()) {
|
||||||
//console.log(sample.timestamp);
|
//console.log(sample.timestamp);
|
||||||
//sample.timestamp *= 2;
|
//sample.timestamp *= 2;
|
||||||
//console.log(sample);
|
//console.log(sample);
|
||||||
@@ -80,13 +80,13 @@
|
|||||||
await sampleSource.digest(sample, { decoderConfig });
|
await sampleSource.digest(sample, { decoderConfig });
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
for await (const { data, timestamp } of new Metamuxer.AudioDataDrain(audioTrack).data()) {
|
for await (const { data, timestamp } of new Metamuxer.AudioDataSink(audioTrack).data()) {
|
||||||
//console.log("wow", data.timestamp);
|
//console.log("wow", data.timestamp);
|
||||||
//console.log(sample)
|
//console.log(sample)
|
||||||
await audioDataSource.digest(data);
|
await audioDataSource.digest(data);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
for await (const sample of new Metamuxer.EncodedVideoSampleDrain(videoTrack).samples()) {
|
for await (const sample of new Metamuxer.EncodedVideoSampleSink(videoTrack).samples()) {
|
||||||
//console.log(sample)
|
//console.log(sample)
|
||||||
await videoSampleSource.digest(sample, { decoderConfig: videoDecoderConfig });
|
await videoSampleSource.digest(sample, { decoderConfig: videoDecoderConfig });
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -68,8 +68,8 @@ durationElement.textContent = formatSeconds(totalDuration);
|
|||||||
|
|
||||||
playerDiv.style.display = 'flex';
|
playerDiv.style.display = 'flex';
|
||||||
|
|
||||||
const videoDrain = videoTrack && new Metamuxer.CanvasDrain(videoTrack);
|
const videoSink = videoTrack && new Metamuxer.CanvasSink(videoTrack);
|
||||||
const audioDrain = audioTrack && new Metamuxer.AudioBufferDrain(audioTrack);
|
const audioSink = audioTrack && new Metamuxer.AudioBufferSink(audioTrack);
|
||||||
|
|
||||||
let startTime = null;
|
let startTime = null;
|
||||||
let playing = false;
|
let playing = false;
|
||||||
@@ -92,7 +92,7 @@ function getPlaybackTime() {
|
|||||||
|
|
||||||
function play() {
|
function play() {
|
||||||
audioBufferIterator?.return();
|
audioBufferIterator?.return();
|
||||||
audioBufferIterator = audioDrain?.buffers(getPlaybackTime());
|
audioBufferIterator = audioSink?.buffers(getPlaybackTime());
|
||||||
startTime = audioContext.currentTime;
|
startTime = audioContext.currentTime;
|
||||||
playing = true;
|
playing = true;
|
||||||
runAudioIterator();
|
runAudioIterator();
|
||||||
@@ -135,7 +135,7 @@ async function seek() {
|
|||||||
|
|
||||||
await videoFrameIterator?.return();
|
await videoFrameIterator?.return();
|
||||||
|
|
||||||
videoFrameIterator = videoDrain.canvases(getPlaybackTime());
|
videoFrameIterator = videoSink.canvases(getPlaybackTime());
|
||||||
|
|
||||||
const newCurrentFrame = (await videoFrameIterator.next()).value;
|
const newCurrentFrame = (await videoFrameIterator.next()).value;
|
||||||
const newNextFrame = (await videoFrameIterator.next()).value;
|
const newNextFrame = (await videoFrameIterator.next()).value;
|
||||||
|
|||||||
+9
-9
@@ -71,18 +71,18 @@ export {
|
|||||||
} from './sample';
|
} from './sample';
|
||||||
export {
|
export {
|
||||||
SampleRetrievalOptions,
|
SampleRetrievalOptions,
|
||||||
BaseSampleDrain,
|
BaseSampleSink,
|
||||||
WrappedMediaFrame,
|
WrappedMediaFrame,
|
||||||
BaseMediaFrameDrain,
|
BaseMediaFrameSink,
|
||||||
EncodedVideoSampleDrain,
|
EncodedVideoSampleSink,
|
||||||
VideoFrameDrain,
|
VideoFrameSink,
|
||||||
EncodedAudioSampleDrain,
|
EncodedAudioSampleSink,
|
||||||
CanvasDrain,
|
CanvasSink,
|
||||||
WrappedCanvas,
|
WrappedCanvas,
|
||||||
AudioDataDrain,
|
AudioDataSink,
|
||||||
WrappedAudioData,
|
WrappedAudioData,
|
||||||
AudioBufferDrain,
|
AudioBufferSink,
|
||||||
WrappedAudioBuffer,
|
WrappedAudioBuffer,
|
||||||
} from './media-drain';
|
} from './media-sink';
|
||||||
|
|
||||||
// 🐡🦔
|
// 🐡🦔
|
||||||
|
|||||||
+5
-5
@@ -1,5 +1,5 @@
|
|||||||
import { AudioCodec, MediaCodec, VideoCodec } from './codec';
|
import { AudioCodec, MediaCodec, VideoCodec } from './codec';
|
||||||
import { EncodedAudioSampleDrain, EncodedVideoSampleDrain, SampleRetrievalOptions } from './media-drain';
|
import { EncodedAudioSampleSink, EncodedVideoSampleSink, SampleRetrievalOptions } from './media-sink';
|
||||||
import { Rotation } from './misc';
|
import { Rotation } from './misc';
|
||||||
import { EncodedAudioSample, EncodedVideoSample } from './sample';
|
import { EncodedAudioSample, EncodedVideoSample } from './sample';
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ export class InputVideoTrack extends InputTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeSampleStats() {
|
computeSampleStats() {
|
||||||
return computeSampleStats(new EncodedVideoSampleDrain(this));
|
return computeSampleStats(new EncodedVideoSampleSink(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ export class InputAudioTrack extends InputTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeSampleStats() {
|
computeSampleStats() {
|
||||||
return computeSampleStats(new EncodedAudioSampleDrain(this));
|
return computeSampleStats(new EncodedAudioSampleSink(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,13 +196,13 @@ export type SampleStats = {
|
|||||||
averageBitrate: number;
|
averageBitrate: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const computeSampleStats = async (drain: EncodedVideoSampleDrain | EncodedAudioSampleDrain): Promise<SampleStats> => {
|
const computeSampleStats = async (sink: EncodedVideoSampleSink | EncodedAudioSampleSink): Promise<SampleStats> => {
|
||||||
let startTimestamp = Infinity;
|
let startTimestamp = Infinity;
|
||||||
let endTimestamp = -Infinity;
|
let endTimestamp = -Infinity;
|
||||||
let sampleCount = 0;
|
let sampleCount = 0;
|
||||||
let totalSampleBytes = 0;
|
let totalSampleBytes = 0;
|
||||||
|
|
||||||
for await (const sample of drain.samples(undefined, undefined, { metadataOnly: true })) {
|
for await (const sample of sink.samples(undefined, undefined, { metadataOnly: true })) {
|
||||||
startTimestamp = Math.min(startTimestamp, sample.timestamp);
|
startTimestamp = Math.min(startTimestamp, sample.timestamp);
|
||||||
endTimestamp = Math.max(endTimestamp, sample.timestamp + sample.duration);
|
endTimestamp = Math.max(endTimestamp, sample.timestamp + sample.duration);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
InputVideoTrack,
|
InputVideoTrack,
|
||||||
InputVideoTrackBacking,
|
InputVideoTrackBacking,
|
||||||
} from '../input-track';
|
} from '../input-track';
|
||||||
import { SampleRetrievalOptions } from '../media-drain';
|
import { SampleRetrievalOptions } from '../media-sink';
|
||||||
import {
|
import {
|
||||||
assert,
|
assert,
|
||||||
COLOR_PRIMARIES_MAP_INVERSE,
|
COLOR_PRIMARIES_MAP_INVERSE,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const validateTimestamp = (timestamp: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export abstract class BaseSampleDrain<Sample extends EncodedVideoSample | EncodedAudioSample> {
|
export abstract class BaseSampleSink<Sample extends EncodedVideoSample | EncodedAudioSample> {
|
||||||
abstract getFirstSample(options?: SampleRetrievalOptions): Promise<Sample | null>;
|
abstract getFirstSample(options?: SampleRetrievalOptions): Promise<Sample | null>;
|
||||||
abstract getSample(timestamp: number, options?: SampleRetrievalOptions): Promise<Sample | null>;
|
abstract getSample(timestamp: number, options?: SampleRetrievalOptions): Promise<Sample | null>;
|
||||||
abstract getNextSample(sample: Sample, options?: SampleRetrievalOptions): Promise<Sample | null>;
|
abstract getNextSample(sample: Sample, options?: SampleRetrievalOptions): Promise<Sample | null>;
|
||||||
@@ -162,7 +162,7 @@ abstract class DecoderWrapper<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export abstract class BaseMediaFrameDrain<
|
export abstract class BaseMediaFrameSink<
|
||||||
Sample extends EncodedVideoSample | EncodedAudioSample,
|
Sample extends EncodedVideoSample | EncodedAudioSample,
|
||||||
MediaFrame extends VideoFrame | AudioData,
|
MediaFrame extends VideoFrame | AudioData,
|
||||||
WrappedFrame extends WrappedMediaFrame<MediaFrame> = WrappedMediaFrame<MediaFrame>,
|
WrappedFrame extends WrappedMediaFrame<MediaFrame> = WrappedMediaFrame<MediaFrame>,
|
||||||
@@ -173,7 +173,7 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
onError: (error: DOMException) => unknown
|
onError: (error: DOMException) => unknown
|
||||||
): Promise<DecoderWrapper<Sample, MediaFrame>>;
|
): Promise<DecoderWrapper<Sample, MediaFrame>>;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
abstract _createSampleDrain(): BaseSampleDrain<Sample>;
|
abstract _createSampleSink(): BaseSampleSink<Sample>;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
private _duplicateFrame(frame: WrappedFrame) {
|
private _duplicateFrame(frame: WrappedFrame) {
|
||||||
@@ -248,8 +248,8 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const sampleDrain = this._createSampleDrain();
|
const sampleSink = this._createSampleSink();
|
||||||
const keySample = await sampleDrain.getKeySample(startTimestamp) ?? await sampleDrain.getFirstSample();
|
const keySample = await sampleSink.getKeySample(startTimestamp) ?? await sampleSink.getFirstSample();
|
||||||
if (!keySample) {
|
if (!keySample) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -262,19 +262,19 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
// frames (B-frames). Instead, we'll need to keep decoding samples until we get a frame that exceeds
|
// frames (B-frames). Instead, we'll need to keep decoding samples until we get a frame that exceeds
|
||||||
// this end time. However, we can still put a bound on it: Since key frames are by definition never
|
// this end time. However, we can still put a bound on it: Since key frames are by definition never
|
||||||
// out of order, we can stop at the first key frame after the end timestamp.
|
// out of order, we can stop at the first key frame after the end timestamp.
|
||||||
const endSample = await sampleDrain.getSample(endTimestamp);
|
const endSample = await sampleSink.getSample(endTimestamp);
|
||||||
const endKeySample = !endSample
|
const endKeySample = !endSample
|
||||||
? null
|
? null
|
||||||
: endSample.type === 'key' && endSample.timestamp === endTimestamp
|
: endSample.type === 'key' && endSample.timestamp === endTimestamp
|
||||||
? endSample
|
? endSample
|
||||||
: await sampleDrain.getNextKeySample(endSample);
|
: await sampleSink.getNextKeySample(endSample);
|
||||||
|
|
||||||
if (endKeySample) {
|
if (endKeySample) {
|
||||||
samplesEndTimestamp = endKeySample.timestamp;
|
samplesEndTimestamp = endKeySample.timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const samples = sampleDrain.samples(keySample, samplesEndTimestamp);
|
const samples = sampleSink.samples(keySample, samplesEndTimestamp);
|
||||||
await samples.next(); // Skip the start sample as we already have it
|
await samples.next(); // Skip the start sample as we already have it
|
||||||
|
|
||||||
while (currentSample && !ended) {
|
while (currentSample && !ended) {
|
||||||
@@ -409,7 +409,7 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const sampleDrain = this._createSampleDrain();
|
const sampleSink = this._createSampleSink();
|
||||||
let lastKeySample: Sample | null = null;
|
let lastKeySample: Sample | null = null;
|
||||||
let lastSample: Sample | null = null;
|
let lastSample: Sample | null = null;
|
||||||
|
|
||||||
@@ -425,13 +425,13 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetSample = await sampleDrain.getSample(timestamp);
|
const targetSample = await sampleSink.getSample(timestamp);
|
||||||
if (!targetSample) {
|
if (!targetSample) {
|
||||||
pushToQueue(null);
|
pushToQueue(null);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const keySample = await sampleDrain.getKeySample(timestamp);
|
const keySample = await sampleSink.getKeySample(timestamp);
|
||||||
if (!keySample) {
|
if (!keySample) {
|
||||||
pushToQueue(null);
|
pushToQueue(null);
|
||||||
continue;
|
continue;
|
||||||
@@ -461,7 +461,7 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (lastSample.timestamp !== targetSample.timestamp) {
|
while (lastSample.timestamp !== targetSample.timestamp) {
|
||||||
const nextSample = await sampleDrain.getNextSample(lastSample);
|
const nextSample = await sampleSink.getNextSample(lastSample);
|
||||||
assert(nextSample);
|
assert(nextSample);
|
||||||
|
|
||||||
lastSample = nextSample;
|
lastSample = nextSample;
|
||||||
@@ -523,7 +523,7 @@ export abstract class BaseMediaFrameDrain<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class EncodedVideoSampleDrain extends BaseSampleDrain<EncodedVideoSample> {
|
export class EncodedVideoSampleSink extends BaseSampleSink<EncodedVideoSample> {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_videoTrack: InputVideoTrack;
|
_videoTrack: InputVideoTrack;
|
||||||
|
|
||||||
@@ -620,7 +620,7 @@ class VideoDecoderWrapper extends DecoderWrapper<EncodedVideoSample, VideoFrame>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class VideoFrameDrain extends BaseMediaFrameDrain<EncodedVideoSample, VideoFrame> {
|
export class VideoFrameSink extends BaseMediaFrameSink<EncodedVideoSample, VideoFrame> {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_videoTrack: InputVideoTrack;
|
_videoTrack: InputVideoTrack;
|
||||||
|
|
||||||
@@ -653,8 +653,8 @@ export class VideoFrameDrain extends BaseMediaFrameDrain<EncodedVideoSample, Vid
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_createSampleDrain() {
|
_createSampleSink() {
|
||||||
return new EncodedVideoSampleDrain(this._videoTrack);
|
return new EncodedVideoSampleSink(this._videoTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFrame(timestamp: number) {
|
async getFrame(timestamp: number) {
|
||||||
@@ -683,13 +683,13 @@ export type WrappedCanvas = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class CanvasDrain {
|
export class CanvasSink {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_videoTrack: InputVideoTrack;
|
_videoTrack: InputVideoTrack;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_dimensions?: { width: number; height: number };
|
_dimensions?: { width: number; height: number };
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_videoFrameDrain: VideoFrameDrain;
|
_videoFrameSink: VideoFrameSink;
|
||||||
|
|
||||||
constructor(videoTrack: InputVideoTrack, dimensions?: { width: number; height: number }) {
|
constructor(videoTrack: InputVideoTrack, dimensions?: { width: number; height: number }) {
|
||||||
if (!(videoTrack instanceof InputVideoTrack)) {
|
if (!(videoTrack instanceof InputVideoTrack)) {
|
||||||
@@ -707,7 +707,7 @@ export class CanvasDrain {
|
|||||||
|
|
||||||
this._videoTrack = videoTrack;
|
this._videoTrack = videoTrack;
|
||||||
this._dimensions = dimensions;
|
this._dimensions = dimensions;
|
||||||
this._videoFrameDrain = new VideoFrameDrain(videoTrack);
|
this._videoFrameSink = new VideoFrameSink(videoTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@@ -746,27 +746,27 @@ export class CanvasDrain {
|
|||||||
async getCanvas(timestamp: number) {
|
async getCanvas(timestamp: number) {
|
||||||
validateTimestamp(timestamp);
|
validateTimestamp(timestamp);
|
||||||
|
|
||||||
const frame = await this._videoFrameDrain.getFrame(timestamp);
|
const frame = await this._videoFrameSink.getFrame(timestamp);
|
||||||
return frame && this._videoFrameToWrappedCanvas(frame);
|
return frame && this._videoFrameToWrappedCanvas(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvases(startTimestamp = 0, endTimestamp = Infinity) {
|
canvases(startTimestamp = 0, endTimestamp = Infinity) {
|
||||||
return mapAsyncGenerator(
|
return mapAsyncGenerator(
|
||||||
this._videoFrameDrain.frames(startTimestamp, endTimestamp),
|
this._videoFrameSink.frames(startTimestamp, endTimestamp),
|
||||||
frame => this._videoFrameToWrappedCanvas(frame),
|
frame => this._videoFrameToWrappedCanvas(frame),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasesAtTimestamps(timestamps: AnyIterable<number>) {
|
canvasesAtTimestamps(timestamps: AnyIterable<number>) {
|
||||||
return mapAsyncGenerator(
|
return mapAsyncGenerator(
|
||||||
this._videoFrameDrain.framesAtTimestamps(timestamps),
|
this._videoFrameSink.framesAtTimestamps(timestamps),
|
||||||
async frame => frame && this._videoFrameToWrappedCanvas(frame),
|
async frame => frame && this._videoFrameToWrappedCanvas(frame),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class EncodedAudioSampleDrain extends BaseSampleDrain<EncodedAudioSample> {
|
export class EncodedAudioSampleSink extends BaseSampleSink<EncodedAudioSample> {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_audioTrack: InputAudioTrack;
|
_audioTrack: InputAudioTrack;
|
||||||
|
|
||||||
@@ -1023,7 +1023,7 @@ export type WrappedAudioData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class AudioDataDrain extends BaseMediaFrameDrain<EncodedAudioSample, AudioData> {
|
export class AudioDataSink extends BaseMediaFrameSink<EncodedAudioSample, AudioData> {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_audioTrack: InputAudioTrack;
|
_audioTrack: InputAudioTrack;
|
||||||
|
|
||||||
@@ -1069,8 +1069,8 @@ export class AudioDataDrain extends BaseMediaFrameDrain<EncodedAudioSample, Audi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_createSampleDrain() {
|
_createSampleSink() {
|
||||||
return new EncodedAudioSampleDrain(this._audioTrack);
|
return new EncodedAudioSampleSink(this._audioTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getData(timestamp: number) {
|
async getData(timestamp: number) {
|
||||||
@@ -1105,16 +1105,16 @@ export type WrappedAudioBuffer = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export class AudioBufferDrain {
|
export class AudioBufferSink {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_audioDataDrain: AudioDataDrain;
|
_audioDataSink: AudioDataSink;
|
||||||
|
|
||||||
constructor(audioTrack: InputAudioTrack) {
|
constructor(audioTrack: InputAudioTrack) {
|
||||||
if (!(audioTrack instanceof InputAudioTrack)) {
|
if (!(audioTrack instanceof InputAudioTrack)) {
|
||||||
throw new TypeError('audioTrack must be an InputAudioTrack.');
|
throw new TypeError('audioTrack must be an InputAudioTrack.');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._audioDataDrain = new AudioDataDrain(audioTrack);
|
this._audioDataSink = new AudioDataSink(audioTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@@ -1146,20 +1146,20 @@ export class AudioBufferDrain {
|
|||||||
async getBuffer(timestamp: number) {
|
async getBuffer(timestamp: number) {
|
||||||
validateTimestamp(timestamp);
|
validateTimestamp(timestamp);
|
||||||
|
|
||||||
const data = await this._audioDataDrain.getData(timestamp);
|
const data = await this._audioDataSink.getData(timestamp);
|
||||||
return data && this._audioDataToWrappedArrayBuffer(data);
|
return data && this._audioDataToWrappedArrayBuffer(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers(startTimestamp = 0, endTimestamp = Infinity) {
|
buffers(startTimestamp = 0, endTimestamp = Infinity) {
|
||||||
return mapAsyncGenerator(
|
return mapAsyncGenerator(
|
||||||
this._audioDataDrain.data(startTimestamp, endTimestamp),
|
this._audioDataSink.data(startTimestamp, endTimestamp),
|
||||||
async data => this._audioDataToWrappedArrayBuffer(data),
|
async data => this._audioDataToWrappedArrayBuffer(data),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffersAtTimestamps(timestamps: AnyIterable<number>) {
|
buffersAtTimestamps(timestamps: AnyIterable<number>) {
|
||||||
return mapAsyncGenerator(
|
return mapAsyncGenerator(
|
||||||
this._audioDataDrain.dataAtTimestamps(timestamps),
|
this._audioDataSink.dataAtTimestamps(timestamps),
|
||||||
async data => data && this._audioDataToWrappedArrayBuffer(data),
|
async data => data && this._audioDataToWrappedArrayBuffer(data),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ import { AudioCodec } from '../codec';
|
|||||||
import { Demuxer } from '../demuxer';
|
import { Demuxer } from '../demuxer';
|
||||||
import { Input } from '../input';
|
import { Input } from '../input';
|
||||||
import { InputAudioTrack, InputAudioTrackBacking } from '../input-track';
|
import { InputAudioTrack, InputAudioTrackBacking } from '../input-track';
|
||||||
import { SampleRetrievalOptions } from '../media-drain';
|
import { SampleRetrievalOptions } from '../media-sink';
|
||||||
import { assert } from '../misc';
|
import { assert } from '../misc';
|
||||||
import { Reader } from '../reader';
|
import { Reader } from '../reader';
|
||||||
import { EncodedAudioSample, PLACEHOLDER_DATA } from '../sample';
|
import { EncodedAudioSample, PLACEHOLDER_DATA } from '../sample';
|
||||||
|
|||||||
Reference in New Issue
Block a user