@smoove/core 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/composition.d.ts.map +1 -1
- package/dist/engine/composition.js +1 -1
- package/dist/engine/composition.js.map +1 -1
- package/dist/engine/marker.d.ts +77 -0
- package/dist/engine/marker.d.ts.map +1 -0
- package/dist/engine/marker.js +107 -0
- package/dist/engine/marker.js.map +1 -0
- package/dist/engine/runtime-defaults.d.ts +5 -5
- package/dist/engine/runtime-defaults.d.ts.map +1 -1
- package/dist/engine/runtime-defaults.js +12 -9
- package/dist/engine/runtime-defaults.js.map +1 -1
- package/dist/engine/sequence.d.ts +39 -11
- package/dist/engine/sequence.d.ts.map +1 -1
- package/dist/engine/sequence.js +52 -12
- package/dist/engine/sequence.js.map +1 -1
- package/dist/engine/series.d.ts +20 -4
- package/dist/engine/series.d.ts.map +1 -1
- package/dist/engine/series.js +42 -3
- package/dist/engine/series.js.map +1 -1
- package/dist/index.d.ts +5 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/layout/group.js +1 -1
- package/dist/layout/group.js.map +1 -1
- package/dist/layout/image.js +1 -1
- package/dist/layout/image.js.map +1 -1
- package/dist/layout/text/font.js +1 -1
- package/dist/layout/text/font.js.map +1 -1
- package/dist/layout/text/text.js +1 -1
- package/dist/layout/text/text.js.map +1 -1
- package/dist/markers.d.ts +43 -0
- package/dist/markers.d.ts.map +1 -0
- package/dist/markers.js +46 -0
- package/dist/markers.js.map +1 -0
- package/package.json +2 -3
- package/dist/media/audio/audio-driver.d.ts +0 -34
- package/dist/media/audio/audio-driver.d.ts.map +0 -1
- package/dist/media/audio/audio-driver.js +0 -2
- package/dist/media/audio/audio-driver.js.map +0 -1
- package/dist/media/audio/audio-for-preview.d.ts +0 -47
- package/dist/media/audio/audio-for-preview.d.ts.map +0 -1
- package/dist/media/audio/audio-for-preview.js +0 -232
- package/dist/media/audio/audio-for-preview.js.map +0 -1
- package/dist/media/audio/audio-for-rendering.d.ts +0 -16
- package/dist/media/audio/audio-for-rendering.d.ts.map +0 -1
- package/dist/media/audio/audio-for-rendering.js +0 -32
- package/dist/media/audio/audio-for-rendering.js.map +0 -1
- package/dist/media/audio/audio-source-browser.d.ts +0 -30
- package/dist/media/audio/audio-source-browser.d.ts.map +0 -1
- package/dist/media/audio/audio-source-browser.js +0 -139
- package/dist/media/audio/audio-source-browser.js.map +0 -1
- package/dist/media/audio/audio-source-mediabunny.d.ts +0 -45
- package/dist/media/audio/audio-source-mediabunny.d.ts.map +0 -1
- package/dist/media/audio/audio-source-mediabunny.js +0 -79
- package/dist/media/audio/audio-source-mediabunny.js.map +0 -1
- package/dist/media/audio/index.d.ts +0 -57
- package/dist/media/audio/index.d.ts.map +0 -1
- package/dist/media/audio/index.js +0 -176
- package/dist/media/audio/index.js.map +0 -1
- package/dist/media/audio/shared-audio-context.d.ts +0 -30
- package/dist/media/audio/shared-audio-context.d.ts.map +0 -1
- package/dist/media/audio/shared-audio-context.js +0 -68
- package/dist/media/audio/shared-audio-context.js.map +0 -1
- package/dist/media/audio/types.d.ts +0 -48
- package/dist/media/audio/types.d.ts.map +0 -1
- package/dist/media/audio/types.js +0 -2
- package/dist/media/audio/types.js.map +0 -1
- package/dist/media/media-marker.d.ts +0 -34
- package/dist/media/media-marker.d.ts.map +0 -1
- package/dist/media/media-marker.js +0 -34
- package/dist/media/media-marker.js.map +0 -1
- package/dist/media/video/driver.d.ts +0 -31
- package/dist/media/video/driver.d.ts.map +0 -1
- package/dist/media/video/driver.js +0 -3
- package/dist/media/video/driver.js.map +0 -1
- package/dist/media/video/index.d.ts +0 -66
- package/dist/media/video/index.d.ts.map +0 -1
- package/dist/media/video/index.js +0 -372
- package/dist/media/video/index.js.map +0 -1
- package/dist/media/video/types.d.ts +0 -36
- package/dist/media/video/types.d.ts.map +0 -1
- package/dist/media/video/types.js +0 -2
- package/dist/media/video/types.js.map +0 -1
- package/dist/media/video/video-for-preview.d.ts +0 -17
- package/dist/media/video/video-for-preview.d.ts.map +0 -1
- package/dist/media/video/video-for-preview.js +0 -30
- package/dist/media/video/video-for-preview.js.map +0 -1
- package/dist/media/video/video-for-rendering.d.ts +0 -17
- package/dist/media/video/video-for-rendering.d.ts.map +0 -1
- package/dist/media/video/video-for-rendering.js +0 -59
- package/dist/media/video/video-for-rendering.js.map +0 -1
- package/dist/media/video/video-source-browser.d.ts +0 -37
- package/dist/media/video/video-source-browser.d.ts.map +0 -1
- package/dist/media/video/video-source-browser.js +0 -171
- package/dist/media/video/video-source-browser.js.map +0 -1
- package/dist/media/video/video-source-mediabunny.d.ts +0 -69
- package/dist/media/video/video-source-mediabunny.d.ts.map +0 -1
- package/dist/media/video/video-source-mediabunny.js +0 -236
- package/dist/media/video/video-source-mediabunny.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smoove/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A timeline-driven animation engine for Konva. Runs in the browser or on the server and renders to any target.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -28,8 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"bezier-easing": "^2.1.0",
|
|
31
|
-
"flexily": "^0.7.1"
|
|
32
|
-
"mediabunny": "^1.49.0"
|
|
31
|
+
"flexily": "^0.7.1"
|
|
33
32
|
},
|
|
34
33
|
"peerDependencies": {
|
|
35
34
|
"konva": ">=10"
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Composition } from "../../engine/composition.js";
|
|
2
|
-
import type { MediaTiming } from "../media-time.js";
|
|
3
|
-
import type { AudioSource } from "./audio-source.js";
|
|
4
|
-
/**
|
|
5
|
-
* What an audio driver needs from the host {@link Audio}: the media source, the
|
|
6
|
-
* resolved timing, the owning composition (for play state + asset collection),
|
|
7
|
-
* the source identity, and getters for the effective audio level so a render
|
|
8
|
-
* driver can record it. No `redraw` — audio paints nothing.
|
|
9
|
-
*/
|
|
10
|
-
export type AudioDriverContext = {
|
|
11
|
-
readonly source: AudioSource;
|
|
12
|
-
readonly timing: MediaTiming;
|
|
13
|
-
readonly comp: Composition;
|
|
14
|
-
readonly id: string;
|
|
15
|
-
readonly src: string;
|
|
16
|
-
/** Effective level (master × intrinsic), 0..1, at the current frame. */
|
|
17
|
-
effectiveVolume(): number;
|
|
18
|
-
/** Effective mute (masterMuted || intrinsicMuted) at the current frame. */
|
|
19
|
-
effectiveMuted(): boolean;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Strategy that maps the composition's current frame onto the audio. Mirrors
|
|
23
|
-
* {@link VideoDriver}: a realtime preview driver and a deterministic render
|
|
24
|
-
* driver (which collects assets rather than playing).
|
|
25
|
-
*/
|
|
26
|
-
export interface AudioDriver {
|
|
27
|
-
/** Called by Sequence each tick while the audio is on-stage (`localFrame` = frame - sequence.from). */
|
|
28
|
-
tick(localFrame: number): void;
|
|
29
|
-
/** Called by Sequence when the audio leaves range. */
|
|
30
|
-
deactivate(): void;
|
|
31
|
-
/** Release any subscriptions; called on `Audio.destroy()`. */
|
|
32
|
-
dispose(): void;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=audio-driver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-driver.d.ts","sourceRoot":"","sources":["../../../src/media/audio/audio-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,eAAe,IAAI,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,cAAc,IAAI,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,uGAAuG;IACvG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,sDAAsD;IACtD,UAAU,IAAI,IAAI,CAAC;IACnB,8DAA8D;IAC9D,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-driver.js","sourceRoot":"","sources":["../../../src/media/audio/audio-driver.ts"],"names":[],"mappings":""}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { AudioDriver, AudioDriverContext } from "./audio-driver.js";
|
|
2
|
-
/**
|
|
3
|
-
* Realtime preview driver for a **pull-based** audio source (Mediabunny +
|
|
4
|
-
* WebCodecs). Nothing self-plays: while the composition is playing, a pump
|
|
5
|
-
* decodes buffers from the source's {@link AudioBufferSink} and schedules them on
|
|
6
|
-
* the shared {@link AudioContext}, anchoring the timeline clock to the context
|
|
7
|
-
* clock so audio stays locked to the frame clock. Pausing or scrubbing stops the
|
|
8
|
-
* pump (no audio while paused). A seek mid-playback re-anchors and reschedules.
|
|
9
|
-
*
|
|
10
|
-
* The clock works in **unwrapped** media time (monotonic, ignoring loop wrap), so
|
|
11
|
-
* a looping clip schedules iteration after iteration seamlessly and seek
|
|
12
|
-
* detection stays correct across the loop boundary.
|
|
13
|
-
*/
|
|
14
|
-
export declare class PreviewAudioDriver implements AudioDriver {
|
|
15
|
-
private readonly ctx;
|
|
16
|
-
private readonly _shared;
|
|
17
|
-
private _gain;
|
|
18
|
-
private readonly _nodes;
|
|
19
|
-
private _wasActive;
|
|
20
|
-
private _lastLocalFrame;
|
|
21
|
-
private _pumpToken;
|
|
22
|
-
private _anchored;
|
|
23
|
-
private _anchorCtxTime;
|
|
24
|
-
private _anchorUnwrapped;
|
|
25
|
-
private _effectiveRate;
|
|
26
|
-
private readonly _unsubs;
|
|
27
|
-
constructor(ctx: AudioDriverContext);
|
|
28
|
-
tick(localFrame: number): void;
|
|
29
|
-
deactivate(): void;
|
|
30
|
-
dispose(): void;
|
|
31
|
-
private _maybeStart;
|
|
32
|
-
/** True if the audio clock has drifted from the playhead — i.e. a seek happened. */
|
|
33
|
-
private _seekDetected;
|
|
34
|
-
private _ensureGain;
|
|
35
|
-
private _applyGain;
|
|
36
|
-
private _startPump;
|
|
37
|
-
/**
|
|
38
|
-
* Decoded buffers tagged with unwrapped media time, from `anchorUnwrapped`
|
|
39
|
-
* onward. Non-looping clips stream once to the trim end; looping clips replay
|
|
40
|
-
* the `[trimBefore, trimAfter)` segment forever (offsetting each iteration), so
|
|
41
|
-
* the consumer just keeps scheduling. Back-pressured by the consumer's awaits.
|
|
42
|
-
*/
|
|
43
|
-
private _stream;
|
|
44
|
-
private _stop;
|
|
45
|
-
private _stopNodes;
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=audio-for-preview.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-for-preview.d.ts","sourceRoot":"","sources":["../../../src/media/audio/audio-for-preview.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAqBzE;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IAiBxC,OAAO,CAAC,QAAQ,CAAC,GAAG;IAhBhC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAE3D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAK;IAG5B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAK;IAE3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAEpB,GAAG,EAAE,kBAAkB;IAgBpD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAiB9B,UAAU,IAAI,IAAI;IAKlB,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,WAAW;IAOnB,oFAAoF;IACpF,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,UAAU;YAMJ,UAAU;IAgExB;;;;;OAKG;YACY,OAAO;IAsCtB,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,UAAU;CAYnB"}
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { isSchedulable } from "./audio-source-mediabunny.js";
|
|
2
|
-
import { getSharedAudioContext } from "./shared-audio-context.js";
|
|
3
|
-
/** Keep roughly this many seconds of audio scheduled ahead of the context clock. */
|
|
4
|
-
const SCHEDULE_AHEAD = 1.0;
|
|
5
|
-
/** Decode this much lead-in before the start point so the decoder is primed. */
|
|
6
|
-
const PRIMING = 0.25;
|
|
7
|
-
/** Re-anchor (restart the pump) when the playhead diverges from the audio clock by more than this. */
|
|
8
|
-
const SEEK_THRESHOLD = 0.15;
|
|
9
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
10
|
-
/** Unwrapped media time (seconds) for a local frame — monotonic, ignores loop wrap. */
|
|
11
|
-
function unwrappedMedia(localFrame, timing) {
|
|
12
|
-
return (timing.trimBefore + localFrame * timing.playbackRate) / timing.fps;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Realtime preview driver for a **pull-based** audio source (Mediabunny +
|
|
16
|
-
* WebCodecs). Nothing self-plays: while the composition is playing, a pump
|
|
17
|
-
* decodes buffers from the source's {@link AudioBufferSink} and schedules them on
|
|
18
|
-
* the shared {@link AudioContext}, anchoring the timeline clock to the context
|
|
19
|
-
* clock so audio stays locked to the frame clock. Pausing or scrubbing stops the
|
|
20
|
-
* pump (no audio while paused). A seek mid-playback re-anchors and reschedules.
|
|
21
|
-
*
|
|
22
|
-
* The clock works in **unwrapped** media time (monotonic, ignoring loop wrap), so
|
|
23
|
-
* a looping clip schedules iteration after iteration seamlessly and seek
|
|
24
|
-
* detection stays correct across the loop boundary.
|
|
25
|
-
*/
|
|
26
|
-
export class PreviewAudioDriver {
|
|
27
|
-
ctx;
|
|
28
|
-
_shared;
|
|
29
|
-
_gain = null;
|
|
30
|
-
_nodes = new Set();
|
|
31
|
-
_wasActive = false;
|
|
32
|
-
_lastLocalFrame = 0;
|
|
33
|
-
// Pump identity (cancels a superseded pump) + the timeline↔context clock anchor.
|
|
34
|
-
_pumpToken = null;
|
|
35
|
-
_anchored = false;
|
|
36
|
-
_anchorCtxTime = 0;
|
|
37
|
-
_anchorUnwrapped = 0;
|
|
38
|
-
_effectiveRate = 1;
|
|
39
|
-
_unsubs = [];
|
|
40
|
-
constructor(ctx) {
|
|
41
|
-
this.ctx = ctx;
|
|
42
|
-
this._shared = getSharedAudioContext(ctx.comp);
|
|
43
|
-
this._unsubs.push(ctx.comp.isPlaying.subscribe((playing) => {
|
|
44
|
-
if (playing)
|
|
45
|
-
this._maybeStart(this._lastLocalFrame);
|
|
46
|
-
else
|
|
47
|
-
this._stop();
|
|
48
|
-
}));
|
|
49
|
-
// A rate change re-anchors so the new speed takes effect from here on.
|
|
50
|
-
this._unsubs.push(ctx.comp.playbackRate.subscribe(() => {
|
|
51
|
-
if (ctx.comp.isPlaying.get())
|
|
52
|
-
this._maybeStart(this._lastLocalFrame);
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
tick(localFrame) {
|
|
56
|
-
this._lastLocalFrame = localFrame;
|
|
57
|
-
const { source, comp } = this.ctx;
|
|
58
|
-
if (!source.isReady || !isSchedulable(source))
|
|
59
|
-
return;
|
|
60
|
-
const wasActive = this._wasActive;
|
|
61
|
-
this._wasActive = true;
|
|
62
|
-
if (comp.isPlaying.get()) {
|
|
63
|
-
this._applyGain();
|
|
64
|
-
if (this._pumpToken === null || !wasActive || this._seekDetected(localFrame)) {
|
|
65
|
-
this._startPump(source, localFrame);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
this._stop();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
deactivate() {
|
|
73
|
-
this._wasActive = false;
|
|
74
|
-
this._stop();
|
|
75
|
-
}
|
|
76
|
-
dispose() {
|
|
77
|
-
for (const u of this._unsubs)
|
|
78
|
-
u();
|
|
79
|
-
this._unsubs.length = 0;
|
|
80
|
-
this._stop();
|
|
81
|
-
this._gain?.disconnect();
|
|
82
|
-
this._gain = null;
|
|
83
|
-
}
|
|
84
|
-
_maybeStart(localFrame) {
|
|
85
|
-
const { source } = this.ctx;
|
|
86
|
-
if (this._wasActive && source.isReady && isSchedulable(source)) {
|
|
87
|
-
this._startPump(source, localFrame);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/** True if the audio clock has drifted from the playhead — i.e. a seek happened. */
|
|
91
|
-
_seekDetected(localFrame) {
|
|
92
|
-
if (!this._anchored)
|
|
93
|
-
return false;
|
|
94
|
-
const predicted = this._anchorUnwrapped + (this._shared.now() - this._anchorCtxTime) * this._effectiveRate;
|
|
95
|
-
const actual = unwrappedMedia(localFrame, this.ctx.timing);
|
|
96
|
-
return Math.abs(predicted - actual) > SEEK_THRESHOLD;
|
|
97
|
-
}
|
|
98
|
-
_ensureGain() {
|
|
99
|
-
if (!this._gain)
|
|
100
|
-
this._gain = this._shared.createChannelGain();
|
|
101
|
-
return this._gain;
|
|
102
|
-
}
|
|
103
|
-
_applyGain() {
|
|
104
|
-
const gain = this._ensureGain();
|
|
105
|
-
if (!gain)
|
|
106
|
-
return;
|
|
107
|
-
gain.gain.value = this.ctx.effectiveMuted() ? 0 : this.ctx.effectiveVolume();
|
|
108
|
-
}
|
|
109
|
-
async _startPump(source, fromLocalFrame) {
|
|
110
|
-
const token = {};
|
|
111
|
-
this._pumpToken = token;
|
|
112
|
-
this._anchored = false;
|
|
113
|
-
this._stopNodes();
|
|
114
|
-
const sink = source.sink;
|
|
115
|
-
if (!sink)
|
|
116
|
-
return;
|
|
117
|
-
await this._shared.resume();
|
|
118
|
-
if (token !== this._pumpToken)
|
|
119
|
-
return;
|
|
120
|
-
const ac = this._shared.context;
|
|
121
|
-
if (!ac)
|
|
122
|
-
return;
|
|
123
|
-
const gain = this._ensureGain();
|
|
124
|
-
if (!gain)
|
|
125
|
-
return;
|
|
126
|
-
this._applyGain();
|
|
127
|
-
const effRate = this.ctx.timing.playbackRate * this.ctx.comp.playbackRate.get();
|
|
128
|
-
if (effRate <= 0)
|
|
129
|
-
return; // reverse playback has no meaningful audio (documented)
|
|
130
|
-
const anchorUnwrapped = unwrappedMedia(fromLocalFrame, this.ctx.timing);
|
|
131
|
-
this._anchorCtxTime = ac.currentTime;
|
|
132
|
-
this._anchorUnwrapped = anchorUnwrapped;
|
|
133
|
-
this._effectiveRate = effRate;
|
|
134
|
-
this._anchored = true;
|
|
135
|
-
try {
|
|
136
|
-
for await (const { buffer, startUnwrapped } of this._stream(sink, anchorUnwrapped)) {
|
|
137
|
-
if (token !== this._pumpToken)
|
|
138
|
-
break;
|
|
139
|
-
const desiredUnwrapped = Math.max(startUnwrapped, anchorUnwrapped);
|
|
140
|
-
let when = this._anchorCtxTime + (desiredUnwrapped - anchorUnwrapped) / effRate;
|
|
141
|
-
// Throttle: stay ~SCHEDULE_AHEAD seconds ahead so we don't queue the file.
|
|
142
|
-
while (when - ac.currentTime > SCHEDULE_AHEAD) {
|
|
143
|
-
await sleep(120);
|
|
144
|
-
if (token !== this._pumpToken)
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
let offset = desiredUnwrapped - startUnwrapped;
|
|
148
|
-
if (when < ac.currentTime) {
|
|
149
|
-
// Slightly late — start immediately and advance into the buffer.
|
|
150
|
-
offset += (ac.currentTime - when) * effRate;
|
|
151
|
-
when = ac.currentTime;
|
|
152
|
-
}
|
|
153
|
-
if (offset >= buffer.duration)
|
|
154
|
-
continue; // fully behind the playhead — skip
|
|
155
|
-
const node = ac.createBufferSource();
|
|
156
|
-
node.buffer = buffer;
|
|
157
|
-
node.playbackRate.value = effRate;
|
|
158
|
-
node.connect(gain);
|
|
159
|
-
node.onended = () => {
|
|
160
|
-
this._nodes.delete(node);
|
|
161
|
-
try {
|
|
162
|
-
node.disconnect();
|
|
163
|
-
}
|
|
164
|
-
catch { }
|
|
165
|
-
};
|
|
166
|
-
node.start(when, offset);
|
|
167
|
-
this._nodes.add(node);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
catch (err) {
|
|
171
|
-
if (token === this._pumpToken)
|
|
172
|
-
console.warn("[smoove] audio pump error:", err);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Decoded buffers tagged with unwrapped media time, from `anchorUnwrapped`
|
|
177
|
-
* onward. Non-looping clips stream once to the trim end; looping clips replay
|
|
178
|
-
* the `[trimBefore, trimAfter)` segment forever (offsetting each iteration), so
|
|
179
|
-
* the consumer just keeps scheduling. Back-pressured by the consumer's awaits.
|
|
180
|
-
*/
|
|
181
|
-
async *_stream(sink, anchorUnwrapped) {
|
|
182
|
-
const t = this.ctx.timing;
|
|
183
|
-
const wrap = (item, startUnwrapped) => ({
|
|
184
|
-
buffer: item.buffer,
|
|
185
|
-
startUnwrapped,
|
|
186
|
-
});
|
|
187
|
-
const loopLenFrames = t.trimAfter !== undefined ? t.trimAfter - t.trimBefore : 0;
|
|
188
|
-
if (!t.loop || t.trimAfter === undefined || loopLenFrames <= 0) {
|
|
189
|
-
// Single pass to the trim end (or natural end).
|
|
190
|
-
const endMedia = t.trimAfter !== undefined ? t.trimAfter / t.fps : undefined;
|
|
191
|
-
const start = Math.max(0, anchorUnwrapped - PRIMING);
|
|
192
|
-
for await (const item of sink.buffers(start, endMedia)) {
|
|
193
|
-
yield wrap(item, item.timestamp);
|
|
194
|
-
}
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
// Looping: segment [segStart, segEnd) in source seconds.
|
|
198
|
-
const segStart = t.trimBefore / t.fps;
|
|
199
|
-
const segEnd = t.trimAfter / t.fps;
|
|
200
|
-
const loopDur = segEnd - segStart;
|
|
201
|
-
const kStart = Math.floor((anchorUnwrapped - segStart) / loopDur);
|
|
202
|
-
const posInSeg = anchorUnwrapped - (segStart + kStart * loopDur);
|
|
203
|
-
for (let k = kStart;; k++) {
|
|
204
|
-
const base = segStart + k * loopDur;
|
|
205
|
-
const fetchFrom = k === kStart ? segStart + posInSeg : segStart;
|
|
206
|
-
for await (const item of sink.buffers(Math.max(0, fetchFrom - PRIMING), segEnd)) {
|
|
207
|
-
// unwrapped start of this buffer within iteration k
|
|
208
|
-
yield wrap(item, base + (item.timestamp - segStart));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
_stop() {
|
|
213
|
-
this._pumpToken = null;
|
|
214
|
-
this._anchored = false;
|
|
215
|
-
this._stopNodes();
|
|
216
|
-
}
|
|
217
|
-
_stopNodes() {
|
|
218
|
-
for (const node of this._nodes) {
|
|
219
|
-
node.onended = null;
|
|
220
|
-
try {
|
|
221
|
-
node.stop();
|
|
222
|
-
}
|
|
223
|
-
catch { }
|
|
224
|
-
try {
|
|
225
|
-
node.disconnect();
|
|
226
|
-
}
|
|
227
|
-
catch { }
|
|
228
|
-
}
|
|
229
|
-
this._nodes.clear();
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
//# sourceMappingURL=audio-for-preview.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-for-preview.js","sourceRoot":"","sources":["../../../src/media/audio/audio-for-preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { AudioDriver, AudioDriverContext } from "./audio-driver.js";
|
|
2
|
-
/**
|
|
3
|
-
* Deterministic, non-playing audio driver for offline rendering. The engine
|
|
4
|
-
* captures canvas pixels frame-by-frame and has no in-engine audio encoder, so
|
|
5
|
-
* decoding/playing audio during render buys nothing. Instead each tick records
|
|
6
|
-
* an {@link AudioAsset} on the composition — the seam where a future ffmpeg
|
|
7
|
-
* audio-mux pass reads `comp.getAudioAssets()` to assemble the audio track.
|
|
8
|
-
*/
|
|
9
|
-
export declare class RenderingAudioDriver implements AudioDriver {
|
|
10
|
-
private readonly ctx;
|
|
11
|
-
constructor(ctx: AudioDriverContext);
|
|
12
|
-
tick(localFrame: number): void;
|
|
13
|
-
deactivate(): void;
|
|
14
|
-
dispose(): void;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=audio-for-rendering.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-for-rendering.d.ts","sourceRoot":"","sources":["../../../src/media/audio/audio-for-rendering.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,WAAW;IAC1C,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,kBAAkB;IAKpD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAc9B,UAAU,IAAI,IAAI;IAElB,OAAO,IAAI,IAAI;CAChB"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { getMediaTime } from "../media-time.js";
|
|
2
|
-
/**
|
|
3
|
-
* Deterministic, non-playing audio driver for offline rendering. The engine
|
|
4
|
-
* captures canvas pixels frame-by-frame and has no in-engine audio encoder, so
|
|
5
|
-
* decoding/playing audio during render buys nothing. Instead each tick records
|
|
6
|
-
* an {@link AudioAsset} on the composition — the seam where a future ffmpeg
|
|
7
|
-
* audio-mux pass reads `comp.getAudioAssets()` to assemble the audio track.
|
|
8
|
-
*/
|
|
9
|
-
export class RenderingAudioDriver {
|
|
10
|
-
ctx;
|
|
11
|
-
constructor(ctx) {
|
|
12
|
-
this.ctx = ctx;
|
|
13
|
-
// Never audible during render.
|
|
14
|
-
ctx.source.setMuted(true);
|
|
15
|
-
}
|
|
16
|
-
tick(localFrame) {
|
|
17
|
-
const { comp, timing } = this.ctx;
|
|
18
|
-
const mediaTime = getMediaTime(localFrame, timing);
|
|
19
|
-
comp._collectAudioAsset({
|
|
20
|
-
id: this.ctx.id,
|
|
21
|
-
src: this.ctx.src,
|
|
22
|
-
frame: comp.frame.get(),
|
|
23
|
-
mediaTime,
|
|
24
|
-
volume: this.ctx.effectiveVolume(),
|
|
25
|
-
muted: this.ctx.effectiveMuted(),
|
|
26
|
-
playbackRate: timing.playbackRate,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
deactivate() { }
|
|
30
|
-
dispose() { }
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=audio-for-rendering.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-for-rendering.js","sourceRoot":"","sources":["../../../src/media/audio/audio-for-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IACF;IAA7B,YAA6B,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;QAClD,+BAA+B;QAC/B,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,UAAkB;QACrB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAClC,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,kBAAkB,CAAC;YACtB,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE;YACf,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACvB,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE;YAClC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;YAChC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,KAAU,CAAC;IAErB,OAAO,KAAU,CAAC;CACnB"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { AudioSource, SeekMode } from "./audio-source.js";
|
|
2
|
-
/**
|
|
3
|
-
* Preview-mode {@link AudioSource}: wraps an `HTMLAudioElement` and drives it in
|
|
4
|
-
* realtime. Ported from {@link BrowserVideoSource} minus the drawable/rvfc bits
|
|
5
|
-
* (audio produces no frames). A server renderer injects a different source via
|
|
6
|
-
* `AudioConfig.sourceFactory`.
|
|
7
|
-
*/
|
|
8
|
-
export declare class BrowserAudioSource implements AudioSource {
|
|
9
|
-
private readonly _el;
|
|
10
|
-
private _ready;
|
|
11
|
-
private readonly _readyCbs;
|
|
12
|
-
private _seeking;
|
|
13
|
-
private _pending;
|
|
14
|
-
constructor();
|
|
15
|
-
load(src: string): Promise<void>;
|
|
16
|
-
get duration(): number;
|
|
17
|
-
get currentTime(): number;
|
|
18
|
-
get isReady(): boolean;
|
|
19
|
-
seek(timeSeconds: number, mode?: SeekMode): Promise<void>;
|
|
20
|
-
/** Issue the pending seek if none is in flight; chains the latest target after each completes. */
|
|
21
|
-
private _drainSeek;
|
|
22
|
-
play(): Promise<void>;
|
|
23
|
-
pause(): void;
|
|
24
|
-
setMuted(muted: boolean): void;
|
|
25
|
-
setVolume(volume: number): void;
|
|
26
|
-
setPlaybackRate(rate: number): void;
|
|
27
|
-
onReady(cb: () => void): () => void;
|
|
28
|
-
destroy(): void;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=audio-source-browser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-source-browser.d.ts","sourceRoot":"","sources":["../../../src/media/audio/audio-source-browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAM/D;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAKnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAA+E;;IAa/F,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,QAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpE,kGAAkG;IAClG,OAAO,CAAC,UAAU;IA6BlB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,IAAI,IAAI;IAIb,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAInC,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IASnC,OAAO,IAAI,IAAI;CAQhB"}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Preview-mode {@link AudioSource}: wraps an `HTMLAudioElement` and drives it in
|
|
3
|
-
* realtime. Ported from {@link BrowserVideoSource} minus the drawable/rvfc bits
|
|
4
|
-
* (audio produces no frames). A server renderer injects a different source via
|
|
5
|
-
* `AudioConfig.sourceFactory`.
|
|
6
|
-
*/
|
|
7
|
-
export class BrowserAudioSource {
|
|
8
|
-
_el;
|
|
9
|
-
_ready = false;
|
|
10
|
-
_readyCbs = new Set();
|
|
11
|
-
// Seek coalescing: keep at most one seek in flight. Rapid scrubbing only ever
|
|
12
|
-
// lands the latest target — intermediate ones are dropped — so the backlog
|
|
13
|
-
// never grows (which is what makes scrubbing a large clip degrade over time).
|
|
14
|
-
_seeking = false;
|
|
15
|
-
_pending = null;
|
|
16
|
-
constructor() {
|
|
17
|
-
// createElement (not `new Audio()`) dodges the global `Audio` constructor,
|
|
18
|
-
// which collides with our exported `Audio` class.
|
|
19
|
-
const el = document.createElement("audio");
|
|
20
|
-
el.crossOrigin = "anonymous";
|
|
21
|
-
el.preload = "auto";
|
|
22
|
-
// Muted so the browser allows programmatic play()/seek before any user gesture.
|
|
23
|
-
el.muted = true;
|
|
24
|
-
this._el = el;
|
|
25
|
-
}
|
|
26
|
-
load(src) {
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
const onReady = () => {
|
|
29
|
-
cleanup();
|
|
30
|
-
this._ready = true;
|
|
31
|
-
for (const cb of this._readyCbs)
|
|
32
|
-
cb();
|
|
33
|
-
resolve();
|
|
34
|
-
};
|
|
35
|
-
const onErr = () => {
|
|
36
|
-
cleanup();
|
|
37
|
-
reject(new Error(`Failed to load audio: ${src}`));
|
|
38
|
-
};
|
|
39
|
-
const cleanup = () => {
|
|
40
|
-
this._el.removeEventListener("loadeddata", onReady);
|
|
41
|
-
this._el.removeEventListener("error", onErr);
|
|
42
|
-
};
|
|
43
|
-
this._el.addEventListener("loadeddata", onReady);
|
|
44
|
-
this._el.addEventListener("error", onErr);
|
|
45
|
-
this._el.src = src;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
get duration() {
|
|
49
|
-
return Number.isFinite(this._el.duration) ? this._el.duration : 0;
|
|
50
|
-
}
|
|
51
|
-
get currentTime() {
|
|
52
|
-
return this._el.currentTime;
|
|
53
|
-
}
|
|
54
|
-
get isReady() {
|
|
55
|
-
return this._ready;
|
|
56
|
-
}
|
|
57
|
-
seek(timeSeconds, mode = "precise") {
|
|
58
|
-
const clamped = Math.max(0, this.duration > 0 ? Math.min(this.duration, timeSeconds) : timeSeconds);
|
|
59
|
-
// No-op seek with nothing in flight: already there, resolve immediately.
|
|
60
|
-
if (!this._seeking && Math.abs(this._el.currentTime - clamped) <= 1e-4) {
|
|
61
|
-
return Promise.resolve();
|
|
62
|
-
}
|
|
63
|
-
return new Promise((resolve) => {
|
|
64
|
-
if (this._pending) {
|
|
65
|
-
// Supersede the queued target — only the latest scrub position matters.
|
|
66
|
-
this._pending.time = clamped;
|
|
67
|
-
this._pending.mode = mode;
|
|
68
|
-
this._pending.resolvers.push(resolve);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
this._pending = { time: clamped, mode, resolvers: [resolve] };
|
|
72
|
-
}
|
|
73
|
-
this._drainSeek();
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
/** Issue the pending seek if none is in flight; chains the latest target after each completes. */
|
|
77
|
-
_drainSeek() {
|
|
78
|
-
if (this._seeking || !this._pending)
|
|
79
|
-
return;
|
|
80
|
-
const { time, mode, resolvers } = this._pending;
|
|
81
|
-
this._pending = null;
|
|
82
|
-
if (Math.abs(this._el.currentTime - time) <= 1e-4) {
|
|
83
|
-
for (const r of resolvers)
|
|
84
|
-
r();
|
|
85
|
-
this._drainSeek();
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
this._seeking = true;
|
|
89
|
-
const onSeeked = () => {
|
|
90
|
-
this._el.removeEventListener("seeked", onSeeked);
|
|
91
|
-
this._seeking = false;
|
|
92
|
-
for (const r of resolvers)
|
|
93
|
-
r();
|
|
94
|
-
// A newer target may have arrived mid-seek — land it now.
|
|
95
|
-
this._drainSeek();
|
|
96
|
-
};
|
|
97
|
-
this._el.addEventListener("seeked", onSeeked);
|
|
98
|
-
// fastSeek jumps to the nearest keyframe — much snappier for scrubbing a
|
|
99
|
-
// large clip. Fall back to a precise currentTime seek when unavailable.
|
|
100
|
-
if (mode === "fast" && typeof this._el.fastSeek === "function") {
|
|
101
|
-
this._el.fastSeek(time);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
this._el.currentTime = time;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
play() {
|
|
108
|
-
return this._el.play();
|
|
109
|
-
}
|
|
110
|
-
pause() {
|
|
111
|
-
this._el.pause();
|
|
112
|
-
}
|
|
113
|
-
setMuted(muted) {
|
|
114
|
-
this._el.muted = muted;
|
|
115
|
-
}
|
|
116
|
-
setVolume(volume) {
|
|
117
|
-
this._el.volume = Math.max(0, Math.min(1, volume));
|
|
118
|
-
}
|
|
119
|
-
setPlaybackRate(rate) {
|
|
120
|
-
this._el.playbackRate = rate;
|
|
121
|
-
}
|
|
122
|
-
onReady(cb) {
|
|
123
|
-
if (this._ready) {
|
|
124
|
-
cb();
|
|
125
|
-
return () => { };
|
|
126
|
-
}
|
|
127
|
-
this._readyCbs.add(cb);
|
|
128
|
-
return () => this._readyCbs.delete(cb);
|
|
129
|
-
}
|
|
130
|
-
destroy() {
|
|
131
|
-
this._el.pause();
|
|
132
|
-
this._el.removeAttribute("src");
|
|
133
|
-
this._el.load();
|
|
134
|
-
this._readyCbs.clear();
|
|
135
|
-
this._pending = null;
|
|
136
|
-
this._seeking = false;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=audio-source-browser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-source-browser.js","sourceRoot":"","sources":["../../../src/media/audio/audio-source-browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { AudioBufferSink } from "mediabunny";
|
|
2
|
-
import type { AudioSource, SeekMode } from "./audio-source.js";
|
|
3
|
-
/**
|
|
4
|
-
* A preview {@link AudioSource} that also exposes a Mediabunny
|
|
5
|
-
* {@link AudioBufferSink}. The {@link PreviewAudioDriver} owns the Web Audio
|
|
6
|
-
* scheduling, so all it needs from the source is decoded buffers on demand — the
|
|
7
|
-
* old self-playing `play()/pause()/seek()` surface is inert here.
|
|
8
|
-
*/
|
|
9
|
-
export interface SchedulableAudioSource extends AudioSource {
|
|
10
|
-
/** Decoded-buffer sink for the primary audio track, or null until ready. */
|
|
11
|
-
readonly sink: AudioBufferSink | null;
|
|
12
|
-
/** Track start time in seconds (videos don't always start at 0). */
|
|
13
|
-
readonly firstTimestamp: number;
|
|
14
|
-
}
|
|
15
|
-
export declare function isSchedulable(s: AudioSource): s is SchedulableAudioSource;
|
|
16
|
-
/**
|
|
17
|
-
* Preview-mode {@link AudioSource} backed by Mediabunny + WebCodecs. Replaces the
|
|
18
|
-
* `HTMLAudioElement`-based {@link BrowserAudioSource}: it only decodes — playback,
|
|
19
|
-
* volume, mute and rate are driven by the {@link PreviewAudioDriver}'s Web Audio
|
|
20
|
-
* scheduler, which reads {@link sink}.
|
|
21
|
-
*/
|
|
22
|
-
export declare class MediabunnyAudioSource implements SchedulableAudioSource {
|
|
23
|
-
private _input;
|
|
24
|
-
private _sink;
|
|
25
|
-
private _ready;
|
|
26
|
-
private _disposed;
|
|
27
|
-
private _duration;
|
|
28
|
-
private _firstTimestamp;
|
|
29
|
-
private readonly _readyCbs;
|
|
30
|
-
load(src: string): Promise<void>;
|
|
31
|
-
get sink(): AudioBufferSink | null;
|
|
32
|
-
get firstTimestamp(): number;
|
|
33
|
-
get duration(): number;
|
|
34
|
-
get currentTime(): number;
|
|
35
|
-
get isReady(): boolean;
|
|
36
|
-
seek(_timeSeconds: number, _mode?: SeekMode): Promise<void>;
|
|
37
|
-
play(): Promise<void>;
|
|
38
|
-
pause(): void;
|
|
39
|
-
setMuted(_muted: boolean): void;
|
|
40
|
-
setVolume(_volume: number): void;
|
|
41
|
-
setPlaybackRate(_rate: number): void;
|
|
42
|
-
onReady(cb: () => void): () => void;
|
|
43
|
-
destroy(): void;
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=audio-source-mediabunny.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audio-source-mediabunny.d.ts","sourceRoot":"","sources":["../../../src/media/audio/audio-source-mediabunny.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,eAAe,EAAoB,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IACtC,oEAAoE;IACpE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,IAAI,sBAAsB,CAEzE;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,sBAAsB;IAClE,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAE7C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtC,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAGD,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAG3D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAGrB,KAAK,IAAI,IAAI;IACb,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAC/B,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAChC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAEpC,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IASnC,OAAO,IAAI,IAAI;CAOhB"}
|