@remotion/media 4.0.356 → 4.0.357

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.
Files changed (55) hide show
  1. package/dist/audio/audio-for-preview.d.ts +30 -0
  2. package/dist/audio/audio-for-preview.js +213 -0
  3. package/dist/audio/audio-for-rendering.js +32 -15
  4. package/dist/audio/audio.js +7 -49
  5. package/dist/audio/props.d.ts +8 -14
  6. package/dist/audio-extraction/audio-cache.d.ts +1 -1
  7. package/dist/audio-extraction/audio-cache.js +5 -1
  8. package/dist/audio-extraction/audio-iterator.d.ts +4 -1
  9. package/dist/audio-extraction/audio-iterator.js +22 -10
  10. package/dist/audio-extraction/audio-manager.d.ts +8 -37
  11. package/dist/audio-extraction/audio-manager.js +35 -8
  12. package/dist/audio-extraction/extract-audio.d.ts +9 -2
  13. package/dist/audio-extraction/extract-audio.js +28 -15
  14. package/dist/caches.d.ts +9 -44
  15. package/dist/convert-audiodata/apply-tonefrequency.js +0 -1
  16. package/dist/convert-audiodata/combine-audiodata.js +2 -23
  17. package/dist/convert-audiodata/convert-audiodata.d.ts +1 -5
  18. package/dist/convert-audiodata/convert-audiodata.js +16 -24
  19. package/dist/convert-audiodata/wsola.js +1 -1
  20. package/dist/esm/index.mjs +2681 -2162
  21. package/dist/extract-frame-and-audio.d.ts +6 -7
  22. package/dist/extract-frame-and-audio.js +28 -19
  23. package/dist/get-sink-weak.d.ts +1 -1
  24. package/dist/get-sink-weak.js +3 -11
  25. package/dist/get-sink.d.ts +13 -0
  26. package/dist/get-sink.js +15 -0
  27. package/dist/get-time-in-seconds.d.ts +10 -0
  28. package/dist/get-time-in-seconds.js +25 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.js +1 -0
  31. package/dist/is-network-error.d.ts +6 -0
  32. package/dist/is-network-error.js +17 -0
  33. package/dist/render-timestamp-range.d.ts +1 -0
  34. package/dist/render-timestamp-range.js +9 -0
  35. package/dist/video/media-player.d.ts +28 -7
  36. package/dist/video/media-player.js +123 -58
  37. package/dist/video/props.d.ts +1 -0
  38. package/dist/video/resolve-playback-time.d.ts +8 -0
  39. package/dist/video/resolve-playback-time.js +22 -0
  40. package/dist/video/video-for-preview.d.ts +8 -0
  41. package/dist/video/video-for-preview.js +113 -90
  42. package/dist/video/video-for-rendering.d.ts +3 -0
  43. package/dist/video/video-for-rendering.js +58 -25
  44. package/dist/video/video.js +6 -10
  45. package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +18 -6
  46. package/dist/video-extraction/extract-frame-via-broadcast-channel.js +21 -7
  47. package/dist/video-extraction/extract-frame.d.ts +20 -2
  48. package/dist/video-extraction/extract-frame.js +40 -9
  49. package/dist/video-extraction/get-frames-since-keyframe.d.ts +5 -3
  50. package/dist/video-extraction/get-frames-since-keyframe.js +7 -4
  51. package/dist/video-extraction/keyframe-bank.d.ts +3 -2
  52. package/dist/video-extraction/keyframe-bank.js +32 -12
  53. package/dist/video-extraction/keyframe-manager.d.ts +3 -8
  54. package/dist/video-extraction/keyframe-manager.js +25 -10
  55. package/package.json +4 -4
@@ -1,8 +1,26 @@
1
1
  import type { VideoSample } from 'mediabunny';
2
2
  import { type LogLevel } from 'remotion';
3
- export declare const extractFrame: ({ src, timeInSeconds: unloopedTimeinSeconds, logLevel, loop, }: {
3
+ type ExtractFrameResult = {
4
+ type: 'success';
5
+ frame: VideoSample | null;
6
+ durationInSeconds: number | null;
7
+ } | {
8
+ type: 'cannot-decode';
9
+ durationInSeconds: number | null;
10
+ } | {
11
+ type: 'unknown-container-format';
12
+ };
13
+ type ExtractFrameParams = {
4
14
  src: string;
5
15
  timeInSeconds: number;
6
16
  logLevel: LogLevel;
7
17
  loop: boolean;
8
- }) => Promise<VideoSample | "cannot-decode" | "unknown-container-format" | null>;
18
+ trimAfter: number | undefined;
19
+ trimBefore: number | undefined;
20
+ playbackRate: number;
21
+ fps: number;
22
+ };
23
+ declare const extractFrameInternal: ({ src, timeInSeconds: unloopedTimeInSeconds, logLevel, loop, trimAfter, trimBefore, playbackRate, fps, }: ExtractFrameParams) => Promise<ExtractFrameResult>;
24
+ type ExtractFrameReturnType = Awaited<ReturnType<typeof extractFrameInternal>>;
25
+ export declare const extractFrame: (params: ExtractFrameParams) => Promise<ExtractFrameReturnType>;
26
+ export {};
@@ -1,20 +1,39 @@
1
1
  import { keyframeManager } from '../caches';
2
- import { getSinkWeak } from '../get-sink-weak';
3
- export const extractFrame = async ({ src, timeInSeconds: unloopedTimeinSeconds, logLevel, loop, }) => {
4
- const sink = await getSinkWeak(src, logLevel);
2
+ import { getSink } from '../get-sink';
3
+ import { getTimeInSeconds } from '../get-time-in-seconds';
4
+ const extractFrameInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds, logLevel, loop, trimAfter, trimBefore, playbackRate, fps, }) => {
5
+ const sink = await getSink(src, logLevel);
5
6
  const video = await sink.getVideo();
6
7
  if (video === 'no-video-track') {
7
8
  throw new Error(`No video track found for ${src}`);
8
9
  }
9
10
  if (video === 'cannot-decode') {
10
- return 'cannot-decode';
11
+ return { type: 'cannot-decode', durationInSeconds: await sink.getDuration() };
11
12
  }
12
13
  if (video === 'unknown-container-format') {
13
- return 'unknown-container-format';
14
+ return { type: 'unknown-container-format' };
15
+ }
16
+ let mediaDurationInSeconds = null;
17
+ if (loop) {
18
+ mediaDurationInSeconds = await sink.getDuration();
19
+ }
20
+ const timeInSeconds = getTimeInSeconds({
21
+ loop,
22
+ mediaDurationInSeconds,
23
+ unloopedTimeInSeconds,
24
+ src,
25
+ trimAfter,
26
+ playbackRate,
27
+ trimBefore,
28
+ fps,
29
+ });
30
+ if (timeInSeconds === null) {
31
+ return {
32
+ type: 'success',
33
+ frame: null,
34
+ durationInSeconds: await sink.getDuration(),
35
+ };
14
36
  }
15
- const timeInSeconds = loop
16
- ? unloopedTimeinSeconds % (await sink.getDuration())
17
- : unloopedTimeinSeconds;
18
37
  const keyframeBank = await keyframeManager.requestKeyframeBank({
19
38
  packetSink: video.packetSink,
20
39
  videoSampleSink: video.sampleSink,
@@ -22,6 +41,18 @@ export const extractFrame = async ({ src, timeInSeconds: unloopedTimeinSeconds,
22
41
  src,
23
42
  logLevel,
24
43
  });
44
+ if (!keyframeBank) {
45
+ return {
46
+ type: 'success',
47
+ frame: null,
48
+ durationInSeconds: await sink.getDuration(),
49
+ };
50
+ }
25
51
  const frame = await keyframeBank.getFrameFromTimestamp(timeInSeconds);
26
- return frame;
52
+ return { type: 'success', frame, durationInSeconds: await sink.getDuration() };
53
+ };
54
+ let queue = Promise.resolve(undefined);
55
+ export const extractFrame = (params) => {
56
+ queue = queue.then(() => extractFrameInternal(params));
57
+ return queue;
27
58
  };
@@ -1,5 +1,6 @@
1
1
  import type { EncodedPacket } from 'mediabunny';
2
2
  import { AudioSampleSink, EncodedPacketSink, VideoSampleSink } from 'mediabunny';
3
+ import type { LogLevel } from 'remotion';
3
4
  type VideoSinks = {
4
5
  sampleSink: VideoSampleSink;
5
6
  packetSink: EncodedPacketSink;
@@ -9,7 +10,7 @@ type AudioSinks = {
9
10
  };
10
11
  export type AudioSinkResult = AudioSinks | 'no-audio-track' | 'cannot-decode-audio' | 'unknown-container-format';
11
12
  export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'unknown-container-format';
12
- export declare const getSinks: (src: string) => Promise<WeakRef<{
13
+ export declare const getSinks: (src: string) => Promise<{
13
14
  getVideo: () => Promise<VideoSinkResult>;
14
15
  getAudio: (index: number) => Promise<AudioSinkResult>;
15
16
  actualMatroskaTimestamps: {
@@ -18,11 +19,12 @@ export declare const getSinks: (src: string) => Promise<WeakRef<{
18
19
  };
19
20
  isMatroska: boolean;
20
21
  getDuration: () => Promise<number>;
21
- }>>;
22
+ }>;
22
23
  export type GetSink = Awaited<ReturnType<typeof getSinks>>;
23
- export declare const getFramesSinceKeyframe: ({ packetSink, videoSampleSink, startPacket, }: {
24
+ export declare const getFramesSinceKeyframe: ({ packetSink, videoSampleSink, startPacket, logLevel, }: {
24
25
  packetSink: EncodedPacketSink;
25
26
  videoSampleSink: VideoSampleSink;
26
27
  startPacket: EncodedPacket;
28
+ logLevel: LogLevel;
27
29
  }) => Promise<import("./keyframe-bank").KeyframeBank>;
28
30
  export {};
@@ -72,15 +72,17 @@ export const getSinks = async (src) => {
72
72
  audioSinksPromise[index] = getAudioSinks(index);
73
73
  return audioSinksPromise[index];
74
74
  };
75
- return new WeakRef({
75
+ return {
76
76
  getVideo: () => getVideoSinksPromise(),
77
77
  getAudio: (index) => getAudioSinksPromise(index),
78
78
  actualMatroskaTimestamps: rememberActualMatroskaTimestamps(isMatroska),
79
79
  isMatroska,
80
- getDuration: () => input.computeDuration(),
81
- });
80
+ getDuration: () => {
81
+ return input.computeDuration();
82
+ },
83
+ };
82
84
  };
83
- export const getFramesSinceKeyframe = async ({ packetSink, videoSampleSink, startPacket, }) => {
85
+ export const getFramesSinceKeyframe = async ({ packetSink, videoSampleSink, startPacket, logLevel, }) => {
84
86
  const nextKeyPacket = await packetSink.getNextKeyPacket(startPacket, {
85
87
  verifyKeyPackets: true,
86
88
  });
@@ -89,6 +91,7 @@ export const getFramesSinceKeyframe = async ({ packetSink, videoSampleSink, star
89
91
  startTimestampInSeconds: startPacket.timestamp,
90
92
  endTimestampInSeconds: nextKeyPacket ? nextKeyPacket.timestamp : Infinity,
91
93
  sampleIterator,
94
+ logLevel,
92
95
  });
93
96
  return keyframeBank;
94
97
  };
@@ -4,7 +4,7 @@ export type KeyframeBank = {
4
4
  startTimestampInSeconds: number;
5
5
  endTimestampInSeconds: number;
6
6
  getFrameFromTimestamp: (timestamp: number) => Promise<VideoSample | null>;
7
- prepareForDeletion: () => Promise<void>;
7
+ prepareForDeletion: (logLevel: LogLevel) => void;
8
8
  deleteFramesBeforeTimestamp: ({ logLevel, src, timestampInSeconds, }: {
9
9
  timestampInSeconds: number;
10
10
  logLevel: LogLevel;
@@ -18,8 +18,9 @@ export type KeyframeBank = {
18
18
  };
19
19
  getLastUsed: () => number;
20
20
  };
21
- export declare const makeKeyframeBank: ({ startTimestampInSeconds, endTimestampInSeconds, sampleIterator, }: {
21
+ export declare const makeKeyframeBank: ({ startTimestampInSeconds, endTimestampInSeconds, sampleIterator, logLevel: parentLogLevel, }: {
22
22
  startTimestampInSeconds: number;
23
23
  endTimestampInSeconds: number;
24
24
  sampleIterator: AsyncGenerator<VideoSample, void, unknown>;
25
+ logLevel: LogLevel;
25
26
  }) => KeyframeBank;
@@ -1,9 +1,11 @@
1
1
  import { Internals } from 'remotion';
2
+ import { renderTimestampRange } from '../render-timestamp-range';
2
3
  // Round to only 4 digits, because WebM has a timescale of 1_000, e.g. framer.webm
3
4
  const roundTo4Digits = (timestamp) => {
4
5
  return Math.round(timestamp * 1000) / 1000;
5
6
  };
6
- export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSeconds, sampleIterator, }) => {
7
+ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSeconds, sampleIterator, logLevel: parentLogLevel, }) => {
8
+ Internals.Log.verbose({ logLevel: parentLogLevel, tag: '@remotion/media' }, `Creating keyframe bank from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
7
9
  const frames = {};
8
10
  const frameTimestamps = [];
9
11
  let lastUsed = Date.now();
@@ -19,7 +21,7 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
19
21
  return true;
20
22
  }
21
23
  return (roundTo4Digits(lastFrame.timestamp + lastFrame.duration) >
22
- roundTo4Digits(timestamp));
24
+ roundTo4Digits(timestamp) + 0.001);
23
25
  };
24
26
  const addFrame = (frame) => {
25
27
  frames[frame.timestamp] = frame;
@@ -53,7 +55,11 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
53
55
  if (!sample) {
54
56
  return null;
55
57
  }
56
- if (roundTo4Digits(sample.timestamp) <= roundTo4Digits(timestampInSeconds)) {
58
+ if (roundTo4Digits(sample.timestamp) <=
59
+ roundTo4Digits(timestampInSeconds) ||
60
+ // Match 0.3333333333 to 0.33355555
61
+ // this does not satisfy the previous condition, since one rounds up and one rounds down
62
+ Math.abs(sample.timestamp - timestampInSeconds) <= 0.001) {
57
63
  return sample;
58
64
  }
59
65
  }
@@ -62,12 +68,15 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
62
68
  const hasTimestampInSecond = async (timestamp) => {
63
69
  return (await getFrameFromTimestamp(timestamp)) !== null;
64
70
  };
65
- const prepareForDeletion = async () => {
71
+ const prepareForDeletion = (logLevel) => {
72
+ Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Preparing for deletion of keyframe bank from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
66
73
  // Cleanup frames that have been extracted that might not have been retrieved yet
67
- const { value } = await sampleIterator.return();
68
- if (value) {
69
- value.close();
70
- }
74
+ sampleIterator.return().then((result) => {
75
+ if (result.value) {
76
+ result.value.close();
77
+ }
78
+ return null;
79
+ });
71
80
  for (const frameTimestamp of frameTimestamps) {
72
81
  if (!frames[frameTimestamp]) {
73
82
  continue;
@@ -79,7 +88,8 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
79
88
  frameTimestamps.length = 0;
80
89
  };
81
90
  const deleteFramesBeforeTimestamp = ({ logLevel, src, timestampInSeconds, }) => {
82
- for (const frameTimestamp of frameTimestamps) {
91
+ const deletedTimestamps = [];
92
+ for (const frameTimestamp of frameTimestamps.slice()) {
83
93
  const isLast = frameTimestamp === frameTimestamps[frameTimestamps.length - 1];
84
94
  // Don't delete the last frame, since it may be the last one in the video!
85
95
  if (isLast) {
@@ -93,9 +103,12 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
93
103
  frameTimestamps.splice(frameTimestamps.indexOf(frameTimestamp), 1);
94
104
  frames[frameTimestamp].close();
95
105
  delete frames[frameTimestamp];
96
- Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Deleted frame ${frameTimestamp} for src ${src}`);
106
+ deletedTimestamps.push(frameTimestamp);
97
107
  }
98
108
  }
109
+ if (deletedTimestamps.length > 0) {
110
+ Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Deleted ${deletedTimestamps.length} frame${deletedTimestamps.length === 1 ? '' : 's'} ${renderTimestampRange(deletedTimestamps)} for src ${src} because it is lower than ${timestampInSeconds}. Remaining: ${renderTimestampRange(frameTimestamps)}`);
111
+ }
99
112
  };
100
113
  const getOpenFrameCount = () => {
101
114
  return {
@@ -106,11 +119,18 @@ export const makeKeyframeBank = ({ startTimestampInSeconds, endTimestampInSecond
106
119
  const getLastUsed = () => {
107
120
  return lastUsed;
108
121
  };
122
+ let queue = Promise.resolve(undefined);
109
123
  const keyframeBank = {
110
124
  startTimestampInSeconds,
111
125
  endTimestampInSeconds,
112
- getFrameFromTimestamp,
113
- prepareForDeletion,
126
+ getFrameFromTimestamp: (timestamp) => {
127
+ queue = queue.then(() => getFrameFromTimestamp(timestamp));
128
+ return queue;
129
+ },
130
+ prepareForDeletion: (logLevel) => {
131
+ queue = queue.then(() => prepareForDeletion(logLevel));
132
+ return queue;
133
+ },
114
134
  hasTimestampInSecond,
115
135
  addFrame,
116
136
  deleteFramesBeforeTimestamp,
@@ -3,21 +3,16 @@ import { type LogLevel } from 'remotion';
3
3
  import { type KeyframeBank } from './keyframe-bank';
4
4
  export declare const makeKeyframeManager: () => {
5
5
  requestKeyframeBank: ({ packetSink, timestamp, videoSampleSink, src, logLevel, }: {
6
- timestamp: number;
7
6
  packetSink: EncodedPacketSink;
7
+ timestamp: number;
8
8
  videoSampleSink: VideoSampleSink;
9
9
  src: string;
10
10
  logLevel: LogLevel;
11
- }) => Promise<KeyframeBank>;
12
- addKeyframeBank: ({ src, bank, startTimestampInSeconds, }: {
13
- src: string;
14
- bank: Promise<KeyframeBank>;
15
- startTimestampInSeconds: number;
16
- }) => void;
11
+ }) => Promise<KeyframeBank | null>;
17
12
  getCacheStats: () => Promise<{
18
13
  count: number;
19
14
  totalSize: number;
20
15
  }>;
21
- clearAll: () => Promise<void>;
16
+ clearAll: (logLevel: LogLevel) => Promise<void>;
22
17
  };
23
18
  export type KeyframeManager = Awaited<ReturnType<typeof makeKeyframeManager>>;
@@ -1,5 +1,6 @@
1
1
  import { Internals } from 'remotion';
2
2
  import { getMaxVideoCacheSize, getTotalCacheStats, SAFE_BACK_WINDOW_IN_SECONDS, } from '../caches';
3
+ import { renderTimestampRange } from '../render-timestamp-range';
3
4
  import { getFramesSinceKeyframe } from './get-frames-since-keyframe';
4
5
  export const makeKeyframeManager = () => {
5
6
  // src => {[startTimestampInSeconds]: KeyframeBank
@@ -20,7 +21,7 @@ export const makeKeyframeManager = () => {
20
21
  if (size === 0) {
21
22
  continue;
22
23
  }
23
- Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Open frames for src ${src}: ${timestamps.join(', ')}`);
24
+ Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Open frames for src ${src}: ${renderTimestampRange(timestamps)}`);
24
25
  }
25
26
  }
26
27
  Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Video cache stats: ${count} open frames, ${totalSize} bytes`);
@@ -62,7 +63,7 @@ export const makeKeyframeManager = () => {
62
63
  const deleteOldestKeyframeBank = async (logLevel) => {
63
64
  const { bank: mostInThePastBank, src: mostInThePastSrc } = await getTheKeyframeBankMostInThePast();
64
65
  if (mostInThePastBank) {
65
- await mostInThePastBank.prepareForDeletion();
66
+ await mostInThePastBank.prepareForDeletion(logLevel);
66
67
  delete sources[mostInThePastSrc][mostInThePastBank.startTimestampInSeconds];
67
68
  Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Deleted frames for src ${mostInThePastSrc} from ${mostInThePastBank.startTimestampInSeconds}sec to ${mostInThePastBank.endTimestampInSeconds}sec to free up memory.`);
68
69
  }
@@ -85,7 +86,7 @@ export const makeKeyframeManager = () => {
85
86
  const bank = await sources[src][startTimeInSeconds];
86
87
  const { endTimestampInSeconds, startTimestampInSeconds } = bank;
87
88
  if (endTimestampInSeconds < threshold) {
88
- await bank.prepareForDeletion();
89
+ await bank.prepareForDeletion(logLevel);
89
90
  Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `[Video] Cleared frames for src ${src} from ${startTimestampInSeconds}sec to ${endTimestampInSeconds}sec`);
90
91
  delete sources[src][startTimeInSeconds];
91
92
  }
@@ -104,7 +105,10 @@ export const makeKeyframeManager = () => {
104
105
  verifyKeyPackets: true,
105
106
  });
106
107
  if (!startPacket) {
107
- throw new Error(`No key packet found for timestamp ${timestamp}`);
108
+ // e.g. https://discord.com/channels/809501355504959528/809501355504959531/1424400511070765086
109
+ // The video has an offset and the first frame is at time 0.033sec
110
+ // we shall not crash here but handle it gracefully
111
+ return null;
108
112
  }
109
113
  const startTimestampInSeconds = startPacket.timestamp;
110
114
  const existingBank = sources[src]?.[startTimestampInSeconds];
@@ -114,6 +118,7 @@ export const makeKeyframeManager = () => {
114
118
  packetSink,
115
119
  videoSampleSink,
116
120
  startPacket,
121
+ logLevel,
117
122
  });
118
123
  addKeyframeBank({ src, bank: newKeyframeBank, startTimestampInSeconds });
119
124
  return newKeyframeBank;
@@ -122,16 +127,17 @@ export const makeKeyframeManager = () => {
122
127
  if (await (await existingBank).hasTimestampInSecond(timestamp)) {
123
128
  return existingBank;
124
129
  }
125
- Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Keyframe bank exists but frames have already been evicted!`);
130
+ Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Keyframe bank exists but frame at time ${timestamp} does not exist anymore.`);
126
131
  // Bank exists but frames have already been evicted!
127
132
  // First delete it entirely
128
- await (await existingBank).prepareForDeletion();
133
+ await (await existingBank).prepareForDeletion(logLevel);
129
134
  delete sources[src][startTimestampInSeconds];
130
135
  // Then refetch
131
136
  const replacementKeybank = getFramesSinceKeyframe({
132
137
  packetSink,
133
138
  videoSampleSink,
134
139
  startPacket,
140
+ logLevel,
135
141
  });
136
142
  addKeyframeBank({ src, bank: replacementKeybank, startTimestampInSeconds });
137
143
  return replacementKeybank;
@@ -152,20 +158,29 @@ export const makeKeyframeManager = () => {
152
158
  });
153
159
  return keyframeBank;
154
160
  };
155
- const clearAll = async () => {
161
+ const clearAll = async (logLevel) => {
156
162
  const srcs = Object.keys(sources);
157
163
  for (const src of srcs) {
158
164
  const banks = Object.keys(sources[src]);
159
165
  for (const startTimeInSeconds of banks) {
160
166
  const bank = await sources[src][startTimeInSeconds];
161
- await bank.prepareForDeletion();
167
+ bank.prepareForDeletion(logLevel);
162
168
  delete sources[src][startTimeInSeconds];
163
169
  }
164
170
  }
165
171
  };
172
+ let queue = Promise.resolve(undefined);
166
173
  return {
167
- requestKeyframeBank,
168
- addKeyframeBank,
174
+ requestKeyframeBank: ({ packetSink, timestamp, videoSampleSink, src, logLevel, }) => {
175
+ queue = queue.then(() => requestKeyframeBank({
176
+ packetSink,
177
+ timestamp,
178
+ videoSampleSink,
179
+ src,
180
+ logLevel,
181
+ }));
182
+ return queue;
183
+ },
169
184
  getCacheStats,
170
185
  clearAll,
171
186
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.356",
3
+ "version": "4.0.357",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/esm/index.mjs",
@@ -13,9 +13,9 @@
13
13
  "url": "https://github.com/remotion-dev/remotion/issues"
14
14
  },
15
15
  "dependencies": {
16
- "mediabunny": "1.21.0",
16
+ "mediabunny": "1.23.0",
17
17
  "webdriverio": "9.19.2",
18
- "remotion": "4.0.356"
18
+ "remotion": "4.0.357"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",
@@ -27,7 +27,7 @@
27
27
  "react": "19.0.0",
28
28
  "react-dom": "19.0.0",
29
29
  "vitest": "3.2.4",
30
- "@remotion/eslint-config-internal": "4.0.356"
30
+ "@remotion/eslint-config-internal": "4.0.357"
31
31
  },
32
32
  "keywords": [],
33
33
  "publishConfig": {