@remotion/media 4.0.488 → 4.0.490

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.
@@ -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";
@@ -1659,13 +1711,13 @@ class MediaPlayer {
1659
1711
  this.onVideoFrameCallback = onVideoFrameCallback;
1660
1712
  this.playing = playing;
1661
1713
  this.sequenceOffset = sequenceOffset;
1662
- const resolvedRequestInit = resolveRequestInit({ credentials, requestInit });
1663
- this.input = new Input({
1664
- source: new UrlSource(this.src, resolvedRequestInit ? {
1665
- requestInit: resolvedRequestInit
1666
- } : undefined),
1667
- formats: ALL_FORMATS
1714
+ const { input, cacheKey } = acquireSharedInput({
1715
+ src: this.src,
1716
+ credentials,
1717
+ requestInit
1668
1718
  });
1719
+ this.input = input;
1720
+ this.inputCacheKey = cacheKey;
1669
1721
  this.tagType = tagType;
1670
1722
  this.getEffects = getEffects;
1671
1723
  this.getEffectChainState = getEffectChainState;
@@ -1683,8 +1735,10 @@ class MediaPlayer {
1683
1735
  }
1684
1736
  }
1685
1737
  input;
1738
+ inputCacheKey;
1739
+ disposed = false;
1686
1740
  isDisposalError() {
1687
- return this.input.disposed === true;
1741
+ return this.disposed || this.input.disposed === true;
1688
1742
  }
1689
1743
  initialize(startTimeUnresolved, initialMuted) {
1690
1744
  const promise = this._initialize(startTimeUnresolved, initialMuted);
@@ -1719,7 +1773,7 @@ class MediaPlayer {
1719
1773
  try {
1720
1774
  const _ = __using(__stack, this.delayPlaybackHandleIfNotPremounting(), 0);
1721
1775
  try {
1722
- if (this.input.disposed) {
1776
+ if (this.isDisposalError()) {
1723
1777
  return { type: "disposed" };
1724
1778
  }
1725
1779
  try {
@@ -1740,7 +1794,7 @@ class MediaPlayer {
1740
1794
  this.input.getPrimaryVideoTrack(),
1741
1795
  this.input.getAudioTracks()
1742
1796
  ]);
1743
- if (this.input.disposed) {
1797
+ if (this.isDisposalError()) {
1744
1798
  return { type: "disposed" };
1745
1799
  }
1746
1800
  this.totalDuration = durationInSeconds;
@@ -1763,7 +1817,7 @@ class MediaPlayer {
1763
1817
  if (!canDecode) {
1764
1818
  return { type: "cannot-decode" };
1765
1819
  }
1766
- if (this.input.disposed) {
1820
+ if (this.isDisposalError()) {
1767
1821
  return { type: "disposed" };
1768
1822
  }
1769
1823
  this.videoIteratorManager = await videoIteratorManager({
@@ -1796,7 +1850,7 @@ class MediaPlayer {
1796
1850
  if (!canDecode) {
1797
1851
  return { type: "cannot-decode" };
1798
1852
  }
1799
- if (this.input.disposed) {
1853
+ if (this.isDisposalError()) {
1800
1854
  return { type: "disposed" };
1801
1855
  }
1802
1856
  this.audioIteratorManager = audioIteratorManager({
@@ -2015,6 +2069,10 @@ class MediaPlayer {
2015
2069
  }
2016
2070
  }
2017
2071
  async dispose() {
2072
+ if (this.disposed) {
2073
+ return;
2074
+ }
2075
+ this.disposed = true;
2018
2076
  if (this.initializationPromise) {
2019
2077
  try {
2020
2078
  await this.initializationPromise;
@@ -2023,7 +2081,7 @@ class MediaPlayer {
2023
2081
  this.nonceManager.createAsyncOperation();
2024
2082
  this.videoIteratorManager?.destroy();
2025
2083
  this.audioIteratorManager?.destroyIterator();
2026
- this.input.dispose();
2084
+ releaseSharedInput(this.inputCacheKey);
2027
2085
  }
2028
2086
  getTargetTime = (mediaTimestamp, currentTime) => {
2029
2087
  if (!this.sharedAudioContext) {
@@ -4886,7 +4944,6 @@ var Audio = Interactive.withSchema({
4886
4944
  schema: audioSchema,
4887
4945
  supportsEffects: false
4888
4946
  });
4889
- Internals17.addSequenceStackTraces(Audio);
4890
4947
 
4891
4948
  // src/video/video.tsx
4892
4949
  import React6, { useMemo as useMemo6, useState as useState6 } from "react";
@@ -5974,7 +6031,6 @@ var Video = Interactive2.withSchema({
5974
6031
  schema: videoSchema,
5975
6032
  supportsEffects: true
5976
6033
  });
5977
- Internals21.addSequenceStackTraces(Video);
5978
6034
 
5979
6035
  // src/index.ts
5980
6036
  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;
@@ -72,6 +72,8 @@ export declare class MediaPlayer {
72
72
  getEffectChainState: (width: number, height: number) => EffectChainState | null;
73
73
  });
74
74
  private input;
75
+ private inputCacheKey;
76
+ private disposed;
75
77
  private isDisposalError;
76
78
  initialize(startTimeUnresolved: number, initialMuted: boolean): Promise<MediaPlayerInitResult>;
77
79
  private getStartTime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.488",
3
+ "version": "4.0.490",
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.488",
26
+ "remotion": "4.0.490",
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.488",
35
- "@remotion/player": "4.0.488",
34
+ "@remotion/eslint-config-internal": "4.0.490",
35
+ "@remotion/player": "4.0.490",
36
36
  "@vitest/browser-webdriverio": "4.0.9",
37
37
  "eslint": "9.19.0",
38
38
  "react": "19.2.3",