remotion 4.0.523 → 4.0.524
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/cjs/audio/shared-audio-tags.d.ts +1 -0
- package/dist/cjs/audio/shared-audio-tags.js +2 -6
- package/dist/cjs/audio/streaming-pitch-shifter.d.ts +18 -0
- package/dist/cjs/audio/streaming-pitch-shifter.js +349 -0
- package/dist/cjs/internals.d.ts +1 -0
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/index.mjs +3 -7
- package/dist/esm/version.mjs +1 -1
- package/package.json +2 -2
|
@@ -91,12 +91,6 @@ const shouldSaveForLater = (state) => {
|
|
|
91
91
|
const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled, previewSampleRate, _experimentalKeepAudioContextAlive, }) => {
|
|
92
92
|
const logLevel = (0, log_level_context_js_1.useLogLevel)();
|
|
93
93
|
const sampleRate = previewSampleRate !== null && previewSampleRate !== void 0 ? previewSampleRate : 48000;
|
|
94
|
-
(0, react_1.useEffect)(() => {
|
|
95
|
-
if (typeof window === 'undefined') {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
window.remotion_sampleRate = sampleRate;
|
|
99
|
-
}, [sampleRate]);
|
|
100
94
|
const ctxAndGain = (0, use_audio_context_js_1.useSingletonAudioContext)({
|
|
101
95
|
logLevel,
|
|
102
96
|
latencyHint: audioLatencyHint,
|
|
@@ -323,6 +317,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
|
|
|
323
317
|
const audioContextValue = (0, react_1.useMemo)(() => {
|
|
324
318
|
var _a, _b;
|
|
325
319
|
return {
|
|
320
|
+
sampleRate,
|
|
326
321
|
audioContext: (_a = ctxAndGain === null || ctxAndGain === void 0 ? void 0 : ctxAndGain.audioContext) !== null && _a !== void 0 ? _a : null,
|
|
327
322
|
getAudioContextState: () => {
|
|
328
323
|
var _a;
|
|
@@ -340,6 +335,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
|
|
|
340
335
|
_experimentalKeepAudioContextAlive,
|
|
341
336
|
};
|
|
342
337
|
}, [
|
|
338
|
+
sampleRate,
|
|
343
339
|
ctxAndGain,
|
|
344
340
|
audioSyncAnchor,
|
|
345
341
|
audioSyncAnchorEmitter,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type PlanarAudio = Float32Array[];
|
|
2
|
+
export declare class StreamingPitchShifter {
|
|
3
|
+
private readonly numberOfChannels;
|
|
4
|
+
private readonly stretcher;
|
|
5
|
+
private readonly resampler;
|
|
6
|
+
private readonly outputQueue;
|
|
7
|
+
private totalInputFrames;
|
|
8
|
+
private totalOutputFrames;
|
|
9
|
+
constructor({ numberOfChannels, sampleRate, toneFrequency }: {
|
|
10
|
+
numberOfChannels: number;
|
|
11
|
+
sampleRate: number;
|
|
12
|
+
toneFrequency: number;
|
|
13
|
+
});
|
|
14
|
+
append(audio: PlanarAudio): PlanarAudio;
|
|
15
|
+
private takeAvailableOutput;
|
|
16
|
+
finalize(): Float32Array<ArrayBuffer>[];
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamingPitchShifter = void 0;
|
|
4
|
+
// The pitch-shifting algorithm is adapted from Vanilagy's WSOLA audio
|
|
5
|
+
// stretcher: https://gist.github.com/Vanilagy/05f7901f4c4398356657e3a86c7aee05
|
|
6
|
+
const REFERENCE_SAMPLE_RATE = 48000;
|
|
7
|
+
const REFERENCE_HOP_SIZE = 512;
|
|
8
|
+
const makePlanarAudio = (numberOfChannels, length) => {
|
|
9
|
+
return new Array(numberOfChannels)
|
|
10
|
+
.fill(null)
|
|
11
|
+
.map(() => new Float32Array(length));
|
|
12
|
+
};
|
|
13
|
+
const ensurePlanarCapacity = ({ buffers, requiredLength, }) => {
|
|
14
|
+
if (buffers[0].length >= requiredLength) {
|
|
15
|
+
return buffers;
|
|
16
|
+
}
|
|
17
|
+
let newLength = buffers[0].length;
|
|
18
|
+
while (newLength < requiredLength) {
|
|
19
|
+
newLength *= 2;
|
|
20
|
+
}
|
|
21
|
+
return buffers.map((buffer) => {
|
|
22
|
+
const expanded = new Float32Array(newLength);
|
|
23
|
+
expanded.set(buffer);
|
|
24
|
+
return expanded;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
class PlanarAudioQueue {
|
|
28
|
+
chunks = [];
|
|
29
|
+
length = 0;
|
|
30
|
+
push(audio) {
|
|
31
|
+
if (audio[0].length === 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.chunks.push(audio);
|
|
35
|
+
this.length += audio[0].length;
|
|
36
|
+
}
|
|
37
|
+
take(numberOfFrames, numberOfChannels) {
|
|
38
|
+
const framesToTake = Math.min(numberOfFrames, this.length);
|
|
39
|
+
const result = makePlanarAudio(numberOfChannels, framesToTake);
|
|
40
|
+
let written = 0;
|
|
41
|
+
while (written < framesToTake) {
|
|
42
|
+
const first = this.chunks[0];
|
|
43
|
+
const available = first[0].length;
|
|
44
|
+
const count = Math.min(available, framesToTake - written);
|
|
45
|
+
for (let channel = 0; channel < numberOfChannels; channel++) {
|
|
46
|
+
result[channel].set(first[channel].subarray(0, count), written);
|
|
47
|
+
}
|
|
48
|
+
if (count === available) {
|
|
49
|
+
this.chunks.shift();
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.chunks[0] = first.map((channel) => channel.subarray(count));
|
|
53
|
+
}
|
|
54
|
+
written += count;
|
|
55
|
+
this.length -= count;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
getLength() {
|
|
60
|
+
return this.length;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// A streaming implementation of Waveform Similarity Overlap-Add. It changes
|
|
64
|
+
// duration while retaining pitch. Pitch shifting is achieved by following this
|
|
65
|
+
// stage with a resampler that restores the original duration.
|
|
66
|
+
class StreamingTimeStretcher {
|
|
67
|
+
numberOfChannels;
|
|
68
|
+
factor;
|
|
69
|
+
hopSize;
|
|
70
|
+
windowSize;
|
|
71
|
+
searchRadius;
|
|
72
|
+
analysisHop;
|
|
73
|
+
input;
|
|
74
|
+
inputLength = 0;
|
|
75
|
+
output;
|
|
76
|
+
outputLength = 0;
|
|
77
|
+
analysisPosition = 0;
|
|
78
|
+
synthesisPosition = 0;
|
|
79
|
+
initialized = false;
|
|
80
|
+
finalized = false;
|
|
81
|
+
totalInputFrames = 0;
|
|
82
|
+
totalOutputFrames = 0;
|
|
83
|
+
constructor({ numberOfChannels, sampleRate, factor, }) {
|
|
84
|
+
this.numberOfChannels = numberOfChannels;
|
|
85
|
+
this.factor = factor;
|
|
86
|
+
this.hopSize = Math.max(32, Math.round((REFERENCE_HOP_SIZE * sampleRate) / REFERENCE_SAMPLE_RATE));
|
|
87
|
+
this.windowSize = this.hopSize * 2;
|
|
88
|
+
this.searchRadius = this.hopSize;
|
|
89
|
+
this.analysisHop = this.hopSize / factor;
|
|
90
|
+
this.input = makePlanarAudio(numberOfChannels, 65536);
|
|
91
|
+
this.output = makePlanarAudio(numberOfChannels, 65536);
|
|
92
|
+
}
|
|
93
|
+
append(audio) {
|
|
94
|
+
if (this.finalized) {
|
|
95
|
+
throw new Error('Cannot append audio after the time stretcher was finalized.');
|
|
96
|
+
}
|
|
97
|
+
const { length } = audio[0];
|
|
98
|
+
this.input = ensurePlanarCapacity({
|
|
99
|
+
buffers: this.input,
|
|
100
|
+
requiredLength: this.inputLength + length,
|
|
101
|
+
});
|
|
102
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
103
|
+
this.input[channel].set(audio[channel], this.inputLength);
|
|
104
|
+
}
|
|
105
|
+
this.inputLength += length;
|
|
106
|
+
this.totalInputFrames += length;
|
|
107
|
+
this.process();
|
|
108
|
+
return this.drainFinalizedOutput();
|
|
109
|
+
}
|
|
110
|
+
findBestAnalysisPosition({ expectedPosition, nextSynthesisPosition, }) {
|
|
111
|
+
const minimum = Math.max(0, Math.floor(expectedPosition - this.searchRadius));
|
|
112
|
+
const maximum = Math.min(this.inputLength - this.windowSize, Math.ceil(expectedPosition + this.searchRadius));
|
|
113
|
+
let bestPosition = minimum;
|
|
114
|
+
let bestCorrelation = -Infinity;
|
|
115
|
+
for (let candidate = minimum; candidate <= maximum; candidate += 4) {
|
|
116
|
+
let dotProduct = 0;
|
|
117
|
+
let previousEnergy = 0;
|
|
118
|
+
let candidateEnergy = 0;
|
|
119
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
120
|
+
const previous = this.output[channel];
|
|
121
|
+
const incoming = this.input[channel];
|
|
122
|
+
for (let frame = 0; frame < this.hopSize; frame += 2) {
|
|
123
|
+
const previousValue = previous[nextSynthesisPosition + frame];
|
|
124
|
+
const candidateValue = incoming[candidate + frame];
|
|
125
|
+
dotProduct += previousValue * candidateValue;
|
|
126
|
+
previousEnergy += previousValue * previousValue;
|
|
127
|
+
candidateEnergy += candidateValue * candidateValue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const correlation = dotProduct /
|
|
131
|
+
(Math.sqrt(previousEnergy * candidateEnergy) || Number.EPSILON);
|
|
132
|
+
if (correlation > bestCorrelation) {
|
|
133
|
+
bestCorrelation = correlation;
|
|
134
|
+
bestPosition = candidate;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const fineMinimum = Math.max(minimum, bestPosition - 4);
|
|
138
|
+
const fineMaximum = Math.min(maximum, bestPosition + 4);
|
|
139
|
+
for (let candidate = fineMinimum; candidate <= fineMaximum; candidate++) {
|
|
140
|
+
let dotProduct = 0;
|
|
141
|
+
let previousEnergy = 0;
|
|
142
|
+
let candidateEnergy = 0;
|
|
143
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
144
|
+
const previous = this.output[channel];
|
|
145
|
+
const incoming = this.input[channel];
|
|
146
|
+
for (let frame = 0; frame < this.hopSize; frame++) {
|
|
147
|
+
const previousValue = previous[nextSynthesisPosition + frame];
|
|
148
|
+
const candidateValue = incoming[candidate + frame];
|
|
149
|
+
dotProduct += previousValue * candidateValue;
|
|
150
|
+
previousEnergy += previousValue * previousValue;
|
|
151
|
+
candidateEnergy += candidateValue * candidateValue;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const correlation = dotProduct /
|
|
155
|
+
(Math.sqrt(previousEnergy * candidateEnergy) || Number.EPSILON);
|
|
156
|
+
if (correlation > bestCorrelation) {
|
|
157
|
+
bestCorrelation = correlation;
|
|
158
|
+
bestPosition = candidate;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return bestPosition;
|
|
162
|
+
}
|
|
163
|
+
process() {
|
|
164
|
+
if (!this.initialized) {
|
|
165
|
+
if (this.inputLength < this.windowSize + this.searchRadius) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
169
|
+
this.output[channel].set(this.input[channel].subarray(0, this.windowSize));
|
|
170
|
+
}
|
|
171
|
+
this.outputLength = this.windowSize;
|
|
172
|
+
this.initialized = true;
|
|
173
|
+
}
|
|
174
|
+
while (true) {
|
|
175
|
+
const expectedPosition = this.analysisPosition + this.analysisHop;
|
|
176
|
+
if (expectedPosition + this.searchRadius + this.windowSize >
|
|
177
|
+
this.inputLength) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
const nextSynthesisPosition = this.synthesisPosition + this.hopSize;
|
|
181
|
+
this.output = ensurePlanarCapacity({
|
|
182
|
+
buffers: this.output,
|
|
183
|
+
requiredLength: nextSynthesisPosition + this.windowSize,
|
|
184
|
+
});
|
|
185
|
+
const bestPosition = this.findBestAnalysisPosition({
|
|
186
|
+
expectedPosition,
|
|
187
|
+
nextSynthesisPosition,
|
|
188
|
+
});
|
|
189
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
190
|
+
for (let frame = 0; frame < this.hopSize; frame++) {
|
|
191
|
+
const fadeIn = 0.5 - 0.5 * Math.cos((Math.PI * (frame + 1)) / (this.hopSize + 1));
|
|
192
|
+
const outputIndex = nextSynthesisPosition + frame;
|
|
193
|
+
this.output[channel][outputIndex] =
|
|
194
|
+
this.output[channel][outputIndex] * (1 - fadeIn) +
|
|
195
|
+
this.input[channel][bestPosition + frame] * fadeIn;
|
|
196
|
+
}
|
|
197
|
+
this.output[channel].set(this.input[channel].subarray(bestPosition + this.hopSize, bestPosition + this.windowSize), nextSynthesisPosition + this.hopSize);
|
|
198
|
+
}
|
|
199
|
+
// Keep the analysis clock independent from the correlation correction.
|
|
200
|
+
// Periodic signals can have equally good matches at an earlier period; if
|
|
201
|
+
// the correction became the next clock position, the iterator could stop
|
|
202
|
+
// making forward progress.
|
|
203
|
+
this.analysisPosition = expectedPosition;
|
|
204
|
+
this.synthesisPosition = nextSynthesisPosition;
|
|
205
|
+
this.outputLength = nextSynthesisPosition + this.windowSize;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
drainFinalizedOutput() {
|
|
209
|
+
if (!this.initialized) {
|
|
210
|
+
return makePlanarAudio(this.numberOfChannels, 0);
|
|
211
|
+
}
|
|
212
|
+
const finalizedLength = Math.max(0, this.synthesisPosition + this.hopSize);
|
|
213
|
+
const result = this.output.map((channel) => channel.slice(0, finalizedLength));
|
|
214
|
+
this.totalOutputFrames += finalizedLength;
|
|
215
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
216
|
+
this.output[channel].copyWithin(0, finalizedLength, this.outputLength);
|
|
217
|
+
}
|
|
218
|
+
this.outputLength -= finalizedLength;
|
|
219
|
+
this.synthesisPosition -= finalizedLength;
|
|
220
|
+
const inputFramesToDiscard = Math.max(0, Math.floor(this.analysisPosition) - this.searchRadius);
|
|
221
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
222
|
+
this.input[channel].copyWithin(0, inputFramesToDiscard, this.inputLength);
|
|
223
|
+
}
|
|
224
|
+
this.inputLength -= inputFramesToDiscard;
|
|
225
|
+
this.analysisPosition -= inputFramesToDiscard;
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
finalize() {
|
|
229
|
+
if (this.finalized) {
|
|
230
|
+
throw new Error('The time stretcher has already been finalized.');
|
|
231
|
+
}
|
|
232
|
+
this.finalized = true;
|
|
233
|
+
const targetLength = Math.round(this.totalInputFrames * this.factor);
|
|
234
|
+
const padding = makePlanarAudio(this.numberOfChannels, this.windowSize + this.searchRadius * 2);
|
|
235
|
+
this.input = ensurePlanarCapacity({
|
|
236
|
+
buffers: this.input,
|
|
237
|
+
requiredLength: this.inputLength + padding[0].length,
|
|
238
|
+
});
|
|
239
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
240
|
+
this.input[channel].set(padding[channel], this.inputLength);
|
|
241
|
+
}
|
|
242
|
+
this.inputLength += padding[0].length;
|
|
243
|
+
this.process();
|
|
244
|
+
const finalized = this.drainFinalizedOutput();
|
|
245
|
+
const remaining = Math.max(0, targetLength - this.totalOutputFrames + finalized[0].length);
|
|
246
|
+
if (finalized[0].length >= remaining) {
|
|
247
|
+
return finalized.map((channel) => channel.slice(0, remaining));
|
|
248
|
+
}
|
|
249
|
+
const result = makePlanarAudio(this.numberOfChannels, remaining);
|
|
250
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
251
|
+
result[channel].set(finalized[channel]);
|
|
252
|
+
}
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
class StreamingLinearResampler {
|
|
257
|
+
numberOfChannels;
|
|
258
|
+
step;
|
|
259
|
+
input;
|
|
260
|
+
inputLength = 0;
|
|
261
|
+
position = 0;
|
|
262
|
+
constructor({ numberOfChannels, step, }) {
|
|
263
|
+
this.numberOfChannels = numberOfChannels;
|
|
264
|
+
this.step = step;
|
|
265
|
+
this.input = makePlanarAudio(numberOfChannels, 65536);
|
|
266
|
+
}
|
|
267
|
+
append(audio) {
|
|
268
|
+
this.input = ensurePlanarCapacity({
|
|
269
|
+
buffers: this.input,
|
|
270
|
+
requiredLength: this.inputLength + audio[0].length,
|
|
271
|
+
});
|
|
272
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
273
|
+
this.input[channel].set(audio[channel], this.inputLength);
|
|
274
|
+
}
|
|
275
|
+
this.inputLength += audio[0].length;
|
|
276
|
+
return this.process(false);
|
|
277
|
+
}
|
|
278
|
+
process(finalizing) {
|
|
279
|
+
const outputLength = Math.max(0, Math.floor((this.inputLength - (finalizing ? 0 : 1) - this.position) / this.step) + 1);
|
|
280
|
+
const result = makePlanarAudio(this.numberOfChannels, outputLength);
|
|
281
|
+
for (let outputFrame = 0; outputFrame < outputLength; outputFrame++) {
|
|
282
|
+
const leftIndex = Math.floor(this.position);
|
|
283
|
+
const rightIndex = Math.min(leftIndex + 1, this.inputLength - 1);
|
|
284
|
+
const fraction = this.position - leftIndex;
|
|
285
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
286
|
+
const left = this.input[channel][leftIndex];
|
|
287
|
+
const right = this.input[channel][rightIndex];
|
|
288
|
+
result[channel][outputFrame] = left + (right - left) * fraction;
|
|
289
|
+
}
|
|
290
|
+
this.position += this.step;
|
|
291
|
+
}
|
|
292
|
+
const discard = Math.min(Math.floor(this.position), this.inputLength);
|
|
293
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
294
|
+
this.input[channel].copyWithin(0, discard, this.inputLength);
|
|
295
|
+
}
|
|
296
|
+
this.inputLength -= discard;
|
|
297
|
+
this.position -= discard;
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
finalize() {
|
|
301
|
+
return this.process(true);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
class StreamingPitchShifter {
|
|
305
|
+
numberOfChannels;
|
|
306
|
+
stretcher;
|
|
307
|
+
resampler;
|
|
308
|
+
outputQueue = new PlanarAudioQueue();
|
|
309
|
+
totalInputFrames = 0;
|
|
310
|
+
totalOutputFrames = 0;
|
|
311
|
+
constructor({ numberOfChannels, sampleRate, toneFrequency, }) {
|
|
312
|
+
this.numberOfChannels = numberOfChannels;
|
|
313
|
+
this.stretcher = new StreamingTimeStretcher({
|
|
314
|
+
numberOfChannels,
|
|
315
|
+
sampleRate,
|
|
316
|
+
factor: toneFrequency,
|
|
317
|
+
});
|
|
318
|
+
this.resampler = new StreamingLinearResampler({
|
|
319
|
+
numberOfChannels,
|
|
320
|
+
step: toneFrequency,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
append(audio) {
|
|
324
|
+
this.totalInputFrames += audio[0].length;
|
|
325
|
+
const stretched = this.stretcher.append(audio);
|
|
326
|
+
this.outputQueue.push(this.resampler.append(stretched));
|
|
327
|
+
return this.takeAvailableOutput();
|
|
328
|
+
}
|
|
329
|
+
takeAvailableOutput() {
|
|
330
|
+
const availableInputFrames = this.totalInputFrames - this.totalOutputFrames;
|
|
331
|
+
const framesToTake = Math.min(availableInputFrames, this.outputQueue.getLength());
|
|
332
|
+
const result = this.outputQueue.take(framesToTake, this.numberOfChannels);
|
|
333
|
+
this.totalOutputFrames += framesToTake;
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
finalize() {
|
|
337
|
+
this.outputQueue.push(this.resampler.append(this.stretcher.finalize()));
|
|
338
|
+
this.outputQueue.push(this.resampler.finalize());
|
|
339
|
+
const remaining = this.totalInputFrames - this.totalOutputFrames;
|
|
340
|
+
const available = this.outputQueue.take(Math.min(remaining, this.outputQueue.getLength()), this.numberOfChannels);
|
|
341
|
+
const result = makePlanarAudio(this.numberOfChannels, remaining);
|
|
342
|
+
for (let channel = 0; channel < this.numberOfChannels; channel++) {
|
|
343
|
+
result[channel].set(available[channel]);
|
|
344
|
+
}
|
|
345
|
+
this.totalOutputFrames += remaining;
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.StreamingPitchShifter = StreamingPitchShifter;
|
package/dist/cjs/internals.d.ts
CHANGED
|
@@ -816,6 +816,7 @@ export declare const Internals: {
|
|
|
816
816
|
readonly SetMediaVolumeContext: import("react").Context<SetMediaVolumeContextValue>;
|
|
817
817
|
readonly getRemotionEnvironment: () => RemotionEnvironment;
|
|
818
818
|
readonly SharedAudioContext: import("react").Context<{
|
|
819
|
+
sampleRate: number;
|
|
819
820
|
audioContext: AudioContext | null;
|
|
820
821
|
getAudioContextState: () => RemotionAudioContextState | null;
|
|
821
822
|
gainNode: GainNode | null;
|
package/dist/cjs/version.d.ts
CHANGED
package/dist/cjs/version.js
CHANGED
package/dist/esm/index.mjs
CHANGED
|
@@ -1537,7 +1537,7 @@ var Composition = (props) => {
|
|
|
1537
1537
|
};
|
|
1538
1538
|
|
|
1539
1539
|
// src/version.ts
|
|
1540
|
-
var VERSION = "4.0.
|
|
1540
|
+
var VERSION = "4.0.524";
|
|
1541
1541
|
|
|
1542
1542
|
// src/multiple-versions-warning.ts
|
|
1543
1543
|
var checkMultipleRemotionVersions = () => {
|
|
@@ -7812,12 +7812,6 @@ var SharedAudioContextProvider = ({
|
|
|
7812
7812
|
}) => {
|
|
7813
7813
|
const logLevel = useLogLevel();
|
|
7814
7814
|
const sampleRate = previewSampleRate ?? 48000;
|
|
7815
|
-
useEffect8(() => {
|
|
7816
|
-
if (typeof window === "undefined") {
|
|
7817
|
-
return;
|
|
7818
|
-
}
|
|
7819
|
-
window.remotion_sampleRate = sampleRate;
|
|
7820
|
-
}, [sampleRate]);
|
|
7821
7815
|
const ctxAndGain = useSingletonAudioContext({
|
|
7822
7816
|
logLevel,
|
|
7823
7817
|
latencyHint: audioLatencyHint,
|
|
@@ -8001,6 +7995,7 @@ var SharedAudioContextProvider = ({
|
|
|
8001
7995
|
}, [ctxAndGain, _experimentalKeepAudioContextAlive]);
|
|
8002
7996
|
const audioContextValue = useMemo21(() => {
|
|
8003
7997
|
return {
|
|
7998
|
+
sampleRate,
|
|
8004
7999
|
audioContext: ctxAndGain?.audioContext ?? null,
|
|
8005
8000
|
getAudioContextState: () => ctxAndGain?.getState() ?? null,
|
|
8006
8001
|
gainNode: ctxAndGain?.gainNode ?? null,
|
|
@@ -8015,6 +8010,7 @@ var SharedAudioContextProvider = ({
|
|
|
8015
8010
|
_experimentalKeepAudioContextAlive
|
|
8016
8011
|
};
|
|
8017
8012
|
}, [
|
|
8013
|
+
sampleRate,
|
|
8018
8014
|
ctxAndGain,
|
|
8019
8015
|
audioSyncAnchor,
|
|
8020
8016
|
audioSyncAnchorEmitter,
|
package/dist/esm/version.mjs
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/core"
|
|
4
4
|
},
|
|
5
5
|
"name": "remotion",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.524",
|
|
7
7
|
"description": "Make videos programmatically",
|
|
8
8
|
"main": "dist/cjs/index.js",
|
|
9
9
|
"types": "dist/cjs/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react-dom": "19.2.3",
|
|
36
36
|
"webpack": "5.105.0",
|
|
37
37
|
"zod": "4.5.4",
|
|
38
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
38
|
+
"@remotion/eslint-config-internal": "4.0.524",
|
|
39
39
|
"eslint": "9.19.0",
|
|
40
40
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
41
41
|
},
|