@remotion/studio 4.0.465 → 4.0.467
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/components/CompositionSelectorItem.js +16 -79
- package/dist/components/CurrentAsset.js +8 -54
- package/dist/components/EditorContent.js +1 -3
- package/dist/components/Menu/MenuItem.d.ts +1 -1
- package/dist/components/Modals.js +1 -1
- package/dist/components/NewComposition/MenuContent.js +1 -0
- package/dist/components/NewComposition/ValidationMessage.d.ts +1 -0
- package/dist/components/NewComposition/ValidationMessage.js +3 -3
- package/dist/components/RenderButton.js +1 -0
- package/dist/components/RenderModal/DataEditor.js +8 -2
- package/dist/components/RenderModal/RenderModalAdvanced.d.ts +1 -11
- package/dist/components/RenderModal/RenderModalAdvanced.js +4 -50
- package/dist/components/RenderModal/RenderModalEncoding.d.ts +37 -0
- package/dist/components/RenderModal/RenderModalEncoding.js +165 -0
- package/dist/components/RenderModal/RenderModalPicture.d.ts +1 -22
- package/dist/components/RenderModal/RenderModalPicture.js +6 -84
- package/dist/components/RenderModal/ServerRenderModal.d.ts +1 -0
- package/dist/components/RenderModal/ServerRenderModal.js +16 -4
- package/dist/components/RenderModal/get-render-modal-warnings.d.ts +7 -1
- package/dist/components/RenderModal/get-render-modal-warnings.js +21 -7
- package/dist/components/RenderQueue/actions.d.ts +2 -1
- package/dist/components/RenderQueue/actions.js +2 -1
- package/dist/components/SidebarRenderButton.js +1 -0
- package/dist/components/Timeline/Timeline.js +6 -4
- package/dist/components/Timeline/TimelineEffectFieldRow.js +2 -1
- package/dist/components/Timeline/TimelineEffectGroupRow.d.ts +1 -0
- package/dist/components/Timeline/TimelineEffectGroupRow.js +18 -2
- package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
- package/dist/components/Timeline/TimelineExpandedRow.js +1 -1
- package/dist/components/Timeline/TimelineExpandedSection.js +9 -2
- package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +7 -0
- package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +124 -0
- package/dist/components/Timeline/TimelineListItem.js +21 -3
- package/dist/components/Timeline/TimelineMediaInfo.d.ts +5 -0
- package/dist/components/Timeline/TimelineMediaInfo.js +173 -0
- package/dist/components/Timeline/TimelineSchemaField.js +2 -1
- package/dist/components/Timeline/TimelineStack/index.js +7 -47
- package/dist/components/Timeline/TimelineTracks.js +2 -16
- package/dist/components/Timeline/TimelineVideoInfo.js +2 -2
- package/dist/components/Timeline/get-timeline-keyframes.d.ts +6 -0
- package/dist/components/Timeline/get-timeline-keyframes.js +22 -0
- package/dist/components/composition-menu-items.d.ts +12 -0
- package/dist/components/composition-menu-items.js +166 -0
- package/dist/esm/chunk-5gtx3pza.js +9 -0
- package/dist/esm/{chunk-pqk2qd0d.js → chunk-vwnse6c9.js} +4297 -3547
- package/dist/esm/index.mjs +0 -16
- package/dist/esm/internals.mjs +4295 -3560
- package/dist/esm/previewEntry.mjs +4049 -3314
- package/dist/esm/renderEntry.mjs +3 -4
- package/dist/helpers/format-media-duration.d.ts +1 -0
- package/dist/helpers/format-media-duration.js +14 -0
- package/dist/helpers/get-timeline-sequence-layout.js +4 -3
- package/dist/helpers/make-render-command.d.ts +2 -2
- package/dist/helpers/make-render-command.js +2 -1
- package/dist/helpers/open-in-editor.d.ts +8 -0
- package/dist/helpers/open-in-editor.js +58 -1
- package/dist/helpers/render-modal-sections.d.ts +1 -1
- package/dist/helpers/render-modal-sections.js +35 -5
- package/dist/helpers/retry-payload.js +3 -0
- package/dist/helpers/timeline-layout.d.ts +11 -6
- package/dist/helpers/timeline-layout.js +28 -8
- package/dist/helpers/use-max-media-duration.js +25 -28
- package/dist/helpers/use-media-metadata.d.ts +10 -0
- package/dist/helpers/use-media-metadata.js +135 -0
- package/dist/helpers/use-menu-structure.js +43 -0
- package/dist/state/modals.d.ts +1 -0
- package/package.json +10 -10
- package/dist/esm/chunk-6jf1natv.js +0 -25
package/dist/esm/renderEntry.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
__require
|
|
3
|
-
|
|
4
|
-
} from "./chunk-6jf1natv.js";
|
|
2
|
+
__require
|
|
3
|
+
} from "./chunk-5gtx3pza.js";
|
|
5
4
|
|
|
6
5
|
// src/renderEntry.tsx
|
|
7
6
|
import { useContext, useEffect, useRef, useState } from "react";
|
|
@@ -207,7 +206,7 @@ var renderContent = (Root) => {
|
|
|
207
206
|
renderToDOM(/* @__PURE__ */ jsx("div", {
|
|
208
207
|
children: /* @__PURE__ */ jsx(DelayedSpinner, {})
|
|
209
208
|
}));
|
|
210
|
-
import("./chunk-
|
|
209
|
+
import("./chunk-vwnse6c9.js").then(({ StudioInternals }) => {
|
|
211
210
|
window.remotion_isStudio = true;
|
|
212
211
|
window.remotion_isReadOnlyStudio = true;
|
|
213
212
|
window.remotion_inputProps = "{}";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const formatMediaDuration: (seconds: number) => string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatMediaDuration = void 0;
|
|
4
|
+
const formatMediaDuration = (seconds) => {
|
|
5
|
+
const h = Math.floor(seconds / 3600);
|
|
6
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
7
|
+
const s = seconds % 60;
|
|
8
|
+
const sFixed = s.toFixed(2).padStart(5, '0');
|
|
9
|
+
if (h > 0) {
|
|
10
|
+
return `${h}:${String(m).padStart(2, '0')}:${sFixed}`;
|
|
11
|
+
}
|
|
12
|
+
return `${String(m).padStart(2, '0')}:${sFixed}`;
|
|
13
|
+
};
|
|
14
|
+
exports.formatMediaDuration = formatMediaDuration;
|
|
@@ -13,10 +13,11 @@ const getWidthOfTrack = ({ durationInFrames, lastFrame, windowWidth, spatialDura
|
|
|
13
13
|
const getTimelineSequenceLayout = ({ durationInFrames, startFrom, maxMediaDuration, startFromMedia, video, windowWidth, premountDisplay, postmountDisplay, }) => {
|
|
14
14
|
var _a;
|
|
15
15
|
const maxMediaSequenceDuration = (maxMediaDuration !== null && maxMediaDuration !== void 0 ? maxMediaDuration : Infinity) - startFromMedia;
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const timelineDuration = (_a = video.durationInFrames) !== null && _a !== void 0 ? _a : 1;
|
|
17
|
+
const lastFrame = timelineDuration - 1;
|
|
18
|
+
const spatialDuration = Math.max(0, Math.min(maxMediaSequenceDuration, durationInFrames, timelineDuration - startFrom));
|
|
18
19
|
// Unclipped spatial duration: without the lastFrame - startFrom constraint
|
|
19
|
-
const naturalSpatialDuration = Math.max(0, Math.min(maxMediaSequenceDuration, durationInFrames
|
|
20
|
+
const naturalSpatialDuration = Math.max(0, Math.min(maxMediaSequenceDuration, durationInFrames));
|
|
20
21
|
const marginLeft = lastFrame === 0
|
|
21
22
|
? 0
|
|
22
23
|
: (startFrom / lastFrame) * (windowWidth - timeline_layout_1.TIMELINE_PADDING * 2);
|
|
@@ -10,7 +10,7 @@ export declare const normalizeServeUrlForRenderCommand: ({ locationHref, composi
|
|
|
10
10
|
type StrictRequired<T> = {
|
|
11
11
|
[K in keyof T]-?: Exclude<T[K], undefined>;
|
|
12
12
|
};
|
|
13
|
-
type RenderMediaCommandOptions = Omit<StrictRequired<Pick<RenderMediaOptions, 'codec' | 'crf' | 'concurrency' | 'disallowParallelEncoding' | 'muted' | 'enforceAudioTrack' | 'everyNthFrame' | 'numberOfGifLoops' | 'colorSpace' | 'scale' | 'logLevel' | 'repro' | 'metadata' | 'jpegQuality' | 'pixelFormat' | 'proResProfile' | 'x264Preset' | 'audioCodec' | 'forSeamlessAacConcatenation' | 'separateAudioTo' | 'hardwareAcceleration' | 'chromeMode' | 'offthreadVideoCacheSizeInBytes' | 'offthreadVideoThreads' | 'mediaCacheSizeInBytes' | 'audioBitrate' | 'videoBitrate' | 'encodingMaxRate' | 'encodingBufferSize' | 'sampleRate'>>, 'audioBitrate' | 'videoBitrate' | 'encodingMaxRate' | 'encodingBufferSize' | 'jpegQuality' | 'proResProfile'> & {
|
|
13
|
+
type RenderMediaCommandOptions = Omit<StrictRequired<Pick<RenderMediaOptions, 'codec' | 'crf' | 'concurrency' | 'disallowParallelEncoding' | 'muted' | 'enforceAudioTrack' | 'everyNthFrame' | 'numberOfGifLoops' | 'colorSpace' | 'scale' | 'logLevel' | 'repro' | 'metadata' | 'jpegQuality' | 'pixelFormat' | 'proResProfile' | 'x264Preset' | 'gopSize' | 'audioCodec' | 'forSeamlessAacConcatenation' | 'separateAudioTo' | 'hardwareAcceleration' | 'chromeMode' | 'offthreadVideoCacheSizeInBytes' | 'offthreadVideoThreads' | 'mediaCacheSizeInBytes' | 'audioBitrate' | 'videoBitrate' | 'encodingMaxRate' | 'encodingBufferSize' | 'sampleRate'>>, 'audioBitrate' | 'videoBitrate' | 'encodingMaxRate' | 'encodingBufferSize' | 'jpegQuality' | 'proResProfile'> & {
|
|
14
14
|
audioBitrate: string | null;
|
|
15
15
|
videoBitrate: string | null;
|
|
16
16
|
encodingMaxRate: string | null;
|
|
@@ -48,5 +48,5 @@ type ReadOnlyStudioRenderCommandInput = RenderMediaCommandOptions & RenderStillC
|
|
|
48
48
|
envVariables: Record<string, string>;
|
|
49
49
|
inputProps: Record<string, unknown>;
|
|
50
50
|
};
|
|
51
|
-
export declare const makeReadOnlyStudioRenderCommand: ({ remotionVersion, locationHref, compositionId, outName, renderMode, renderDefaults, durationInFrames, concurrency, frame, startFrame, endFrame, stillImageFormat, sequenceImageFormat, videoImageFormat, jpegQuality, codec, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, crf, videoBitrate, audioBitrate, audioCodec, everyNthFrame, numberOfGifLoops, disallowParallelEncoding, encodingBufferSize, encodingMaxRate, forSeamlessAacConcatenation, separateAudioTo, colorSpace, scale, logLevel, delayRenderTimeout, hardwareAcceleration, chromeMode, headless, disableWebSecurity, ignoreCertificateErrors, gl, userAgent, multiProcessOnLinux, darkMode, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, mediaCacheSizeInBytes, beepOnFinish, repro, metadata, sampleRate, envVariables, inputProps, }: ReadOnlyStudioRenderCommandInput) => string;
|
|
51
|
+
export declare const makeReadOnlyStudioRenderCommand: ({ remotionVersion, locationHref, compositionId, outName, renderMode, renderDefaults, durationInFrames, concurrency, frame, startFrame, endFrame, stillImageFormat, sequenceImageFormat, videoImageFormat, jpegQuality, codec, muted, enforceAudioTrack, proResProfile, x264Preset, gopSize, pixelFormat, crf, videoBitrate, audioBitrate, audioCodec, everyNthFrame, numberOfGifLoops, disallowParallelEncoding, encodingBufferSize, encodingMaxRate, forSeamlessAacConcatenation, separateAudioTo, colorSpace, scale, logLevel, delayRenderTimeout, hardwareAcceleration, chromeMode, headless, disableWebSecurity, ignoreCertificateErrors, gl, userAgent, multiProcessOnLinux, darkMode, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, mediaCacheSizeInBytes, beepOnFinish, repro, metadata, sampleRate, envVariables, inputProps, }: ReadOnlyStudioRenderCommandInput) => string;
|
|
52
52
|
export {};
|
|
@@ -80,7 +80,7 @@ const renderMediaValueFlag = (option, value, defaultValue) => {
|
|
|
80
80
|
const renderMediaBooleanFlag = (option, value, defaultValue) => {
|
|
81
81
|
return booleanFlag(getRenderMediaFlag(option), value, defaultValue);
|
|
82
82
|
};
|
|
83
|
-
const makeReadOnlyStudioRenderCommand = ({ remotionVersion, locationHref, compositionId, outName, renderMode, renderDefaults, durationInFrames, concurrency, frame, startFrame, endFrame, stillImageFormat, sequenceImageFormat, videoImageFormat, jpegQuality, codec, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, crf, videoBitrate, audioBitrate, audioCodec, everyNthFrame, numberOfGifLoops, disallowParallelEncoding, encodingBufferSize, encodingMaxRate, forSeamlessAacConcatenation, separateAudioTo, colorSpace, scale, logLevel, delayRenderTimeout, hardwareAcceleration, chromeMode, headless, disableWebSecurity, ignoreCertificateErrors, gl, userAgent, multiProcessOnLinux, darkMode, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, mediaCacheSizeInBytes, beepOnFinish, repro, metadata, sampleRate, envVariables, inputProps, }) => {
|
|
83
|
+
const makeReadOnlyStudioRenderCommand = ({ remotionVersion, locationHref, compositionId, outName, renderMode, renderDefaults, durationInFrames, concurrency, frame, startFrame, endFrame, stillImageFormat, sequenceImageFormat, videoImageFormat, jpegQuality, codec, muted, enforceAudioTrack, proResProfile, x264Preset, gopSize, pixelFormat, crf, videoBitrate, audioBitrate, audioCodec, everyNthFrame, numberOfGifLoops, disallowParallelEncoding, encodingBufferSize, encodingMaxRate, forSeamlessAacConcatenation, separateAudioTo, colorSpace, scale, logLevel, delayRenderTimeout, hardwareAcceleration, chromeMode, headless, disableWebSecurity, ignoreCertificateErrors, gl, userAgent, multiProcessOnLinux, darkMode, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, mediaCacheSizeInBytes, beepOnFinish, repro, metadata, sampleRate, envVariables, inputProps, }) => {
|
|
84
84
|
var _a;
|
|
85
85
|
const serveUrl = (0, exports.normalizeServeUrlForRenderCommand)({
|
|
86
86
|
locationHref,
|
|
@@ -154,6 +154,7 @@ const makeReadOnlyStudioRenderCommand = ({ remotionVersion, locationHref, compos
|
|
|
154
154
|
renderMediaValueFlag('colorSpace', colorSpace, renderDefaults.colorSpace),
|
|
155
155
|
valueFlag(options.proResProfileOption.cliFlag, proResProfile, renderDefaults.proResProfile),
|
|
156
156
|
renderMediaValueFlag('x264Preset', x264Preset, renderDefaults.x264Preset),
|
|
157
|
+
renderMediaValueFlag('gopSize', gopSize, renderDefaults.gopSize),
|
|
157
158
|
valueFlag(options.crfOption.cliFlag, crf, null),
|
|
158
159
|
valueFlag(options.jpegQualityOption.cliFlag, jpegQuality, renderDefaults.jpegQuality),
|
|
159
160
|
renderMediaValueFlag('videoBitrate', videoBitrate, renderDefaults.videoBitrate),
|
|
@@ -2,3 +2,11 @@ import type { SymbolicatedStackFrame } from '@remotion/studio-shared';
|
|
|
2
2
|
import type { OriginalPosition } from '../error-overlay/react-overlay/utils/get-source-map';
|
|
3
3
|
export declare const openInEditor: (stack: SymbolicatedStackFrame) => Promise<Response>;
|
|
4
4
|
export declare const openOriginalPositionInEditor: (originalPosition: OriginalPosition) => Promise<void>;
|
|
5
|
+
export declare const preloadCompositionComponentInfo: ({ compositionFile, compositionId, }: {
|
|
6
|
+
compositionFile: string;
|
|
7
|
+
compositionId: string;
|
|
8
|
+
}) => void;
|
|
9
|
+
export declare const openCompositionComponentInEditor: ({ compositionFile, compositionId, }: {
|
|
10
|
+
compositionFile: string;
|
|
11
|
+
compositionId: string;
|
|
12
|
+
}) => Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.openOriginalPositionInEditor = exports.openInEditor = void 0;
|
|
3
|
+
exports.openCompositionComponentInEditor = exports.preloadCompositionComponentInfo = exports.openOriginalPositionInEditor = exports.openInEditor = void 0;
|
|
4
4
|
const openInEditor = (stack) => {
|
|
5
5
|
const { originalFileName, originalLineNumber, originalColumnNumber, originalFunctionName, originalScriptCode, } = stack;
|
|
6
6
|
return fetch(`/api/open-in-editor`, {
|
|
@@ -30,3 +30,60 @@ const openOriginalPositionInEditor = async (originalPosition) => {
|
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
32
|
exports.openOriginalPositionInEditor = openOriginalPositionInEditor;
|
|
33
|
+
const componentResolutionCache = new Map();
|
|
34
|
+
const getComponentResolutionCacheKey = ({ compositionFile, compositionId, }) => {
|
|
35
|
+
return `${compositionFile}::${compositionId}`;
|
|
36
|
+
};
|
|
37
|
+
const loadCompositionComponentInfo = async ({ compositionFile, compositionId, }) => {
|
|
38
|
+
const cacheKey = getComponentResolutionCacheKey({
|
|
39
|
+
compositionFile,
|
|
40
|
+
compositionId,
|
|
41
|
+
});
|
|
42
|
+
const existing = componentResolutionCache.get(cacheKey);
|
|
43
|
+
if (existing) {
|
|
44
|
+
return existing;
|
|
45
|
+
}
|
|
46
|
+
const promise = (async () => {
|
|
47
|
+
const response = await fetch(`/api/composition-component-info`, {
|
|
48
|
+
method: 'post',
|
|
49
|
+
headers: {
|
|
50
|
+
'content-type': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
compositionFile,
|
|
54
|
+
compositionId,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
const body = (await response.json());
|
|
58
|
+
if (!body.success) {
|
|
59
|
+
throw new Error(body.error);
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
location: body.location,
|
|
63
|
+
canAddSequence: body.canAddSequence,
|
|
64
|
+
};
|
|
65
|
+
})();
|
|
66
|
+
componentResolutionCache.set(cacheKey, promise);
|
|
67
|
+
try {
|
|
68
|
+
return await promise;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
componentResolutionCache.delete(cacheKey);
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const preloadCompositionComponentInfo = ({ compositionFile, compositionId, }) => {
|
|
76
|
+
loadCompositionComponentInfo({
|
|
77
|
+
compositionFile,
|
|
78
|
+
compositionId,
|
|
79
|
+
}).catch(() => undefined);
|
|
80
|
+
};
|
|
81
|
+
exports.preloadCompositionComponentInfo = preloadCompositionComponentInfo;
|
|
82
|
+
const openCompositionComponentInEditor = async ({ compositionFile, compositionId, }) => {
|
|
83
|
+
const info = await loadCompositionComponentInfo({
|
|
84
|
+
compositionFile,
|
|
85
|
+
compositionId,
|
|
86
|
+
});
|
|
87
|
+
await (0, exports.openOriginalPositionInEditor)(info.location);
|
|
88
|
+
};
|
|
89
|
+
exports.openCompositionComponentInEditor = openCompositionComponentInEditor;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RenderType } from '../components/RenderModal/RenderModalAdvanced';
|
|
2
|
-
type Section = 'general' | '
|
|
2
|
+
type Section = 'general' | 'data' | 'picture' | 'audio' | 'gif' | 'encoding' | 'environment' | 'advanced';
|
|
3
3
|
export declare const useRenderModalSections: (renderMode: RenderType, codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => {
|
|
4
4
|
tab: Section;
|
|
5
5
|
setTab: import("react").Dispatch<import("react").SetStateAction<Section>>;
|
|
@@ -6,19 +6,49 @@ const useRenderModalSections = (renderMode, codec) => {
|
|
|
6
6
|
const [selectedTab, setTab] = (0, react_1.useState)('general');
|
|
7
7
|
const shownTabs = (0, react_1.useMemo)(() => {
|
|
8
8
|
if (renderMode === 'audio') {
|
|
9
|
-
return [
|
|
9
|
+
return [
|
|
10
|
+
'general',
|
|
11
|
+
'data',
|
|
12
|
+
'audio',
|
|
13
|
+
'encoding',
|
|
14
|
+
'environment',
|
|
15
|
+
'advanced',
|
|
16
|
+
];
|
|
10
17
|
}
|
|
11
18
|
if (renderMode === 'still') {
|
|
12
|
-
return ['general', 'data', 'picture', 'advanced'];
|
|
19
|
+
return ['general', 'data', 'picture', 'environment', 'advanced'];
|
|
13
20
|
}
|
|
14
21
|
if (renderMode === 'sequence') {
|
|
15
|
-
return [
|
|
22
|
+
return [
|
|
23
|
+
'general',
|
|
24
|
+
'data',
|
|
25
|
+
'picture',
|
|
26
|
+
'encoding',
|
|
27
|
+
'environment',
|
|
28
|
+
'advanced',
|
|
29
|
+
];
|
|
16
30
|
}
|
|
17
31
|
if (renderMode === 'video') {
|
|
18
32
|
if (codec === 'gif') {
|
|
19
|
-
return [
|
|
33
|
+
return [
|
|
34
|
+
'general',
|
|
35
|
+
'data',
|
|
36
|
+
'picture',
|
|
37
|
+
'gif',
|
|
38
|
+
'encoding',
|
|
39
|
+
'environment',
|
|
40
|
+
'advanced',
|
|
41
|
+
];
|
|
20
42
|
}
|
|
21
|
-
return [
|
|
43
|
+
return [
|
|
44
|
+
'general',
|
|
45
|
+
'data',
|
|
46
|
+
'picture',
|
|
47
|
+
'audio',
|
|
48
|
+
'encoding',
|
|
49
|
+
'environment',
|
|
50
|
+
'advanced',
|
|
51
|
+
];
|
|
22
52
|
}
|
|
23
53
|
throw new TypeError('Unknown render mode');
|
|
24
54
|
}, [codec, renderMode]);
|
|
@@ -25,6 +25,7 @@ const makeRetryPayload = (job) => {
|
|
|
25
25
|
initialEnforceAudioTrack: defaults.enforceAudioTrack,
|
|
26
26
|
initialProResProfile: null,
|
|
27
27
|
initialx264Preset: defaults.x264Preset,
|
|
28
|
+
initialGopSize: defaults.gopSize,
|
|
28
29
|
initialPixelFormat: defaults.pixelFormat,
|
|
29
30
|
initialAudioBitrate: defaults.audioBitrate,
|
|
30
31
|
initialVideoBitrate: defaults.videoBitrate,
|
|
@@ -78,6 +79,7 @@ const makeRetryPayload = (job) => {
|
|
|
78
79
|
initialEnforceAudioTrack: defaults.enforceAudioTrack,
|
|
79
80
|
initialProResProfile: null,
|
|
80
81
|
initialx264Preset: defaults.x264Preset,
|
|
82
|
+
initialGopSize: defaults.gopSize,
|
|
81
83
|
initialPixelFormat: defaults.pixelFormat,
|
|
82
84
|
initialAudioBitrate: defaults.audioBitrate,
|
|
83
85
|
initialVideoBitrate: defaults.videoBitrate,
|
|
@@ -133,6 +135,7 @@ const makeRetryPayload = (job) => {
|
|
|
133
135
|
initialEnforceAudioTrack: job.enforceAudioTrack,
|
|
134
136
|
initialProResProfile: (_d = job.proResProfile) !== null && _d !== void 0 ? _d : null,
|
|
135
137
|
initialx264Preset: (_e = job.x264Preset) !== null && _e !== void 0 ? _e : defaults.x264Preset,
|
|
138
|
+
initialGopSize: job.gopSize,
|
|
136
139
|
initialPixelFormat: job.pixelFormat,
|
|
137
140
|
initialAudioBitrate: job.audioBitrate,
|
|
138
141
|
initialVideoBitrate: job.videoBitrate,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type AnySchemaFieldInfo, type CodeValues, type DragOverrides, type EffectSchemaFieldInfo, type SchemaFieldInfo, type SequenceControls, type SequenceSchemaFieldInfo } from '@remotion/studio-shared';
|
|
2
|
-
import type { GetDragOverrides, SequenceSchema as SequenceSchemaShape, TSequence } from 'remotion';
|
|
2
|
+
import type { GetDragOverrides, GetEffectDragOverrides, SequenceSchema as SequenceSchemaShape, TSequence } from 'remotion';
|
|
3
3
|
import type { GetIsExpanded } from '../components/ExpandedTracksProvider';
|
|
4
4
|
import type { SequenceNodePathInfo } from './get-timeline-sequence-sort-key';
|
|
5
|
+
export { getEffectFieldsToShow, getFieldsToShow, SCHEMA_FIELD_ROW_HEIGHT, } from '@remotion/studio-shared';
|
|
5
6
|
export type { AnySchemaFieldInfo, CodeValues, DragOverrides, EffectSchemaFieldInfo, SchemaFieldInfo, SequenceControls, SequenceSchemaFieldInfo, };
|
|
6
|
-
export { SCHEMA_FIELD_ROW_HEIGHT, getEffectFieldsToShow, getFieldsToShow, } from '@remotion/studio-shared';
|
|
7
7
|
export declare const TIMELINE_PADDING = 16;
|
|
8
8
|
export declare const TIMELINE_BORDER = 1;
|
|
9
9
|
export declare const TIMELINE_ITEM_BORDER_BOTTOM = 1;
|
|
@@ -15,6 +15,7 @@ export type TimelineFieldOnDragValueChange = (value: unknown) => void;
|
|
|
15
15
|
export type TimelineEffectGroupInfo = {
|
|
16
16
|
readonly effectIndex: number;
|
|
17
17
|
readonly effectSchema: SequenceSchemaShape;
|
|
18
|
+
readonly documentationLink: string | null;
|
|
18
19
|
};
|
|
19
20
|
export type TimelineTreeNode = {
|
|
20
21
|
readonly kind: 'group';
|
|
@@ -28,10 +29,11 @@ export type TimelineTreeNode = {
|
|
|
28
29
|
readonly label: string;
|
|
29
30
|
readonly field: AnySchemaFieldInfo | null;
|
|
30
31
|
};
|
|
31
|
-
export declare const buildTimelineTree: ({ sequence, nodePathInfo, getDragOverrides, codeValues, }: {
|
|
32
|
+
export declare const buildTimelineTree: ({ sequence, nodePathInfo, getDragOverrides, getEffectDragOverrides, codeValues, }: {
|
|
32
33
|
sequence: TSequence;
|
|
33
34
|
nodePathInfo: SequenceNodePathInfo;
|
|
34
35
|
getDragOverrides: GetDragOverrides;
|
|
36
|
+
getEffectDragOverrides: GetEffectDragOverrides;
|
|
35
37
|
codeValues: CodeValues;
|
|
36
38
|
}) => TimelineTreeNode[];
|
|
37
39
|
export type FlatTreeRow = {
|
|
@@ -51,6 +53,9 @@ export declare const getExpandedTrackHeight: ({ sequence, nodePathInfo, getIsExp
|
|
|
51
53
|
codeValues: CodeValues;
|
|
52
54
|
}) => number;
|
|
53
55
|
export declare const TIMELINE_LAYER_HEIGHT_VIDEO = 75;
|
|
54
|
-
export declare const TIMELINE_LAYER_HEIGHT_IMAGE =
|
|
55
|
-
export declare const TIMELINE_LAYER_HEIGHT_AUDIO =
|
|
56
|
-
export declare const
|
|
56
|
+
export declare const TIMELINE_LAYER_HEIGHT_IMAGE = 58;
|
|
57
|
+
export declare const TIMELINE_LAYER_HEIGHT_AUDIO = 58;
|
|
58
|
+
export declare const TIMELINE_LAYER_HEIGHT_DEFAULT = 25;
|
|
59
|
+
export declare const TIMELINE_LIST_ITEM_ROW_HEIGHT = 25;
|
|
60
|
+
export declare const TIMELINE_VIDEO_INFO_WAVEFORM_HEIGHT = 25;
|
|
61
|
+
export declare const getTimelineLayerHeight: (type: "audio" | "image" | "other" | "sequence" | "video") => 25 | 58 | 75;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTimelineLayerHeight = exports.TIMELINE_LAYER_HEIGHT_AUDIO = exports.TIMELINE_LAYER_HEIGHT_IMAGE = exports.TIMELINE_LAYER_HEIGHT_VIDEO = exports.getExpandedTrackHeight = exports.getTreeRowHeight = exports.flattenVisibleTreeNodes = exports.buildTimelineTree = exports.EXPANDED_SECTION_PADDING_RIGHT = exports.TREE_GROUP_ROW_HEIGHT = exports.TIMELINE_TRACK_EXPANDED_HEIGHT = exports.TIMELINE_ITEM_BORDER_BOTTOM = exports.TIMELINE_BORDER = exports.TIMELINE_PADDING = exports.
|
|
3
|
+
exports.getTimelineLayerHeight = exports.TIMELINE_VIDEO_INFO_WAVEFORM_HEIGHT = exports.TIMELINE_LIST_ITEM_ROW_HEIGHT = exports.TIMELINE_LAYER_HEIGHT_DEFAULT = exports.TIMELINE_LAYER_HEIGHT_AUDIO = exports.TIMELINE_LAYER_HEIGHT_IMAGE = exports.TIMELINE_LAYER_HEIGHT_VIDEO = exports.getExpandedTrackHeight = exports.getTreeRowHeight = exports.flattenVisibleTreeNodes = exports.buildTimelineTree = exports.EXPANDED_SECTION_PADDING_RIGHT = exports.TREE_GROUP_ROW_HEIGHT = exports.TIMELINE_TRACK_EXPANDED_HEIGHT = exports.TIMELINE_ITEM_BORDER_BOTTOM = exports.TIMELINE_BORDER = exports.TIMELINE_PADDING = exports.SCHEMA_FIELD_ROW_HEIGHT = exports.getFieldsToShow = exports.getEffectFieldsToShow = void 0;
|
|
4
4
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
5
5
|
const studio_shared_2 = require("@remotion/studio-shared");
|
|
6
|
-
Object.defineProperty(exports, "SCHEMA_FIELD_ROW_HEIGHT", { enumerable: true, get: function () { return studio_shared_2.SCHEMA_FIELD_ROW_HEIGHT; } });
|
|
7
6
|
Object.defineProperty(exports, "getEffectFieldsToShow", { enumerable: true, get: function () { return studio_shared_2.getEffectFieldsToShow; } });
|
|
8
7
|
Object.defineProperty(exports, "getFieldsToShow", { enumerable: true, get: function () { return studio_shared_2.getFieldsToShow; } });
|
|
8
|
+
Object.defineProperty(exports, "SCHEMA_FIELD_ROW_HEIGHT", { enumerable: true, get: function () { return studio_shared_2.SCHEMA_FIELD_ROW_HEIGHT; } });
|
|
9
9
|
exports.TIMELINE_PADDING = 16;
|
|
10
10
|
exports.TIMELINE_BORDER = 1;
|
|
11
11
|
exports.TIMELINE_ITEM_BORDER_BOTTOM = 1;
|
|
12
12
|
exports.TIMELINE_TRACK_EXPANDED_HEIGHT = 100;
|
|
13
13
|
exports.TREE_GROUP_ROW_HEIGHT = 22;
|
|
14
14
|
exports.EXPANDED_SECTION_PADDING_RIGHT = 10;
|
|
15
|
-
const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, codeValues, }) => {
|
|
15
|
+
const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getEffectDragOverrides, codeValues, }) => {
|
|
16
16
|
var _a;
|
|
17
17
|
const roots = [];
|
|
18
18
|
const { sequenceSubscriptionKey, index, auxiliaryKeys } = nodePathInfo;
|
|
@@ -50,7 +50,14 @@ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, codeValue
|
|
|
50
50
|
label: 'Effects',
|
|
51
51
|
effectInfo: null,
|
|
52
52
|
children: sequence.effects.map((effect, i) => {
|
|
53
|
-
|
|
53
|
+
var _a;
|
|
54
|
+
const effectFields = (0, studio_shared_1.getEffectFieldsToShow)({
|
|
55
|
+
effect,
|
|
56
|
+
effectIndex: i,
|
|
57
|
+
nodePath: sequenceSubscriptionKey,
|
|
58
|
+
codeValues,
|
|
59
|
+
getEffectDragOverrides,
|
|
60
|
+
});
|
|
54
61
|
return {
|
|
55
62
|
kind: 'group',
|
|
56
63
|
nodePathInfo: {
|
|
@@ -60,7 +67,11 @@ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, codeValue
|
|
|
60
67
|
numberOfSequencesWithThisNodePath: 0,
|
|
61
68
|
},
|
|
62
69
|
label: effect.label,
|
|
63
|
-
effectInfo: {
|
|
70
|
+
effectInfo: {
|
|
71
|
+
effectIndex: i,
|
|
72
|
+
effectSchema: effect.schema,
|
|
73
|
+
documentationLink: (_a = effect.documentationLink) !== null && _a !== void 0 ? _a : null,
|
|
74
|
+
},
|
|
64
75
|
children: effectFields.map((f) => {
|
|
65
76
|
var _a;
|
|
66
77
|
return ({
|
|
@@ -115,6 +126,7 @@ const getExpandedTrackHeight = ({ sequence, nodePathInfo, getIsExpanded, codeVal
|
|
|
115
126
|
nodePathInfo,
|
|
116
127
|
// We assume that no drag overrides can change the timeline layout
|
|
117
128
|
getDragOverrides: () => ({}),
|
|
129
|
+
getEffectDragOverrides: () => ({}),
|
|
118
130
|
codeValues,
|
|
119
131
|
});
|
|
120
132
|
const flat = (0, exports.flattenVisibleTreeNodes)({ nodes: tree, getIsExpanded });
|
|
@@ -127,8 +139,13 @@ const getExpandedTrackHeight = ({ sequence, nodePathInfo, getIsExpanded, codeVal
|
|
|
127
139
|
};
|
|
128
140
|
exports.getExpandedTrackHeight = getExpandedTrackHeight;
|
|
129
141
|
exports.TIMELINE_LAYER_HEIGHT_VIDEO = 75;
|
|
130
|
-
exports.TIMELINE_LAYER_HEIGHT_IMAGE =
|
|
131
|
-
exports.TIMELINE_LAYER_HEIGHT_AUDIO =
|
|
142
|
+
exports.TIMELINE_LAYER_HEIGHT_IMAGE = 58;
|
|
143
|
+
exports.TIMELINE_LAYER_HEIGHT_AUDIO = 58;
|
|
144
|
+
exports.TIMELINE_LAYER_HEIGHT_DEFAULT = 25;
|
|
145
|
+
// The horizontal row inside a timeline list item (eye + arrow + label).
|
|
146
|
+
exports.TIMELINE_LIST_ITEM_ROW_HEIGHT = 25;
|
|
147
|
+
// The waveform stripe rendered underneath the filmstrip in TimelineVideoInfo.
|
|
148
|
+
exports.TIMELINE_VIDEO_INFO_WAVEFORM_HEIGHT = 25;
|
|
132
149
|
const getTimelineLayerHeight = (type) => {
|
|
133
150
|
if (type === 'video') {
|
|
134
151
|
return exports.TIMELINE_LAYER_HEIGHT_VIDEO;
|
|
@@ -136,6 +153,9 @@ const getTimelineLayerHeight = (type) => {
|
|
|
136
153
|
if (type === 'image') {
|
|
137
154
|
return exports.TIMELINE_LAYER_HEIGHT_IMAGE;
|
|
138
155
|
}
|
|
139
|
-
|
|
156
|
+
if (type === 'audio') {
|
|
157
|
+
return exports.TIMELINE_LAYER_HEIGHT_AUDIO;
|
|
158
|
+
}
|
|
159
|
+
return exports.TIMELINE_LAYER_HEIGHT_DEFAULT;
|
|
140
160
|
};
|
|
141
161
|
exports.getTimelineLayerHeight = getTimelineLayerHeight;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useMaxMediaDuration = void 0;
|
|
4
|
-
const media_utils_1 = require("@remotion/media-utils");
|
|
5
|
-
const mediabunny_1 = require("mediabunny");
|
|
6
4
|
const react_1 = require("react");
|
|
7
|
-
const
|
|
5
|
+
const use_media_metadata_1 = require("./use-media-metadata");
|
|
8
6
|
const cache = new Map();
|
|
7
|
+
const getCacheKey = (src, fps) => JSON.stringify([src, fps]);
|
|
9
8
|
const getSrc = (s) => {
|
|
10
9
|
if (s.type === 'video') {
|
|
11
10
|
return s.src;
|
|
@@ -18,40 +17,38 @@ const getSrc = (s) => {
|
|
|
18
17
|
const useMaxMediaDuration = (s, fps) => {
|
|
19
18
|
var _a;
|
|
20
19
|
const src = getSrc(s);
|
|
21
|
-
const
|
|
20
|
+
const cacheKey = src ? getCacheKey(src, fps) : null;
|
|
21
|
+
const [maxMediaDuration, setMaxMediaDuration] = (0, react_1.useState)(cacheKey ? ((_a = cache.get(cacheKey)) !== null && _a !== void 0 ? _a : null) : Infinity);
|
|
22
22
|
(0, react_1.useEffect)(() => {
|
|
23
|
-
|
|
23
|
+
var _a;
|
|
24
|
+
if (!src || !cacheKey) {
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
const cached = (_a = cache.get(cacheKey)) !== null && _a !== void 0 ? _a : null;
|
|
28
|
+
setMaxMediaDuration(cached);
|
|
29
|
+
if (cached !== null) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let cancelled = false;
|
|
33
|
+
(0, use_media_metadata_1.getMediaMetadata)(src)
|
|
34
|
+
.then((metadata) => {
|
|
35
|
+
if (cancelled || !metadata) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const duration = Math.floor(metadata.duration * fps);
|
|
39
|
+
cache.set(cacheKey, duration);
|
|
40
|
+
setMaxMediaDuration(duration);
|
|
34
41
|
})
|
|
35
|
-
.catch((
|
|
36
|
-
if (
|
|
42
|
+
.catch(() => {
|
|
43
|
+
if (cancelled) {
|
|
37
44
|
return;
|
|
38
45
|
}
|
|
39
|
-
|
|
40
|
-
return (0, media_utils_1.getVideoMetadata)(src)
|
|
41
|
-
.then((metadata) => {
|
|
42
|
-
var _a;
|
|
43
|
-
const durationOrInfinity = (_a = metadata.durationInSeconds) !== null && _a !== void 0 ? _a : Infinity;
|
|
44
|
-
cache.set(src, Math.floor(durationOrInfinity * fps));
|
|
45
|
-
setMaxMediaDuration(Math.floor(durationOrInfinity * fps));
|
|
46
|
-
})
|
|
47
|
-
.catch(() => {
|
|
48
|
-
// Silently handle getVideoMetadata failures to prevent unhandled rejections
|
|
49
|
-
});
|
|
46
|
+
setMaxMediaDuration(null);
|
|
50
47
|
});
|
|
51
48
|
return () => {
|
|
52
|
-
|
|
49
|
+
cancelled = true;
|
|
53
50
|
};
|
|
54
|
-
}, [
|
|
51
|
+
}, [cacheKey, fps, src]);
|
|
55
52
|
if (maxMediaDuration !== null && (s.type === 'audio' || s.type === 'video')) {
|
|
56
53
|
return maxMediaDuration;
|
|
57
54
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type MediaMetadata = {
|
|
2
|
+
duration: number;
|
|
3
|
+
format: string | null;
|
|
4
|
+
width: number | null;
|
|
5
|
+
height: number | null;
|
|
6
|
+
videoCodec: string | null;
|
|
7
|
+
audioCodec: string | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const getMediaMetadata: (src: string) => Promise<MediaMetadata | null>;
|
|
10
|
+
export declare const useMediaMetadata: (src: string | null) => MediaMetadata | null;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useMediaMetadata = exports.getMediaMetadata = void 0;
|
|
4
|
+
const media_utils_1 = require("@remotion/media-utils");
|
|
5
|
+
const mediabunny_1 = require("mediabunny");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const get_duration_or_compute_1 = require("./get-duration-or-compute");
|
|
8
|
+
const cache = new Map();
|
|
9
|
+
const pendingRequests = new Map();
|
|
10
|
+
const safeCall = async (fn) => {
|
|
11
|
+
try {
|
|
12
|
+
return await fn();
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const getMediabunnyMetadata = async (src) => {
|
|
19
|
+
var _a;
|
|
20
|
+
let input;
|
|
21
|
+
try {
|
|
22
|
+
input = new mediabunny_1.Input({
|
|
23
|
+
formats: mediabunny_1.ALL_FORMATS,
|
|
24
|
+
source: new mediabunny_1.UrlSource(src),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (_b) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const [duration, format, videoTrack, audioTrack] = await Promise.all([
|
|
32
|
+
safeCall(() => (0, get_duration_or_compute_1.getDurationOrCompute)(input)),
|
|
33
|
+
safeCall(() => input.getFormat()),
|
|
34
|
+
safeCall(() => input.getPrimaryVideoTrack()),
|
|
35
|
+
safeCall(() => input.getPrimaryAudioTrack()),
|
|
36
|
+
]);
|
|
37
|
+
if (duration === null) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const [width, height, videoCodec, audioCodec] = await Promise.all([
|
|
41
|
+
videoTrack ? safeCall(() => videoTrack.getDisplayWidth()) : null,
|
|
42
|
+
videoTrack ? safeCall(() => videoTrack.getDisplayHeight()) : null,
|
|
43
|
+
videoTrack ? safeCall(() => videoTrack.getCodec()) : null,
|
|
44
|
+
audioTrack ? safeCall(() => audioTrack.getCodec()) : null,
|
|
45
|
+
]);
|
|
46
|
+
return {
|
|
47
|
+
duration,
|
|
48
|
+
format: (_a = format === null || format === void 0 ? void 0 : format.name) !== null && _a !== void 0 ? _a : null,
|
|
49
|
+
width,
|
|
50
|
+
height,
|
|
51
|
+
videoCodec,
|
|
52
|
+
audioCodec,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
try {
|
|
57
|
+
input.dispose();
|
|
58
|
+
}
|
|
59
|
+
catch (_c) {
|
|
60
|
+
// ignore
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const getFallbackVideoMetadata = async (src) => {
|
|
65
|
+
try {
|
|
66
|
+
const metadata = await (0, media_utils_1.getVideoMetadata)(src);
|
|
67
|
+
return {
|
|
68
|
+
duration: metadata.durationInSeconds,
|
|
69
|
+
format: null,
|
|
70
|
+
width: metadata.width,
|
|
71
|
+
height: metadata.height,
|
|
72
|
+
videoCodec: null,
|
|
73
|
+
audioCodec: null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (_a) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const getMediaMetadata = (src) => {
|
|
81
|
+
const cached = cache.get(src);
|
|
82
|
+
if (cached) {
|
|
83
|
+
return Promise.resolve(cached);
|
|
84
|
+
}
|
|
85
|
+
const pendingRequest = pendingRequests.get(src);
|
|
86
|
+
if (pendingRequest) {
|
|
87
|
+
return pendingRequest;
|
|
88
|
+
}
|
|
89
|
+
const request = getMediabunnyMetadata(src)
|
|
90
|
+
.catch(() => null)
|
|
91
|
+
.then((metadata) => metadata !== null && metadata !== void 0 ? metadata : getFallbackVideoMetadata(src))
|
|
92
|
+
.then((metadata) => {
|
|
93
|
+
if (metadata) {
|
|
94
|
+
cache.set(src, metadata);
|
|
95
|
+
}
|
|
96
|
+
return metadata;
|
|
97
|
+
})
|
|
98
|
+
.finally(() => {
|
|
99
|
+
pendingRequests.delete(src);
|
|
100
|
+
});
|
|
101
|
+
pendingRequests.set(src, request);
|
|
102
|
+
return request;
|
|
103
|
+
};
|
|
104
|
+
exports.getMediaMetadata = getMediaMetadata;
|
|
105
|
+
const useMediaMetadata = (src) => {
|
|
106
|
+
var _a;
|
|
107
|
+
const [mediaMetadata, setMediaMetadata] = (0, react_1.useState)(src ? ((_a = cache.get(src)) !== null && _a !== void 0 ? _a : null) : null);
|
|
108
|
+
(0, react_1.useEffect)(() => {
|
|
109
|
+
var _a;
|
|
110
|
+
const cached = src ? ((_a = cache.get(src)) !== null && _a !== void 0 ? _a : null) : null;
|
|
111
|
+
setMediaMetadata(cached);
|
|
112
|
+
if (!src || cached) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
let cancelled = false;
|
|
116
|
+
(0, exports.getMediaMetadata)(src)
|
|
117
|
+
.then((metadata) => {
|
|
118
|
+
if (cancelled) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
setMediaMetadata(metadata);
|
|
122
|
+
})
|
|
123
|
+
.catch(() => {
|
|
124
|
+
if (cancelled) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
setMediaMetadata(null);
|
|
128
|
+
});
|
|
129
|
+
return () => {
|
|
130
|
+
cancelled = true;
|
|
131
|
+
};
|
|
132
|
+
}, [src]);
|
|
133
|
+
return mediaMetadata;
|
|
134
|
+
};
|
|
135
|
+
exports.useMediaMetadata = useMediaMetadata;
|