@remotion/media 4.0.489 → 4.0.491
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/esm/index.mjs +207 -83
- package/dist/get-shared-input.d.ts +11 -0
- package/dist/media-player.d.ts +4 -0
- package/dist/prores-error.d.ts +4 -0
- package/dist/video-extraction/add-broadcast-channel-listener.d.ts +4 -0
- package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +3 -0
- package/dist/video-extraction/extract-frame.d.ts +3 -0
- package/dist/video-extraction/get-frames-since-keyframe.d.ts +1 -1
- package/package.json +4 -4
package/dist/esm/index.mjs
CHANGED
|
@@ -136,7 +136,6 @@ var calculateEndTime = ({
|
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
// src/media-player.ts
|
|
139
|
-
import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
|
|
140
139
|
import { Internals as Internals5 } from "remotion";
|
|
141
140
|
|
|
142
141
|
// src/audio-iterator-manager.ts
|
|
@@ -853,6 +852,127 @@ var getDurationOrCompute = async (input) => {
|
|
|
853
852
|
}) ?? input.computeDuration(undefined, { skipLiveWait: true });
|
|
854
853
|
};
|
|
855
854
|
|
|
855
|
+
// src/get-shared-input.ts
|
|
856
|
+
import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
|
|
857
|
+
|
|
858
|
+
// src/request-init.ts
|
|
859
|
+
var normalizeMediaHeaders = (headers) => {
|
|
860
|
+
if (!headers) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const entries = [];
|
|
864
|
+
if (headers instanceof Headers) {
|
|
865
|
+
headers.forEach((value, key) => {
|
|
866
|
+
entries.push([key.toLowerCase(), value]);
|
|
867
|
+
});
|
|
868
|
+
} else if (Array.isArray(headers)) {
|
|
869
|
+
for (const [key, value] of headers) {
|
|
870
|
+
entries.push([key.toLowerCase(), value]);
|
|
871
|
+
}
|
|
872
|
+
} else {
|
|
873
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
874
|
+
entries.push([key.toLowerCase(), value]);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
878
|
+
return entries;
|
|
879
|
+
};
|
|
880
|
+
var normalizeMediaRequestInit = (requestInit) => {
|
|
881
|
+
if (!requestInit) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
const headers = normalizeMediaHeaders(requestInit.headers);
|
|
885
|
+
const normalized = {
|
|
886
|
+
...requestInit.cache === undefined ? null : { cache: requestInit.cache },
|
|
887
|
+
...requestInit.credentials === undefined ? null : { credentials: requestInit.credentials },
|
|
888
|
+
...headers === undefined ? null : { headers },
|
|
889
|
+
...requestInit.integrity === undefined ? null : { integrity: requestInit.integrity },
|
|
890
|
+
...requestInit.mode === undefined ? null : { mode: requestInit.mode },
|
|
891
|
+
...requestInit.redirect === undefined ? null : { redirect: requestInit.redirect },
|
|
892
|
+
...requestInit.referrer === undefined ? null : { referrer: requestInit.referrer },
|
|
893
|
+
...requestInit.referrerPolicy === undefined ? null : { referrerPolicy: requestInit.referrerPolicy }
|
|
894
|
+
};
|
|
895
|
+
return Object.keys(normalized).length === 0 ? undefined : normalized;
|
|
896
|
+
};
|
|
897
|
+
var getMediaRequestInitFingerprint = (requestInit) => {
|
|
898
|
+
const normalized = normalizeMediaRequestInit(requestInit);
|
|
899
|
+
if (!normalized) {
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
return [
|
|
903
|
+
normalized.cache ?? null,
|
|
904
|
+
normalized.credentials ?? null,
|
|
905
|
+
normalized.integrity ?? null,
|
|
906
|
+
normalized.mode ?? null,
|
|
907
|
+
normalized.redirect ?? null,
|
|
908
|
+
normalized.referrer ?? null,
|
|
909
|
+
normalized.referrerPolicy ?? null,
|
|
910
|
+
normalized.headers ?? null
|
|
911
|
+
];
|
|
912
|
+
};
|
|
913
|
+
var resolveRequestInit = ({
|
|
914
|
+
credentials,
|
|
915
|
+
requestInit
|
|
916
|
+
}) => {
|
|
917
|
+
if (credentials === undefined) {
|
|
918
|
+
return normalizeMediaRequestInit(requestInit);
|
|
919
|
+
}
|
|
920
|
+
return normalizeMediaRequestInit({
|
|
921
|
+
credentials,
|
|
922
|
+
...requestInit
|
|
923
|
+
});
|
|
924
|
+
};
|
|
925
|
+
|
|
926
|
+
// src/get-shared-input.ts
|
|
927
|
+
var sharedInputs = {};
|
|
928
|
+
var getSharedInputCacheKey = ({
|
|
929
|
+
src,
|
|
930
|
+
credentials,
|
|
931
|
+
requestInit
|
|
932
|
+
}) => JSON.stringify([
|
|
933
|
+
src,
|
|
934
|
+
credentials ?? null,
|
|
935
|
+
getMediaRequestInitFingerprint(requestInit)
|
|
936
|
+
]);
|
|
937
|
+
var acquireSharedInput = ({
|
|
938
|
+
src,
|
|
939
|
+
credentials,
|
|
940
|
+
requestInit
|
|
941
|
+
}) => {
|
|
942
|
+
const normalizedRequestInit = normalizeMediaRequestInit(requestInit);
|
|
943
|
+
const cacheKey = getSharedInputCacheKey({
|
|
944
|
+
src,
|
|
945
|
+
credentials,
|
|
946
|
+
requestInit: normalizedRequestInit
|
|
947
|
+
});
|
|
948
|
+
const existing = sharedInputs[cacheKey];
|
|
949
|
+
if (existing) {
|
|
950
|
+
existing.refCount++;
|
|
951
|
+
return { input: existing.input, cacheKey };
|
|
952
|
+
}
|
|
953
|
+
const resolvedRequestInit = resolveRequestInit({
|
|
954
|
+
credentials,
|
|
955
|
+
requestInit: normalizedRequestInit
|
|
956
|
+
});
|
|
957
|
+
const input = new Input({
|
|
958
|
+
source: new UrlSource(src, resolvedRequestInit ? { requestInit: resolvedRequestInit } : undefined),
|
|
959
|
+
formats: ALL_FORMATS
|
|
960
|
+
});
|
|
961
|
+
sharedInputs[cacheKey] = { input, refCount: 1 };
|
|
962
|
+
return { input, cacheKey };
|
|
963
|
+
};
|
|
964
|
+
var releaseSharedInput = (cacheKey) => {
|
|
965
|
+
const entry = sharedInputs[cacheKey];
|
|
966
|
+
if (!entry) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
entry.refCount--;
|
|
970
|
+
if (entry.refCount <= 0) {
|
|
971
|
+
delete sharedInputs[cacheKey];
|
|
972
|
+
entry.input.dispose();
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
|
|
856
976
|
// src/helpers/resolve-audio-track.ts
|
|
857
977
|
var resolveAudioTrack = async ({
|
|
858
978
|
videoTrack,
|
|
@@ -972,74 +1092,6 @@ class PremountAwareDelayPlayback {
|
|
|
972
1092
|
}
|
|
973
1093
|
}
|
|
974
1094
|
|
|
975
|
-
// src/request-init.ts
|
|
976
|
-
var normalizeMediaHeaders = (headers) => {
|
|
977
|
-
if (!headers) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
const entries = [];
|
|
981
|
-
if (headers instanceof Headers) {
|
|
982
|
-
headers.forEach((value, key) => {
|
|
983
|
-
entries.push([key.toLowerCase(), value]);
|
|
984
|
-
});
|
|
985
|
-
} else if (Array.isArray(headers)) {
|
|
986
|
-
for (const [key, value] of headers) {
|
|
987
|
-
entries.push([key.toLowerCase(), value]);
|
|
988
|
-
}
|
|
989
|
-
} else {
|
|
990
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
991
|
-
entries.push([key.toLowerCase(), value]);
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
995
|
-
return entries;
|
|
996
|
-
};
|
|
997
|
-
var normalizeMediaRequestInit = (requestInit) => {
|
|
998
|
-
if (!requestInit) {
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
const headers = normalizeMediaHeaders(requestInit.headers);
|
|
1002
|
-
const normalized = {
|
|
1003
|
-
...requestInit.cache === undefined ? null : { cache: requestInit.cache },
|
|
1004
|
-
...requestInit.credentials === undefined ? null : { credentials: requestInit.credentials },
|
|
1005
|
-
...headers === undefined ? null : { headers },
|
|
1006
|
-
...requestInit.integrity === undefined ? null : { integrity: requestInit.integrity },
|
|
1007
|
-
...requestInit.mode === undefined ? null : { mode: requestInit.mode },
|
|
1008
|
-
...requestInit.redirect === undefined ? null : { redirect: requestInit.redirect },
|
|
1009
|
-
...requestInit.referrer === undefined ? null : { referrer: requestInit.referrer },
|
|
1010
|
-
...requestInit.referrerPolicy === undefined ? null : { referrerPolicy: requestInit.referrerPolicy }
|
|
1011
|
-
};
|
|
1012
|
-
return Object.keys(normalized).length === 0 ? undefined : normalized;
|
|
1013
|
-
};
|
|
1014
|
-
var getMediaRequestInitFingerprint = (requestInit) => {
|
|
1015
|
-
const normalized = normalizeMediaRequestInit(requestInit);
|
|
1016
|
-
if (!normalized) {
|
|
1017
|
-
return null;
|
|
1018
|
-
}
|
|
1019
|
-
return [
|
|
1020
|
-
normalized.cache ?? null,
|
|
1021
|
-
normalized.credentials ?? null,
|
|
1022
|
-
normalized.integrity ?? null,
|
|
1023
|
-
normalized.mode ?? null,
|
|
1024
|
-
normalized.redirect ?? null,
|
|
1025
|
-
normalized.referrer ?? null,
|
|
1026
|
-
normalized.referrerPolicy ?? null,
|
|
1027
|
-
normalized.headers ?? null
|
|
1028
|
-
];
|
|
1029
|
-
};
|
|
1030
|
-
var resolveRequestInit = ({
|
|
1031
|
-
credentials,
|
|
1032
|
-
requestInit
|
|
1033
|
-
}) => {
|
|
1034
|
-
if (credentials === undefined) {
|
|
1035
|
-
return normalizeMediaRequestInit(requestInit);
|
|
1036
|
-
}
|
|
1037
|
-
return normalizeMediaRequestInit({
|
|
1038
|
-
credentials,
|
|
1039
|
-
...requestInit
|
|
1040
|
-
});
|
|
1041
|
-
};
|
|
1042
|
-
|
|
1043
1095
|
// src/video-iterator-manager.ts
|
|
1044
1096
|
import { CanvasSink } from "mediabunny";
|
|
1045
1097
|
import { Internals as Internals4 } from "remotion";
|
|
@@ -1070,6 +1122,7 @@ var makeStableFramePool = () => {
|
|
|
1070
1122
|
if (!context) {
|
|
1071
1123
|
throw new Error("Could not create canvas context");
|
|
1072
1124
|
}
|
|
1125
|
+
context.clearRect(0, 0, stableCanvas.width, stableCanvas.height);
|
|
1073
1126
|
context.drawImage(canvas, 0, 0);
|
|
1074
1127
|
let released = false;
|
|
1075
1128
|
const stableFrame = {
|
|
@@ -1659,13 +1712,13 @@ class MediaPlayer {
|
|
|
1659
1712
|
this.onVideoFrameCallback = onVideoFrameCallback;
|
|
1660
1713
|
this.playing = playing;
|
|
1661
1714
|
this.sequenceOffset = sequenceOffset;
|
|
1662
|
-
const
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
} : undefined),
|
|
1667
|
-
formats: ALL_FORMATS
|
|
1715
|
+
const { input, cacheKey } = acquireSharedInput({
|
|
1716
|
+
src: this.src,
|
|
1717
|
+
credentials,
|
|
1718
|
+
requestInit
|
|
1668
1719
|
});
|
|
1720
|
+
this.input = input;
|
|
1721
|
+
this.inputCacheKey = cacheKey;
|
|
1669
1722
|
this.tagType = tagType;
|
|
1670
1723
|
this.getEffects = getEffects;
|
|
1671
1724
|
this.getEffectChainState = getEffectChainState;
|
|
@@ -1683,8 +1736,10 @@ class MediaPlayer {
|
|
|
1683
1736
|
}
|
|
1684
1737
|
}
|
|
1685
1738
|
input;
|
|
1739
|
+
inputCacheKey;
|
|
1740
|
+
disposed = false;
|
|
1686
1741
|
isDisposalError() {
|
|
1687
|
-
return this.input.disposed === true;
|
|
1742
|
+
return this.disposed || this.input.disposed === true;
|
|
1688
1743
|
}
|
|
1689
1744
|
initialize(startTimeUnresolved, initialMuted) {
|
|
1690
1745
|
const promise = this._initialize(startTimeUnresolved, initialMuted);
|
|
@@ -1719,7 +1774,7 @@ class MediaPlayer {
|
|
|
1719
1774
|
try {
|
|
1720
1775
|
const _ = __using(__stack, this.delayPlaybackHandleIfNotPremounting(), 0);
|
|
1721
1776
|
try {
|
|
1722
|
-
if (this.
|
|
1777
|
+
if (this.isDisposalError()) {
|
|
1723
1778
|
return { type: "disposed" };
|
|
1724
1779
|
}
|
|
1725
1780
|
try {
|
|
@@ -1740,7 +1795,7 @@ class MediaPlayer {
|
|
|
1740
1795
|
this.input.getPrimaryVideoTrack(),
|
|
1741
1796
|
this.input.getAudioTracks()
|
|
1742
1797
|
]);
|
|
1743
|
-
if (this.
|
|
1798
|
+
if (this.isDisposalError()) {
|
|
1744
1799
|
return { type: "disposed" };
|
|
1745
1800
|
}
|
|
1746
1801
|
this.totalDuration = durationInSeconds;
|
|
@@ -1761,9 +1816,12 @@ class MediaPlayer {
|
|
|
1761
1816
|
}
|
|
1762
1817
|
const canDecode = await videoTrack.canDecode();
|
|
1763
1818
|
if (!canDecode) {
|
|
1819
|
+
if (videoTrack.codec === "prores") {
|
|
1820
|
+
return { type: "cannot-decode-prores" };
|
|
1821
|
+
}
|
|
1764
1822
|
return { type: "cannot-decode" };
|
|
1765
1823
|
}
|
|
1766
|
-
if (this.
|
|
1824
|
+
if (this.isDisposalError()) {
|
|
1767
1825
|
return { type: "disposed" };
|
|
1768
1826
|
}
|
|
1769
1827
|
this.videoIteratorManager = await videoIteratorManager({
|
|
@@ -1796,7 +1854,7 @@ class MediaPlayer {
|
|
|
1796
1854
|
if (!canDecode) {
|
|
1797
1855
|
return { type: "cannot-decode" };
|
|
1798
1856
|
}
|
|
1799
|
-
if (this.
|
|
1857
|
+
if (this.isDisposalError()) {
|
|
1800
1858
|
return { type: "disposed" };
|
|
1801
1859
|
}
|
|
1802
1860
|
this.audioIteratorManager = audioIteratorManager({
|
|
@@ -2015,6 +2073,10 @@ class MediaPlayer {
|
|
|
2015
2073
|
}
|
|
2016
2074
|
}
|
|
2017
2075
|
async dispose() {
|
|
2076
|
+
if (this.disposed) {
|
|
2077
|
+
return;
|
|
2078
|
+
}
|
|
2079
|
+
this.disposed = true;
|
|
2018
2080
|
if (this.initializationPromise) {
|
|
2019
2081
|
try {
|
|
2020
2082
|
await this.initializationPromise;
|
|
@@ -2023,7 +2085,7 @@ class MediaPlayer {
|
|
|
2023
2085
|
this.nonceManager.createAsyncOperation();
|
|
2024
2086
|
this.videoIteratorManager?.destroy();
|
|
2025
2087
|
this.audioIteratorManager?.destroyIterator();
|
|
2026
|
-
this.
|
|
2088
|
+
releaseSharedInput(this.inputCacheKey);
|
|
2027
2089
|
}
|
|
2028
2090
|
getTargetTime = (mediaTimestamp, currentTime) => {
|
|
2029
2091
|
if (!this.sharedAudioContext) {
|
|
@@ -2475,6 +2537,9 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2475
2537
|
handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
|
|
2476
2538
|
return;
|
|
2477
2539
|
}
|
|
2540
|
+
if (result.type === "cannot-decode-prores") {
|
|
2541
|
+
throw new Error(`Encountered ProRes media for ${preloadedSrc}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
2542
|
+
}
|
|
2478
2543
|
if (result.type === "success") {
|
|
2479
2544
|
setMediaPlayerReady(true);
|
|
2480
2545
|
setMediaDurationInSeconds(result.durationInSeconds);
|
|
@@ -3858,6 +3923,9 @@ var getSinks = async (src, logLevel, credentials, requestInit) => {
|
|
|
3858
3923
|
}
|
|
3859
3924
|
const canDecode = await videoTrack.canDecode();
|
|
3860
3925
|
if (!canDecode) {
|
|
3926
|
+
if (videoTrack.codec === "prores") {
|
|
3927
|
+
return "cannot-decode-prores";
|
|
3928
|
+
}
|
|
3861
3929
|
return "cannot-decode";
|
|
3862
3930
|
}
|
|
3863
3931
|
const sampleSink = new VideoSampleSink(videoTrack);
|
|
@@ -4116,6 +4184,12 @@ var extractFrameInternal = async ({
|
|
|
4116
4184
|
if (video === "cannot-decode") {
|
|
4117
4185
|
return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
|
|
4118
4186
|
}
|
|
4187
|
+
if (video === "cannot-decode-prores") {
|
|
4188
|
+
return {
|
|
4189
|
+
type: "cannot-decode-prores",
|
|
4190
|
+
durationInSeconds: mediaDurationInSeconds
|
|
4191
|
+
};
|
|
4192
|
+
}
|
|
4119
4193
|
if (video === "unknown-container-format") {
|
|
4120
4194
|
return { type: "unknown-container-format" };
|
|
4121
4195
|
}
|
|
@@ -4271,6 +4345,12 @@ var extractFrameAndAudio = async ({
|
|
|
4271
4345
|
durationInSeconds: video.durationInSeconds
|
|
4272
4346
|
};
|
|
4273
4347
|
}
|
|
4348
|
+
if (video?.type === "cannot-decode-prores") {
|
|
4349
|
+
return {
|
|
4350
|
+
type: "cannot-decode-prores",
|
|
4351
|
+
durationInSeconds: video.durationInSeconds
|
|
4352
|
+
};
|
|
4353
|
+
}
|
|
4274
4354
|
if (video?.type === "unknown-container-format") {
|
|
4275
4355
|
return { type: "unknown-container-format" };
|
|
4276
4356
|
}
|
|
@@ -4358,6 +4438,15 @@ var addBroadcastChannelListener = () => {
|
|
|
4358
4438
|
window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
|
|
4359
4439
|
return;
|
|
4360
4440
|
}
|
|
4441
|
+
if (result.type === "cannot-decode-prores") {
|
|
4442
|
+
const cannotDecodeProresResponse = {
|
|
4443
|
+
type: "response-cannot-decode-prores",
|
|
4444
|
+
id: data.id,
|
|
4445
|
+
durationInSeconds: result.durationInSeconds
|
|
4446
|
+
};
|
|
4447
|
+
window.remotion_broadcastChannel.postMessage(cannotDecodeProresResponse);
|
|
4448
|
+
return;
|
|
4449
|
+
}
|
|
4361
4450
|
if (result.type === "cannot-decode-alpha") {
|
|
4362
4451
|
const cannotDecodeAlphaResponse = {
|
|
4363
4452
|
type: "response-cannot-decode-alpha",
|
|
@@ -4504,6 +4593,14 @@ var extractFrameViaBroadcastChannel = async ({
|
|
|
4504
4593
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
4505
4594
|
return;
|
|
4506
4595
|
}
|
|
4596
|
+
if (data.type === "response-cannot-decode-prores") {
|
|
4597
|
+
resolve({
|
|
4598
|
+
type: "cannot-decode-prores",
|
|
4599
|
+
durationInSeconds: data.durationInSeconds
|
|
4600
|
+
});
|
|
4601
|
+
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4507
4604
|
if (data.type === "response-network-error") {
|
|
4508
4605
|
resolve({ type: "network-error" });
|
|
4509
4606
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
@@ -4677,6 +4774,9 @@ var AudioForRendering = ({
|
|
|
4677
4774
|
if (result.type === "cannot-decode-alpha") {
|
|
4678
4775
|
throw new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToHtml5Audio' was set. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
4679
4776
|
}
|
|
4777
|
+
if (result.type === "cannot-decode-prores") {
|
|
4778
|
+
throw new Error(`Encountered ProRes media for ${src}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
4779
|
+
}
|
|
4680
4780
|
if (result.type === "network-error") {
|
|
4681
4781
|
handleError(new Error(`Network error fetching ${src}.`), new Error(`Cannot render audio "${src}": Network error while fetching the audio (possibly CORS).`), `Network error fetching ${src}, falling back to <Html5Audio>`);
|
|
4682
4782
|
return;
|
|
@@ -4886,7 +4986,6 @@ var Audio = Interactive.withSchema({
|
|
|
4886
4986
|
schema: audioSchema,
|
|
4887
4987
|
supportsEffects: false
|
|
4888
4988
|
});
|
|
4889
|
-
Internals17.addSequenceStackTraces(Audio);
|
|
4890
4989
|
|
|
4891
4990
|
// src/video/video.tsx
|
|
4892
4991
|
import React6, { useMemo as useMemo6, useState as useState6 } from "react";
|
|
@@ -4916,6 +5015,19 @@ import {
|
|
|
4916
5015
|
useVideoConfig as useVideoConfig3
|
|
4917
5016
|
} from "remotion";
|
|
4918
5017
|
|
|
5018
|
+
// src/prores-error.ts
|
|
5019
|
+
var PRORES_DOCS_URL = "https://www.remotion.dev/docs/videos/prores";
|
|
5020
|
+
var proresDecoderNotEnabledMessage = (src) => {
|
|
5021
|
+
return `Cannot decode "${src}": it is encoded with Apple ProRes, which WebCodecs does not support natively. ` + `ProRes decoding is not enabled by default. Register the ProRes decoder by calling ` + `registerProresDecoder() from "@mediabunny/prores" in your entry point, before registerRoot(). ` + `See ${PRORES_DOCS_URL}. ` + `(This is required to decode a ProRes source for both preview and rendering — it is unrelated to exporting a video as ProRes.)`;
|
|
5022
|
+
};
|
|
5023
|
+
|
|
5024
|
+
class ProResDecoderNotEnabledError extends Error {
|
|
5025
|
+
constructor(src) {
|
|
5026
|
+
super(proresDecoderNotEnabledMessage(src));
|
|
5027
|
+
this.name = "ProResDecoderNotEnabledError";
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
|
|
4919
5031
|
// src/video/video-frame-cache.ts
|
|
4920
5032
|
var cache = new Map;
|
|
4921
5033
|
var cacheVideoFrame = (src, sourceCanvas) => {
|
|
@@ -5171,6 +5283,9 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5171
5283
|
handleError(new Error(`Cannot decode ${preloadedSrc}.`), `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
5172
5284
|
return;
|
|
5173
5285
|
}
|
|
5286
|
+
if (result.type === "cannot-decode-prores") {
|
|
5287
|
+
throw new ProResDecoderNotEnabledError(preloadedSrc);
|
|
5288
|
+
}
|
|
5174
5289
|
if (result.type === "no-tracks") {
|
|
5175
5290
|
handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
5176
5291
|
return;
|
|
@@ -5181,6 +5296,10 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5181
5296
|
hasDrawnRealFrameRef.current = true;
|
|
5182
5297
|
}
|
|
5183
5298
|
}).catch((error) => {
|
|
5299
|
+
if (error instanceof ProResDecoderNotEnabledError) {
|
|
5300
|
+
onErrorRef.current?.(error);
|
|
5301
|
+
throw error;
|
|
5302
|
+
}
|
|
5184
5303
|
const [action, errorToUse] = callOnErrorAndResolve({
|
|
5185
5304
|
onError: onErrorRef.current,
|
|
5186
5305
|
error,
|
|
@@ -5497,6 +5616,12 @@ var VideoForRendering = ({
|
|
|
5497
5616
|
handleError(new Error(`Cannot decode ${src}.`), new Error(`Cannot render video "${src}": The video could not be decoded by the browser.`), `Cannot decode ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
|
|
5498
5617
|
return;
|
|
5499
5618
|
}
|
|
5619
|
+
if (result.type === "cannot-decode-prores") {
|
|
5620
|
+
const proresError = new ProResDecoderNotEnabledError(src);
|
|
5621
|
+
onError?.(proresError);
|
|
5622
|
+
cancelRender3(proresError);
|
|
5623
|
+
return;
|
|
5624
|
+
}
|
|
5500
5625
|
if (result.type === "cannot-decode-alpha") {
|
|
5501
5626
|
handleError(new Error(`Cannot decode alpha component for ${src}.`), new Error(`Cannot render video "${src}": The alpha channel could not be decoded by the browser.`), `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
|
|
5502
5627
|
return;
|
|
@@ -5974,7 +6099,6 @@ var Video = Interactive2.withSchema({
|
|
|
5974
6099
|
schema: videoSchema,
|
|
5975
6100
|
supportsEffects: true
|
|
5976
6101
|
});
|
|
5977
|
-
Internals21.addSequenceStackTraces(Video);
|
|
5978
6102
|
|
|
5979
6103
|
// src/index.ts
|
|
5980
6104
|
var experimental_Audio = Audio;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Input } from 'mediabunny';
|
|
2
|
+
import { type MediaRequestInit } from './request-init';
|
|
3
|
+
export declare const acquireSharedInput: ({ src, credentials, requestInit, }: {
|
|
4
|
+
src: string;
|
|
5
|
+
credentials: RequestCredentials | undefined;
|
|
6
|
+
requestInit: MediaRequestInit | undefined;
|
|
7
|
+
}) => {
|
|
8
|
+
input: Input<import("mediabunny").Source>;
|
|
9
|
+
cacheKey: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const releaseSharedInput: (cacheKey: string) => void;
|
package/dist/media-player.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type MediaPlayerInitResult = {
|
|
|
10
10
|
type: 'unknown-container-format';
|
|
11
11
|
} | {
|
|
12
12
|
type: 'cannot-decode';
|
|
13
|
+
} | {
|
|
14
|
+
type: 'cannot-decode-prores';
|
|
13
15
|
} | {
|
|
14
16
|
type: 'network-error';
|
|
15
17
|
} | {
|
|
@@ -72,6 +74,8 @@ export declare class MediaPlayer {
|
|
|
72
74
|
getEffectChainState: (width: number, height: number) => EffectChainState | null;
|
|
73
75
|
});
|
|
74
76
|
private input;
|
|
77
|
+
private inputCacheKey;
|
|
78
|
+
private disposed;
|
|
75
79
|
private isDisposalError;
|
|
76
80
|
initialize(startTimeUnresolved: number, initialMuted: boolean): Promise<MediaPlayerInitResult>;
|
|
77
81
|
private getStartTime;
|
|
@@ -15,6 +15,10 @@ export type MessageFromMainTab = {
|
|
|
15
15
|
type: 'response-cannot-decode';
|
|
16
16
|
id: string;
|
|
17
17
|
durationInSeconds: number | null;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'response-cannot-decode-prores';
|
|
20
|
+
id: string;
|
|
21
|
+
durationInSeconds: number | null;
|
|
18
22
|
} | {
|
|
19
23
|
type: 'response-cannot-decode-alpha';
|
|
20
24
|
id: string;
|
|
@@ -8,6 +8,9 @@ export type ExtractFrameViaBroadcastChannelResult = {
|
|
|
8
8
|
} | {
|
|
9
9
|
type: 'cannot-decode';
|
|
10
10
|
durationInSeconds: number | null;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'cannot-decode-prores';
|
|
13
|
+
durationInSeconds: number | null;
|
|
11
14
|
} | {
|
|
12
15
|
type: 'cannot-decode-alpha';
|
|
13
16
|
durationInSeconds: number | null;
|
|
@@ -7,7 +7,7 @@ type AudioSinks = {
|
|
|
7
7
|
sampleSink: AudioSampleSink;
|
|
8
8
|
};
|
|
9
9
|
export type AudioSinkResult = AudioSinks | 'no-audio-track' | 'cannot-decode-audio' | 'unknown-container-format' | 'network-error';
|
|
10
|
-
export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
|
|
10
|
+
export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-prores' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
|
|
11
11
|
export declare const getSinks: (src: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn", credentials: RequestCredentials | undefined, requestInit?: MediaRequestInit | undefined) => Promise<{
|
|
12
12
|
getVideo: () => Promise<VideoSinkResult>;
|
|
13
13
|
getAudio: (index: number | null) => Promise<AudioSinkResult>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.491",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"mediabunny": "1.50.8",
|
|
26
|
-
"remotion": "4.0.
|
|
26
|
+
"remotion": "4.0.491",
|
|
27
27
|
"zod": "4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"react-dom": ">=16.8.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
35
|
-
"@remotion/player": "4.0.
|
|
34
|
+
"@remotion/eslint-config-internal": "4.0.491",
|
|
35
|
+
"@remotion/player": "4.0.491",
|
|
36
36
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
37
37
|
"eslint": "9.19.0",
|
|
38
38
|
"react": "19.2.3",
|