@remotion/media 4.0.351 → 4.0.353
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/audio/props.d.ts +1 -2
- package/dist/audio-extraction/audio-cache.js +4 -0
- package/dist/audio-extraction/audio-iterator.d.ts +1 -1
- package/dist/audio-extraction/audio-iterator.js +7 -4
- package/dist/audio-extraction/audio-manager.d.ts +3 -2
- package/dist/audio-extraction/audio-manager.js +4 -3
- package/dist/audio-extraction/extract-audio.d.ts +1 -1
- package/dist/audio-extraction/extract-audio.js +1 -0
- package/dist/caches.d.ts +9 -7
- package/dist/caches.js +37 -1
- package/dist/convert-audiodata/resample-audiodata.js +3 -2
- package/dist/esm/index.mjs +114 -88
- package/dist/video/props.d.ts +1 -0
- package/dist/video/video-for-rendering.js +23 -9
- package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +1 -1
- package/dist/video-extraction/extract-frame.d.ts +1 -1
- package/dist/video-extraction/get-frames-since-keyframe.js +1 -1
- package/dist/video-extraction/keyframe-bank.d.ts +1 -1
- package/dist/video-extraction/keyframe-bank.js +7 -7
- package/dist/video-extraction/keyframe-manager.d.ts +1 -1
- package/dist/video-extraction/keyframe-manager.js +9 -8
- package/package.json +3 -3
- package/dist/audio-for-rendering.d.ts +0 -3
- package/dist/audio-for-rendering.js +0 -94
- package/dist/audio.d.ts +0 -3
- package/dist/audio.js +0 -60
- package/dist/audiodata-to-array.d.ts +0 -0
- package/dist/audiodata-to-array.js +0 -1
- package/dist/convert-audiodata/data-types.d.ts +0 -1
- package/dist/convert-audiodata/data-types.js +0 -22
- package/dist/convert-audiodata/is-planar-format.d.ts +0 -1
- package/dist/convert-audiodata/is-planar-format.js +0 -3
- package/dist/convert-audiodata/log-audiodata.d.ts +0 -1
- package/dist/convert-audiodata/log-audiodata.js +0 -8
- package/dist/convert-audiodata/trim-audiodata.d.ts +0 -0
- package/dist/convert-audiodata/trim-audiodata.js +0 -1
- package/dist/deserialized-audiodata.d.ts +0 -15
- package/dist/deserialized-audiodata.js +0 -26
- package/dist/extract-audio.d.ts +0 -7
- package/dist/extract-audio.js +0 -98
- package/dist/extract-frame-via-broadcast-channel.d.ts +0 -15
- package/dist/extract-frame-via-broadcast-channel.js +0 -104
- package/dist/extract-frame.d.ts +0 -27
- package/dist/extract-frame.js +0 -21
- package/dist/extrct-audio.d.ts +0 -7
- package/dist/extrct-audio.js +0 -94
- package/dist/get-frames-since-keyframe.d.ts +0 -22
- package/dist/get-frames-since-keyframe.js +0 -41
- package/dist/keyframe-bank.d.ts +0 -25
- package/dist/keyframe-bank.js +0 -120
- package/dist/keyframe-manager.d.ts +0 -23
- package/dist/keyframe-manager.js +0 -170
- package/dist/new-video-for-rendering.d.ts +0 -3
- package/dist/new-video-for-rendering.js +0 -108
- package/dist/new-video.d.ts +0 -3
- package/dist/new-video.js +0 -37
- package/dist/props.d.ts +0 -29
- package/dist/props.js +0 -1
- package/dist/remember-actual-matroska-timestamps.d.ts +0 -4
- package/dist/remember-actual-matroska-timestamps.js +0 -19
- package/dist/serialize-videoframe.d.ts +0 -0
- package/dist/serialize-videoframe.js +0 -1
- package/dist/video-for-rendering.d.ts +0 -3
- package/dist/video-for-rendering.js +0 -108
- package/dist/video.d.ts +0 -3
- package/dist/video.js +0 -37
package/dist/audio/props.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ export const makeAudioCache = () => {
|
|
|
9
9
|
for (const timestamp of timestamps) {
|
|
10
10
|
const endTimestamp = timestamp + samples[timestamp].duration;
|
|
11
11
|
if (endTimestamp < threshold) {
|
|
12
|
+
const isLast = timestamp === timestamps[timestamps.length - 1];
|
|
13
|
+
if (isLast) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
12
16
|
samples[timestamp].close();
|
|
13
17
|
delete samples[timestamp];
|
|
14
18
|
timestamps.splice(timestamps.indexOf(timestamp), 1);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AudioSample, AudioSampleSink } from 'mediabunny';
|
|
2
|
-
import type
|
|
2
|
+
import { type LogLevel } from 'remotion';
|
|
3
3
|
import type { RememberActualMatroskaTimestamps } from '../video-extraction/remember-actual-matroska-timestamps';
|
|
4
4
|
export declare const makeAudioIterator: ({ audioSampleSink, isMatroska, startTimestamp, src, actualMatroskaTimestamps, }: {
|
|
5
5
|
audioSampleSink: AudioSampleSink;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Internals } from 'remotion';
|
|
1
2
|
import { SAFE_BACK_WINDOW_IN_SECONDS } from '../caches';
|
|
2
|
-
import { Log } from '../log';
|
|
3
3
|
import { makeAudioCache } from './audio-cache';
|
|
4
4
|
// https://discord.com/channels/@me/1409810025844838481/1415028953093111870
|
|
5
5
|
// Audio frames might have dependencies on previous and next frames so we need to decode a bit more
|
|
@@ -41,10 +41,13 @@ export const makeAudioIterator = ({ audioSampleSink, isMatroska, startTimestamp,
|
|
|
41
41
|
}
|
|
42
42
|
const samples = cache.getSamples(timestamp, durationInSeconds);
|
|
43
43
|
while (true) {
|
|
44
|
+
const sample = await getNextSample();
|
|
44
45
|
// Clear all samples before the timestamp
|
|
45
46
|
// Do this in the while loop because samples might start from 0
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
// Also do this after a sample has just been added, if it was the last sample we now have the duration
|
|
48
|
+
// and can prevent deleting the last sample
|
|
49
|
+
const deleteBefore = fullDuration === null ? timestamp : Math.min(timestamp, fullDuration);
|
|
50
|
+
cache.clearBeforeThreshold(deleteBefore - SAFE_BACK_WINDOW_IN_SECONDS);
|
|
48
51
|
if (sample === null) {
|
|
49
52
|
break;
|
|
50
53
|
}
|
|
@@ -59,7 +62,7 @@ export const makeAudioIterator = ({ audioSampleSink, isMatroska, startTimestamp,
|
|
|
59
62
|
return samples;
|
|
60
63
|
};
|
|
61
64
|
const logOpenFrames = (logLevel) => {
|
|
62
|
-
Log.verbose(logLevel, '
|
|
65
|
+
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, 'Open audio samples for src', src, cache
|
|
63
66
|
.getOpenTimestamps()
|
|
64
67
|
.map((t) => t.toFixed(3))
|
|
65
68
|
.join(', '));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AudioSampleSink } from 'mediabunny';
|
|
2
|
-
import type { LogLevel } from '
|
|
2
|
+
import type { LogLevel } from 'remotion';
|
|
3
3
|
import type { RememberActualMatroskaTimestamps } from '../video-extraction/remember-actual-matroska-timestamps';
|
|
4
4
|
export declare const makeAudioManager: () => {
|
|
5
5
|
makeIterator: ({ timeInSeconds, src, audioSampleSink, isMatroska, actualMatroskaTimestamps, }: {
|
|
@@ -22,12 +22,13 @@ export declare const makeAudioManager: () => {
|
|
|
22
22
|
prepareForDeletion: () => Promise<void>;
|
|
23
23
|
startTimestamp: number;
|
|
24
24
|
};
|
|
25
|
-
getIterator: ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, }: {
|
|
25
|
+
getIterator: ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, logLevel, }: {
|
|
26
26
|
src: string;
|
|
27
27
|
timeInSeconds: number;
|
|
28
28
|
audioSampleSink: AudioSampleSink;
|
|
29
29
|
isMatroska: boolean;
|
|
30
30
|
actualMatroskaTimestamps: RememberActualMatroskaTimestamps;
|
|
31
|
+
logLevel: LogLevel;
|
|
31
32
|
}) => Promise<{
|
|
32
33
|
src: string;
|
|
33
34
|
getSamples: (ts: number, dur: number) => Promise<import("mediabunny").AudioSample[]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getMaxVideoCacheSize, getTotalCacheStats } from '../caches';
|
|
2
2
|
import { makeAudioIterator } from './audio-iterator';
|
|
3
3
|
export const makeAudioManager = () => {
|
|
4
4
|
const iterators = [];
|
|
@@ -32,8 +32,9 @@ export const makeAudioManager = () => {
|
|
|
32
32
|
iterators.splice(iterators.indexOf(iterator), 1);
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
-
const getIterator = async ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, }) => {
|
|
36
|
-
|
|
35
|
+
const getIterator = async ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, logLevel, }) => {
|
|
36
|
+
const maxCacheSize = getMaxVideoCacheSize(logLevel);
|
|
37
|
+
while ((await getTotalCacheStats()).totalSize > maxCacheSize) {
|
|
37
38
|
await deleteOldestIterator();
|
|
38
39
|
}
|
|
39
40
|
for (const iterator of iterators) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { type LogLevel } from 'remotion';
|
|
1
2
|
import type { PcmS16AudioData } from '../convert-audiodata/convert-audiodata';
|
|
2
|
-
import type { LogLevel } from '../log';
|
|
3
3
|
export declare const extractAudio: ({ src, timeInSeconds: unloopedTimeInSeconds, durationInSeconds, volume, logLevel, loop, }: {
|
|
4
4
|
src: string;
|
|
5
5
|
timeInSeconds: number;
|
|
@@ -21,6 +21,7 @@ export const extractAudio = async ({ src, timeInSeconds: unloopedTimeInSeconds,
|
|
|
21
21
|
audioSampleSink: audio.sampleSink,
|
|
22
22
|
isMatroska,
|
|
23
23
|
actualMatroskaTimestamps,
|
|
24
|
+
logLevel,
|
|
24
25
|
});
|
|
25
26
|
const samples = await sampleIterator.getSamples(timeInSeconds, durationInSeconds);
|
|
26
27
|
audioManager.logOpenFrames(logLevel);
|
package/dist/caches.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { type LogLevel } from 'remotion';
|
|
2
2
|
export declare const SAFE_BACK_WINDOW_IN_SECONDS = 1;
|
|
3
3
|
export declare const keyframeManager: {
|
|
4
4
|
requestKeyframeBank: ({ packetSink, timestamp, videoSampleSink, src, logLevel, }: {
|
|
@@ -6,7 +6,7 @@ export declare const keyframeManager: {
|
|
|
6
6
|
packetSink: import("mediabunny").EncodedPacketSink;
|
|
7
7
|
videoSampleSink: import("mediabunny").VideoSampleSink;
|
|
8
8
|
src: string;
|
|
9
|
-
logLevel:
|
|
9
|
+
logLevel: LogLevel;
|
|
10
10
|
}) => Promise<import("./video-extraction/keyframe-bank").KeyframeBank>;
|
|
11
11
|
addKeyframeBank: ({ src, bank, startTimestampInSeconds, }: {
|
|
12
12
|
src: string;
|
|
@@ -31,7 +31,7 @@ export declare const audioManager: {
|
|
|
31
31
|
getSamples: (ts: number, dur: number) => Promise<import("mediabunny").AudioSample[]>;
|
|
32
32
|
waitForCompletion: () => Promise<boolean>;
|
|
33
33
|
canSatisfyRequestedTime: (timestamp: number) => boolean;
|
|
34
|
-
logOpenFrames: (logLevel:
|
|
34
|
+
logOpenFrames: (logLevel: LogLevel) => void;
|
|
35
35
|
getCacheStats: () => {
|
|
36
36
|
count: number;
|
|
37
37
|
size: number;
|
|
@@ -40,18 +40,19 @@ export declare const audioManager: {
|
|
|
40
40
|
prepareForDeletion: () => Promise<void>;
|
|
41
41
|
startTimestamp: number;
|
|
42
42
|
};
|
|
43
|
-
getIterator: ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, }: {
|
|
43
|
+
getIterator: ({ src, timeInSeconds, audioSampleSink, isMatroska, actualMatroskaTimestamps, logLevel, }: {
|
|
44
44
|
src: string;
|
|
45
45
|
timeInSeconds: number;
|
|
46
46
|
audioSampleSink: import("mediabunny").AudioSampleSink;
|
|
47
47
|
isMatroska: boolean;
|
|
48
48
|
actualMatroskaTimestamps: import("./video-extraction/remember-actual-matroska-timestamps").RememberActualMatroskaTimestamps;
|
|
49
|
+
logLevel: LogLevel;
|
|
49
50
|
}) => Promise<{
|
|
50
51
|
src: string;
|
|
51
52
|
getSamples: (ts: number, dur: number) => Promise<import("mediabunny").AudioSample[]>;
|
|
52
53
|
waitForCompletion: () => Promise<boolean>;
|
|
53
54
|
canSatisfyRequestedTime: (timestamp: number) => boolean;
|
|
54
|
-
logOpenFrames: (logLevel:
|
|
55
|
+
logOpenFrames: (logLevel: LogLevel) => void;
|
|
55
56
|
getCacheStats: () => {
|
|
56
57
|
count: number;
|
|
57
58
|
size: number;
|
|
@@ -69,7 +70,7 @@ export declare const audioManager: {
|
|
|
69
70
|
getSamples: (ts: number, dur: number) => Promise<import("mediabunny").AudioSample[]>;
|
|
70
71
|
waitForCompletion: () => Promise<boolean>;
|
|
71
72
|
canSatisfyRequestedTime: (timestamp: number) => boolean;
|
|
72
|
-
logOpenFrames: (logLevel:
|
|
73
|
+
logOpenFrames: (logLevel: LogLevel) => void;
|
|
73
74
|
getCacheStats: () => {
|
|
74
75
|
count: number;
|
|
75
76
|
size: number;
|
|
@@ -78,9 +79,10 @@ export declare const audioManager: {
|
|
|
78
79
|
prepareForDeletion: () => Promise<void>;
|
|
79
80
|
startTimestamp: number;
|
|
80
81
|
} | null;
|
|
81
|
-
logOpenFrames: (logLevel:
|
|
82
|
+
logOpenFrames: (logLevel: LogLevel) => void;
|
|
82
83
|
};
|
|
83
84
|
export declare const getTotalCacheStats: () => Promise<{
|
|
84
85
|
count: number;
|
|
85
86
|
totalSize: number;
|
|
86
87
|
}>;
|
|
88
|
+
export declare const getMaxVideoCacheSize: (logLevel: LogLevel) => number;
|
package/dist/caches.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { cancelRender, Internals } from 'remotion';
|
|
1
2
|
import { makeAudioManager } from './audio-extraction/audio-manager';
|
|
2
3
|
import { makeKeyframeManager } from './video-extraction/keyframe-manager';
|
|
3
|
-
export const MAX_CACHE_SIZE = 1000 * 1000 * 1000; // 1GB
|
|
4
4
|
// TODO: make it dependent on the fps and concurrency
|
|
5
5
|
export const SAFE_BACK_WINDOW_IN_SECONDS = 1;
|
|
6
6
|
export const keyframeManager = makeKeyframeManager();
|
|
@@ -13,3 +13,39 @@ export const getTotalCacheStats = async () => {
|
|
|
13
13
|
totalSize: keyframeManagerCacheStats.totalSize + audioManagerCacheStats.totalSize,
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
|
+
const getUncachedMaxCacheSize = (logLevel) => {
|
|
17
|
+
if (window.remotion_mediaCacheSizeInBytes !== undefined &&
|
|
18
|
+
window.remotion_mediaCacheSizeInBytes !== null) {
|
|
19
|
+
if (window.remotion_mediaCacheSizeInBytes < 240 * 1024 * 1024) {
|
|
20
|
+
cancelRender(new Error(`The minimum value for the "mediaCacheSizeInBytes" prop is 240MB (${240 * 1024 * 1024}), got: ${window.remotion_mediaCacheSizeInBytes}`));
|
|
21
|
+
}
|
|
22
|
+
if (window.remotion_mediaCacheSizeInBytes > 20000 * 1024 * 1024) {
|
|
23
|
+
cancelRender(new Error(`The maximum value for the "mediaCacheSizeInBytes" prop is 20GB (${20000 * 1024 * 1024}), got: ${window.remotion_mediaCacheSizeInBytes}`));
|
|
24
|
+
}
|
|
25
|
+
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set using "mediaCacheSizeInBytes": ${(window.remotion_mediaCacheSizeInBytes / 1024 / 1024).toFixed(1)} MB`);
|
|
26
|
+
return window.remotion_mediaCacheSizeInBytes;
|
|
27
|
+
}
|
|
28
|
+
if (window.remotion_initialMemoryAvailable !== undefined &&
|
|
29
|
+
window.remotion_initialMemoryAvailable !== null) {
|
|
30
|
+
const value = window.remotion_initialMemoryAvailable / 2;
|
|
31
|
+
if (value < 240 * 1024 * 1024) {
|
|
32
|
+
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on minimum value of 240MB (which is more than half of the available system memory!)`);
|
|
33
|
+
return 240 * 1024 * 1024;
|
|
34
|
+
}
|
|
35
|
+
if (value > 20000 * 1024 * 1024) {
|
|
36
|
+
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on maximum value of 20GB (which is less than half of the available system memory)`);
|
|
37
|
+
return 20000 * 1024 * 1024;
|
|
38
|
+
}
|
|
39
|
+
Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on available memory (50% of available memory): ${(value / 1024 / 1024).toFixed(1)} MB`);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
return 1000 * 1000 * 1000; // 1GB
|
|
43
|
+
};
|
|
44
|
+
let cachedMaxCacheSize = null;
|
|
45
|
+
export const getMaxVideoCacheSize = (logLevel) => {
|
|
46
|
+
if (cachedMaxCacheSize !== null) {
|
|
47
|
+
return cachedMaxCacheSize;
|
|
48
|
+
}
|
|
49
|
+
cachedMaxCacheSize = getUncachedMaxCacheSize(logLevel);
|
|
50
|
+
return cachedMaxCacheSize;
|
|
51
|
+
};
|
|
@@ -56,8 +56,9 @@ export const resampleAudioData = ({ srcNumberOfChannels, sourceChannels, destina
|
|
|
56
56
|
const c = getSourceValues(start, end, 2);
|
|
57
57
|
const sl = getSourceValues(start, end, 3);
|
|
58
58
|
const sr = getSourceValues(start, end, 4);
|
|
59
|
-
const
|
|
60
|
-
const
|
|
59
|
+
const sq = Math.sqrt(1 / 2);
|
|
60
|
+
const l2 = l + sq * (c + sl);
|
|
61
|
+
const r2 = r + sq * (c + sr);
|
|
61
62
|
destination[newFrameIndex * 2 + 0] = l2;
|
|
62
63
|
destination[newFrameIndex * 2 + 1] = r2;
|
|
63
64
|
}
|