@remotion/media 4.0.403 → 4.0.404

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/audio/audio-for-preview.d.ts +2 -0
  2. package/dist/audio/audio-preview-iterator.d.ts +8 -3
  3. package/dist/audio/props.d.ts +2 -0
  4. package/dist/audio-extraction/audio-iterator.d.ts +5 -4
  5. package/dist/audio-extraction/audio-manager.d.ts +23 -7
  6. package/dist/audio-extraction/extract-audio.d.ts +2 -4
  7. package/dist/audio-iterator-manager.d.ts +2 -2
  8. package/dist/caches.d.ts +29 -11
  9. package/dist/convert-audiodata/apply-volume.d.ts +1 -1
  10. package/dist/convert-audiodata/resample-audiodata.d.ts +2 -2
  11. package/dist/debug-overlay/preview-overlay.d.ts +83 -5
  12. package/dist/esm/index.mjs +180 -146
  13. package/dist/extract-frame-and-audio.d.ts +1 -2
  14. package/dist/get-sink.d.ts +1 -2
  15. package/dist/index.d.ts +2 -1
  16. package/dist/media-player.d.ts +1 -1
  17. package/dist/on-error.d.ts +12 -0
  18. package/dist/show-in-timeline.d.ts +2 -2
  19. package/dist/use-media-in-timeline.d.ts +2 -2
  20. package/dist/video/props.d.ts +5 -0
  21. package/dist/video/video-for-preview.d.ts +2 -0
  22. package/dist/video/video-for-rendering.d.ts +2 -0
  23. package/dist/video/video-preview-iterator.d.ts +7 -2
  24. package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +1 -2
  25. package/dist/video-extraction/extract-frame.d.ts +1 -3
  26. package/dist/video-extraction/keyframe-bank.d.ts +2 -2
  27. package/dist/video-extraction/keyframe-manager.d.ts +2 -3
  28. package/dist/video-iterator-manager.d.ts +4 -5
  29. package/package.json +8 -7
  30. package/dist/audio/allow-wait.js +0 -15
  31. package/dist/audio/audio-for-preview.js +0 -302
  32. package/dist/audio/audio-for-rendering.js +0 -196
  33. package/dist/audio/audio-preview-iterator.js +0 -176
  34. package/dist/audio/audio.js +0 -20
  35. package/dist/audio/props.js +0 -1
  36. package/dist/audio-extraction/audio-cache.js +0 -66
  37. package/dist/audio-extraction/audio-iterator.js +0 -132
  38. package/dist/audio-extraction/audio-manager.js +0 -121
  39. package/dist/audio-extraction/extract-audio.js +0 -132
  40. package/dist/audio-iterator-manager.js +0 -228
  41. package/dist/browser-can-use-webgl2.js +0 -13
  42. package/dist/caches.js +0 -61
  43. package/dist/calculate-playbacktime.js +0 -4
  44. package/dist/convert-audiodata/apply-volume.js +0 -17
  45. package/dist/convert-audiodata/combine-audiodata.js +0 -23
  46. package/dist/convert-audiodata/convert-audiodata.js +0 -73
  47. package/dist/convert-audiodata/resample-audiodata.js +0 -94
  48. package/dist/debug-overlay/preview-overlay.js +0 -44
  49. package/dist/extract-frame-and-audio.js +0 -86
  50. package/dist/get-sink.js +0 -15
  51. package/dist/get-time-in-seconds.js +0 -40
  52. package/dist/helpers/round-to-4-digits.js +0 -4
  53. package/dist/index.js +0 -12
  54. package/dist/is-type-of-error.js +0 -20
  55. package/dist/looped-frame.js +0 -10
  56. package/dist/media-player.js +0 -445
  57. package/dist/nonce-manager.js +0 -13
  58. package/dist/prewarm-iterator-for-looping.js +0 -56
  59. package/dist/render-timestamp-range.js +0 -9
  60. package/dist/show-in-timeline.js +0 -31
  61. package/dist/use-media-in-timeline.js +0 -103
  62. package/dist/video/props.js +0 -1
  63. package/dist/video/video-for-preview.js +0 -329
  64. package/dist/video/video-for-rendering.js +0 -263
  65. package/dist/video/video-preview-iterator.js +0 -122
  66. package/dist/video/video.js +0 -33
  67. package/dist/video-extraction/add-broadcast-channel-listener.js +0 -125
  68. package/dist/video-extraction/extract-frame-via-broadcast-channel.js +0 -113
  69. package/dist/video-extraction/extract-frame.js +0 -84
  70. package/dist/video-extraction/get-allocation-size.js +0 -6
  71. package/dist/video-extraction/get-frames-since-keyframe.js +0 -105
  72. package/dist/video-extraction/keyframe-bank.js +0 -200
  73. package/dist/video-extraction/keyframe-manager.js +0 -201
  74. package/dist/video-extraction/remember-actual-matroska-timestamps.js +0 -19
  75. package/dist/video-extraction/rotate-frame.js +0 -34
  76. package/dist/video-iterator-manager.js +0 -109
@@ -1,4 +1,8 @@
1
1
  import type { LogLevel, LoopVolumeCurveBehavior, OnVideoFrame, VolumeProp } from 'remotion';
2
+ import type { MediaOnError } from '../on-error';
3
+ export type MediaErrorEvent = {
4
+ error: Error;
5
+ };
2
6
  export type FallbackOffthreadVideoProps = {
3
7
  acceptableTimeShiftInSeconds?: number;
4
8
  transparent?: boolean;
@@ -39,6 +43,7 @@ type OptionalVideoProps = {
39
43
  showInTimeline: boolean;
40
44
  debugOverlay: boolean;
41
45
  headless: boolean;
46
+ onError: MediaOnError | undefined;
42
47
  };
43
48
  export type InnerVideoProps = MandatoryVideoProps & OuterVideoProps & OptionalVideoProps;
44
49
  export type VideoProps = MandatoryVideoProps & Partial<OuterVideoProps> & Partial<OptionalVideoProps>;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { LogLevel, LoopVolumeCurveBehavior, VolumeProp } from 'remotion';
3
+ import { type MediaOnError } from '../on-error';
3
4
  import type { FallbackOffthreadVideoProps } from './props';
4
5
  type VideoForPreviewProps = {
5
6
  readonly src: string;
@@ -22,6 +23,7 @@ type VideoForPreviewProps = {
22
23
  readonly audioStreamIndex: number;
23
24
  readonly debugOverlay: boolean;
24
25
  readonly headless: boolean;
26
+ readonly onError: MediaOnError | undefined;
25
27
  };
26
28
  export declare const VideoForPreview: React.FC<VideoForPreviewProps>;
27
29
  export {};
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { LogLevel, LoopVolumeCurveBehavior, OnVideoFrame, VolumeProp } from 'remotion';
3
+ import { type MediaOnError } from '../on-error';
3
4
  import type { FallbackOffthreadVideoProps } from './props';
4
5
  type InnerVideoProps = {
5
6
  readonly className: string | undefined;
@@ -23,6 +24,7 @@ type InnerVideoProps = {
23
24
  readonly trimBeforeValue: number | undefined;
24
25
  readonly trimAfterValue: number | undefined;
25
26
  readonly headless: boolean;
27
+ readonly onError: MediaOnError | undefined;
26
28
  };
27
29
  export declare const VideoForRendering: React.FC<InnerVideoProps>;
28
30
  export {};
@@ -1,6 +1,11 @@
1
1
  import type { WrappedCanvas } from 'mediabunny';
2
- import type { PrewarmedVideoIteratorCache } from '../prewarm-iterator-for-looping';
3
- export declare const createVideoIterator: (timeToSeek: number, cache: PrewarmedVideoIteratorCache) => {
2
+ export declare const createVideoIterator: (timeToSeek: number, cache: {
3
+ prewarmIteratorForLooping: ({ timeToSeek }: {
4
+ timeToSeek: number;
5
+ }) => void;
6
+ makeIteratorOrUsePrewarmed: (timeToSeek: number) => AsyncGenerator<WrappedCanvas, void, unknown>;
7
+ destroy: () => void;
8
+ }) => {
4
9
  destroy: () => void;
5
10
  getNext: () => Promise<IteratorResult<WrappedCanvas, void>>;
6
11
  isDestroyed: () => boolean;
@@ -1,4 +1,3 @@
1
- import { type LogLevel } from 'remotion';
2
1
  import type { PcmS16AudioData } from '../convert-audiodata/convert-audiodata';
3
2
  export type ExtractFrameViaBroadcastChannelResult = {
4
3
  type: 'success';
@@ -21,7 +20,7 @@ export declare const extractFrameViaBroadcastChannel: ({ src, timeInSeconds, log
21
20
  timeInSeconds: number;
22
21
  durationInSeconds: number;
23
22
  playbackRate: number;
24
- logLevel: LogLevel;
23
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
25
24
  includeAudio: boolean;
26
25
  includeVideo: boolean;
27
26
  isClientSideRendering: boolean;
@@ -26,7 +26,5 @@ type ExtractFrameParams = {
26
26
  fps: number;
27
27
  maxCacheSize: number;
28
28
  };
29
- declare const extractFrameInternal: ({ src, timeInSeconds: unloopedTimeInSeconds, logLevel, loop, trimAfter, trimBefore, playbackRate, fps, maxCacheSize, }: ExtractFrameParams) => Promise<ExtractFrameResult>;
30
- type ExtractFrameReturnType = Awaited<ReturnType<typeof extractFrameInternal>>;
31
- export declare const extractFrame: (params: ExtractFrameParams) => Promise<ExtractFrameReturnType>;
29
+ export declare const extractFrame: (params: ExtractFrameParams) => Promise<ExtractFrameResult>;
32
30
  export {};
@@ -6,7 +6,7 @@ export type KeyframeBank = {
6
6
  prepareForDeletion: (logLevel: LogLevel, reason: string) => {
7
7
  framesDeleted: number;
8
8
  };
9
- deleteFramesBeforeTimestamp: ({ logLevel, timestampInSeconds, }: {
9
+ deleteFramesBeforeTimestamp: ({ logLevel, timestampInSeconds }: {
10
10
  timestampInSeconds: number;
11
11
  logLevel: LogLevel;
12
12
  }) => void;
@@ -24,7 +24,7 @@ export type KeyframeBank = {
24
24
  } | null;
25
25
  };
26
26
  export declare const makeKeyframeBank: ({ logLevel: parentLogLevel, src, videoSampleSink, requestedTimestamp, }: {
27
- logLevel: LogLevel;
27
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
28
28
  src: string;
29
29
  videoSampleSink: VideoSampleSink;
30
30
  requestedTimestamp: number;
@@ -1,18 +1,17 @@
1
1
  import type { VideoSampleSink } from 'mediabunny';
2
- import { type LogLevel } from 'remotion';
3
2
  import { type KeyframeBank } from './keyframe-bank';
4
3
  export declare const makeKeyframeManager: () => {
5
4
  requestKeyframeBank: ({ timestamp, videoSampleSink, src, logLevel, maxCacheSize, }: {
6
5
  timestamp: number;
7
6
  videoSampleSink: VideoSampleSink;
8
7
  src: string;
9
- logLevel: LogLevel;
8
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
10
9
  maxCacheSize: number;
11
10
  }) => Promise<KeyframeBank>;
12
11
  getCacheStats: () => {
13
12
  count: number;
14
13
  totalSize: number;
15
14
  };
16
- clearAll: (logLevel: LogLevel) => void;
15
+ clearAll: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => void;
17
16
  };
18
17
  export type KeyframeManager = Awaited<ReturnType<typeof makeKeyframeManager>>;
@@ -1,15 +1,14 @@
1
1
  import type { InputVideoTrack, WrappedCanvas } from 'mediabunny';
2
- import type { LogLevel } from 'remotion';
3
2
  import type { Nonce } from './nonce-manager';
4
3
  export declare const videoIteratorManager: ({ delayPlaybackHandleIfNotPremounting, canvas, context, drawDebugOverlay, logLevel, getOnVideoFrameCallback, videoTrack, getEndTime, getStartTime, getIsLooping, }: {
5
4
  videoTrack: InputVideoTrack;
6
5
  delayPlaybackHandleIfNotPremounting: () => {
7
6
  unblock: () => void;
8
7
  };
9
- context: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null;
10
- canvas: OffscreenCanvas | HTMLCanvasElement | null;
11
- getOnVideoFrameCallback: () => null | ((frame: CanvasImageSource) => void);
12
- logLevel: LogLevel;
8
+ context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;
9
+ canvas: HTMLCanvasElement | OffscreenCanvas | null;
10
+ getOnVideoFrameCallback: () => ((frame: CanvasImageSource) => void) | null;
11
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
13
12
  drawDebugOverlay: () => void;
14
13
  getEndTime: () => number;
15
14
  getStartTime: () => number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.403",
3
+ "version": "4.0.404",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/esm/index.mjs",
@@ -12,30 +12,32 @@
12
12
  "bugs": {
13
13
  "url": "https://github.com/remotion-dev/remotion/issues"
14
14
  },
15
+ "type": "module",
15
16
  "scripts": {
16
17
  "if-node-18+": "node -e \"const [maj]=process.versions.node.split('.').map(Number); process.exit(maj>=18?0:1)\"",
17
18
  "formatting": "prettier --experimental-cli src --check",
18
19
  "lint": "eslint src",
19
- "watch": "tsc -w",
20
+ "watch": "tsgo -w",
20
21
  "test": "node src/test/execute.mjs",
21
- "make": "tsc -d && bun --env-file=../.env.bundle bundle.ts"
22
+ "make": "tsgo && bun --env-file=../.env.bundle bundle.ts"
22
23
  },
23
24
  "dependencies": {
24
25
  "mediabunny": "1.27.3",
25
- "remotion": "4.0.403"
26
+ "remotion": "4.0.404"
26
27
  },
27
28
  "peerDependencies": {
28
29
  "react": ">=16.8.0",
29
30
  "react-dom": ">=16.8.0"
30
31
  },
31
32
  "devDependencies": {
32
- "@remotion/eslint-config-internal": "4.0.403",
33
+ "@remotion/eslint-config-internal": "4.0.404",
33
34
  "@vitest/browser-webdriverio": "4.0.9",
34
35
  "eslint": "9.19.0",
35
36
  "react": "19.2.3",
36
37
  "react-dom": "19.2.3",
37
38
  "vitest": "4.0.9",
38
- "webdriverio": "9.19.2"
39
+ "webdriverio": "9.19.2",
40
+ "@typescript/native-preview": "7.0.0-dev.20260105.1"
39
41
  },
40
42
  "keywords": [],
41
43
  "publishConfig": {
@@ -44,7 +46,6 @@
44
46
  "exports": {
45
47
  ".": {
46
48
  "types": "./dist/index.d.ts",
47
- "require": "./dist/index.js",
48
49
  "module": "./dist/esm/index.mjs",
49
50
  "import": "./dist/esm/index.mjs"
50
51
  },
@@ -1,15 +0,0 @@
1
- export const allowWaitRoutine = async (next, waitFn) => {
2
- const result = await Promise.race([
3
- next,
4
- new Promise((resolve) => {
5
- Promise.resolve().then(() => resolve());
6
- }),
7
- ]);
8
- if (!result) {
9
- const unblock = waitFn.waitCallback();
10
- const newRes = await next;
11
- unblock();
12
- return newRes;
13
- }
14
- return result;
15
- };
@@ -1,302 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
3
- import { Internals, Audio as RemotionAudio, useBufferState, useCurrentFrame, useVideoConfig, } from 'remotion';
4
- import { getTimeInSeconds } from '../get-time-in-seconds';
5
- import { MediaPlayer } from '../media-player';
6
- import { useLoopDisplay } from '../show-in-timeline';
7
- import { useMediaInTimeline } from '../use-media-in-timeline';
8
- const { useUnsafeVideoConfig, Timeline, SharedAudioContext, useMediaMutedState, useMediaVolumeState, useFrameForVolumeProp, evaluateVolume, warnAboutTooHighVolume, usePreload, SequenceContext, } = Internals;
9
- const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, volume, loopVolumeCurveBehavior, loop, trimAfter, trimBefore, name, showInTimeline, stack, disallowFallbackToHtml5Audio, toneFrequency, audioStreamIndex, fallbackHtml5AudioProps, }) => {
10
- const videoConfig = useUnsafeVideoConfig();
11
- const frame = useCurrentFrame();
12
- const mediaPlayerRef = useRef(null);
13
- const initialTrimBeforeRef = useRef(trimBefore);
14
- const initialTrimAfterRef = useRef(trimAfter);
15
- const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
16
- const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState(false);
17
- const [playing] = Timeline.usePlayingState();
18
- const timelineContext = useContext(Internals.TimelineContext);
19
- const globalPlaybackRate = timelineContext.playbackRate;
20
- const sharedAudioContext = useContext(SharedAudioContext);
21
- const buffer = useBufferState();
22
- const [mediaMuted] = useMediaMutedState();
23
- const [mediaVolume] = useMediaVolumeState();
24
- const [mediaDurationInSeconds, setMediaDurationInSeconds] = useState(null);
25
- const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? 'repeat');
26
- const userPreferredVolume = evaluateVolume({
27
- frame: volumePropFrame,
28
- volume,
29
- mediaVolume,
30
- });
31
- warnAboutTooHighVolume(userPreferredVolume);
32
- if (!videoConfig) {
33
- throw new Error('No video config found');
34
- }
35
- if (!src) {
36
- throw new TypeError('No `src` was passed to <NewAudioForPreview>.');
37
- }
38
- const currentTime = frame / videoConfig.fps;
39
- const currentTimeRef = useRef(currentTime);
40
- currentTimeRef.current = currentTime;
41
- const preloadedSrc = usePreload(src);
42
- const parentSequence = useContext(SequenceContext);
43
- const isPremounting = Boolean(parentSequence?.premounting);
44
- const isPostmounting = Boolean(parentSequence?.postmounting);
45
- const loopDisplay = useLoopDisplay({
46
- loop,
47
- mediaDurationInSeconds,
48
- playbackRate,
49
- trimAfter,
50
- trimBefore,
51
- });
52
- useMediaInTimeline({
53
- volume,
54
- mediaVolume,
55
- mediaType: 'audio',
56
- src,
57
- playbackRate,
58
- displayName: name ?? null,
59
- stack,
60
- showInTimeline,
61
- premountDisplay: parentSequence?.premountDisplay ?? null,
62
- postmountDisplay: parentSequence?.postmountDisplay ?? null,
63
- loopDisplay,
64
- trimAfter,
65
- trimBefore,
66
- });
67
- const bufferingContext = useContext(Internals.BufferingContextReact);
68
- if (!bufferingContext) {
69
- throw new Error('useMediaPlayback must be used inside a <BufferingContext>');
70
- }
71
- const isPlayerBuffering = Internals.useIsPlayerBuffering(bufferingContext);
72
- const initialPlaying = useRef(playing && !isPlayerBuffering);
73
- const initialIsPremounting = useRef(isPremounting);
74
- const initialIsPostmounting = useRef(isPostmounting);
75
- const initialGlobalPlaybackRate = useRef(globalPlaybackRate);
76
- const initialPlaybackRate = useRef(playbackRate);
77
- useEffect(() => {
78
- if (!sharedAudioContext)
79
- return;
80
- if (!sharedAudioContext.audioContext)
81
- return;
82
- try {
83
- const player = new MediaPlayer({
84
- src: preloadedSrc,
85
- logLevel,
86
- sharedAudioContext: sharedAudioContext.audioContext,
87
- loop,
88
- trimAfter: initialTrimAfterRef.current,
89
- trimBefore: initialTrimBeforeRef.current,
90
- fps: videoConfig.fps,
91
- canvas: null,
92
- playbackRate: initialPlaybackRate.current,
93
- audioStreamIndex: audioStreamIndex ?? 0,
94
- debugOverlay: false,
95
- bufferState: buffer,
96
- isPostmounting: initialIsPostmounting.current,
97
- isPremounting: initialIsPremounting.current,
98
- globalPlaybackRate: initialGlobalPlaybackRate.current,
99
- onVideoFrameCallback: null,
100
- playing: initialPlaying.current,
101
- });
102
- mediaPlayerRef.current = player;
103
- player
104
- .initialize(currentTimeRef.current)
105
- .then((result) => {
106
- if (result.type === 'disposed') {
107
- return;
108
- }
109
- if (result.type === 'unknown-container-format') {
110
- if (disallowFallbackToHtml5Audio) {
111
- throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
112
- }
113
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
114
- setShouldFallbackToNativeAudio(true);
115
- return;
116
- }
117
- if (result.type === 'network-error') {
118
- if (disallowFallbackToHtml5Audio) {
119
- throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
120
- }
121
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${preloadedSrc}, falling back to <Html5Audio>`);
122
- setShouldFallbackToNativeAudio(true);
123
- return;
124
- }
125
- if (result.type === 'cannot-decode') {
126
- if (disallowFallbackToHtml5Audio) {
127
- throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
128
- }
129
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${preloadedSrc}, falling back to <Html5Audio>`);
130
- setShouldFallbackToNativeAudio(true);
131
- return;
132
- }
133
- if (result.type === 'no-tracks') {
134
- if (disallowFallbackToHtml5Audio) {
135
- throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
136
- }
137
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
138
- setShouldFallbackToNativeAudio(true);
139
- return;
140
- }
141
- if (result.type === 'success') {
142
- setMediaPlayerReady(true);
143
- setMediaDurationInSeconds(result.durationInSeconds);
144
- Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[AudioForPreview] MediaPlayer initialized successfully`);
145
- }
146
- })
147
- .catch((error) => {
148
- Internals.Log.error({ logLevel, tag: '@remotion/media' }, '[AudioForPreview] Failed to initialize MediaPlayer', error);
149
- setShouldFallbackToNativeAudio(true);
150
- });
151
- }
152
- catch (error) {
153
- Internals.Log.error({ logLevel, tag: '@remotion/media' }, '[AudioForPreview] MediaPlayer initialization failed', error);
154
- setShouldFallbackToNativeAudio(true);
155
- }
156
- return () => {
157
- if (mediaPlayerRef.current) {
158
- Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[AudioForPreview] Disposing MediaPlayer`);
159
- mediaPlayerRef.current.dispose();
160
- mediaPlayerRef.current = null;
161
- }
162
- setMediaPlayerReady(false);
163
- setShouldFallbackToNativeAudio(false);
164
- };
165
- }, [
166
- preloadedSrc,
167
- logLevel,
168
- sharedAudioContext,
169
- currentTimeRef,
170
- loop,
171
- videoConfig.fps,
172
- audioStreamIndex,
173
- disallowFallbackToHtml5Audio,
174
- buffer,
175
- ]);
176
- useLayoutEffect(() => {
177
- const audioPlayer = mediaPlayerRef.current;
178
- if (!audioPlayer)
179
- return;
180
- if (playing && !isPlayerBuffering) {
181
- audioPlayer.play(currentTimeRef.current);
182
- }
183
- else {
184
- audioPlayer.pause();
185
- }
186
- }, [isPlayerBuffering, logLevel, playing]);
187
- useLayoutEffect(() => {
188
- const mediaPlayer = mediaPlayerRef.current;
189
- if (!mediaPlayer || !mediaPlayerReady) {
190
- return;
191
- }
192
- mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
193
- }, [trimBefore, mediaPlayerReady]);
194
- useLayoutEffect(() => {
195
- const mediaPlayer = mediaPlayerRef.current;
196
- if (!mediaPlayer || !mediaPlayerReady) {
197
- return;
198
- }
199
- mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
200
- }, [trimAfter, mediaPlayerReady]);
201
- const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
202
- useLayoutEffect(() => {
203
- const audioPlayer = mediaPlayerRef.current;
204
- if (!audioPlayer || !mediaPlayerReady)
205
- return;
206
- audioPlayer.setMuted(effectiveMuted);
207
- }, [effectiveMuted, mediaPlayerReady]);
208
- useEffect(() => {
209
- const audioPlayer = mediaPlayerRef.current;
210
- if (!audioPlayer || !mediaPlayerReady) {
211
- return;
212
- }
213
- audioPlayer.setVolume(userPreferredVolume);
214
- }, [userPreferredVolume, mediaPlayerReady]);
215
- useEffect(() => {
216
- const audioPlayer = mediaPlayerRef.current;
217
- if (!audioPlayer || !mediaPlayerReady) {
218
- return;
219
- }
220
- audioPlayer.setPlaybackRate(playbackRate);
221
- }, [playbackRate, mediaPlayerReady]);
222
- useLayoutEffect(() => {
223
- const audioPlayer = mediaPlayerRef.current;
224
- if (!audioPlayer || !mediaPlayerReady) {
225
- return;
226
- }
227
- audioPlayer.setGlobalPlaybackRate(globalPlaybackRate);
228
- }, [globalPlaybackRate, mediaPlayerReady]);
229
- useLayoutEffect(() => {
230
- const audioPlayer = mediaPlayerRef.current;
231
- if (!audioPlayer || !mediaPlayerReady) {
232
- return;
233
- }
234
- audioPlayer.setFps(videoConfig.fps);
235
- }, [videoConfig.fps, mediaPlayerReady]);
236
- useLayoutEffect(() => {
237
- const mediaPlayer = mediaPlayerRef.current;
238
- if (!mediaPlayer || !mediaPlayerReady) {
239
- return;
240
- }
241
- mediaPlayer.setLoop(loop);
242
- }, [loop, mediaPlayerReady]);
243
- useLayoutEffect(() => {
244
- const mediaPlayer = mediaPlayerRef.current;
245
- if (!mediaPlayer || !mediaPlayerReady) {
246
- return;
247
- }
248
- mediaPlayer.setIsPremounting(isPremounting);
249
- }, [isPremounting, mediaPlayerReady]);
250
- useLayoutEffect(() => {
251
- const mediaPlayer = mediaPlayerRef.current;
252
- if (!mediaPlayer || !mediaPlayerReady) {
253
- return;
254
- }
255
- mediaPlayer.setIsPostmounting(isPostmounting);
256
- }, [isPostmounting, mediaPlayerReady]);
257
- useLayoutEffect(() => {
258
- const audioPlayer = mediaPlayerRef.current;
259
- if (!audioPlayer || !mediaPlayerReady)
260
- return;
261
- audioPlayer.seekTo(currentTime).catch(() => {
262
- // Might be disposed
263
- });
264
- Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[AudioForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
265
- }, [currentTime, logLevel, mediaPlayerReady]);
266
- if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
267
- return (_jsx(RemotionAudio, { src: src, muted: muted, volume: volume, startFrom: trimBefore, endAt: trimAfter, playbackRate: playbackRate, loopVolumeCurveBehavior: loopVolumeCurveBehavior, name: name, loop: loop, showInTimeline: showInTimeline, stack: stack ?? undefined, toneFrequency: toneFrequency, audioStreamIndex: audioStreamIndex, pauseWhenBuffering: fallbackHtml5AudioProps?.pauseWhenBuffering, crossOrigin: fallbackHtml5AudioProps?.crossOrigin, ...fallbackHtml5AudioProps }));
268
- }
269
- return null;
270
- };
271
- export const AudioForPreview = ({ loop, src, logLevel, muted, name, volume, loopVolumeCurveBehavior, playbackRate, trimAfter, trimBefore, showInTimeline, stack, disallowFallbackToHtml5Audio, toneFrequency, audioStreamIndex, fallbackHtml5AudioProps, }) => {
272
- const preloadedSrc = usePreload(src);
273
- const defaultLogLevel = Internals.useLogLevel();
274
- const frame = useCurrentFrame();
275
- const videoConfig = useVideoConfig();
276
- const currentTime = frame / videoConfig.fps;
277
- const showShow = useMemo(() => {
278
- return (getTimeInSeconds({
279
- unloopedTimeInSeconds: currentTime,
280
- playbackRate: playbackRate ?? 1,
281
- loop: loop ?? false,
282
- trimBefore,
283
- trimAfter,
284
- mediaDurationInSeconds: Infinity,
285
- fps: videoConfig.fps,
286
- ifNoMediaDuration: 'infinity',
287
- src,
288
- }) !== null);
289
- }, [
290
- currentTime,
291
- loop,
292
- playbackRate,
293
- src,
294
- trimAfter,
295
- trimBefore,
296
- videoConfig.fps,
297
- ]);
298
- if (!showShow) {
299
- return null;
300
- }
301
- return (_jsx(AudioForPreviewAssertedShowing, { audioStreamIndex: audioStreamIndex ?? 0, src: preloadedSrc, playbackRate: playbackRate ?? 1, logLevel: logLevel ?? defaultLogLevel, muted: muted ?? false, volume: volume ?? 1, loopVolumeCurveBehavior: loopVolumeCurveBehavior ?? 'repeat', loop: loop ?? false, trimAfter: trimAfter, trimBefore: trimBefore, name: name, showInTimeline: showInTimeline ?? true, stack: stack, disallowFallbackToHtml5Audio: disallowFallbackToHtml5Audio ?? false, toneFrequency: toneFrequency, fallbackHtml5AudioProps: fallbackHtml5AudioProps }));
302
- };