@remotion/media 4.0.351 → 4.0.352

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.
@@ -0,0 +1,114 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext, useEffect, useRef, useState } from 'react';
3
+ import { Internals, useBufferState, useCurrentFrame } from 'remotion';
4
+ import { Log } from '../log';
5
+ import { MediaPlayer } from '../video/media-player';
6
+ const { useUnsafeVideoConfig, Timeline, SharedAudioContext } = Internals;
7
+ export const NewVideoForPreview = ({ src, style, playbackRate = 1, logLevel = 'info', }) => {
8
+ const canvasRef = useRef(null);
9
+ const videoConfig = useUnsafeVideoConfig();
10
+ const frame = useCurrentFrame();
11
+ const lastCurrentTimeRef = useRef(-1);
12
+ const mediaPlayerRef = useRef(null);
13
+ const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
14
+ const [playing] = Timeline.usePlayingState();
15
+ const sharedAudioContext = useContext(SharedAudioContext);
16
+ const buffer = useBufferState();
17
+ const delayHandleRef = useRef(null);
18
+ if (!videoConfig) {
19
+ throw new Error('No video config found');
20
+ }
21
+ if (!src) {
22
+ throw new TypeError('No `src` was passed to <NewVideoForPreview>.');
23
+ }
24
+ const actualFps = videoConfig.fps / playbackRate;
25
+ const currentTime = frame / actualFps;
26
+ const [initialTimestamp] = useState(currentTime);
27
+ useEffect(() => {
28
+ if (!canvasRef.current)
29
+ return;
30
+ if (!sharedAudioContext)
31
+ return;
32
+ if (!sharedAudioContext.audioContext)
33
+ return;
34
+ try {
35
+ Log.trace(logLevel, `[NewVideoForPreview] Creating MediaPlayer for src: ${src}`);
36
+ const player = new MediaPlayer({
37
+ canvas: canvasRef.current,
38
+ src,
39
+ logLevel,
40
+ sharedAudioContext: sharedAudioContext.audioContext,
41
+ });
42
+ mediaPlayerRef.current = player;
43
+ player
44
+ .initialize(initialTimestamp)
45
+ .then(() => {
46
+ setMediaPlayerReady(true);
47
+ Log.trace(logLevel, `[NewVideoForPreview] MediaPlayer initialized successfully`);
48
+ })
49
+ .catch((error) => {
50
+ Log.error('[NewVideoForPreview] Failed to initialize MediaPlayer', error);
51
+ });
52
+ }
53
+ catch (error) {
54
+ Log.error('[NewVideoForPreview] MediaPlayer initialization failed', error);
55
+ }
56
+ return () => {
57
+ if (delayHandleRef.current) {
58
+ delayHandleRef.current.unblock();
59
+ delayHandleRef.current = null;
60
+ }
61
+ if (mediaPlayerRef.current) {
62
+ Log.trace(logLevel, `[NewVideoForPreview] Disposing MediaPlayer`);
63
+ mediaPlayerRef.current.dispose();
64
+ mediaPlayerRef.current = null;
65
+ }
66
+ setMediaPlayerReady(false);
67
+ };
68
+ }, [src, logLevel, sharedAudioContext, initialTimestamp]);
69
+ // sync play/pause state with Remotion timeline (like old VideoForPreview video does)
70
+ useEffect(() => {
71
+ const mediaPlayer = mediaPlayerRef.current;
72
+ if (!mediaPlayer)
73
+ return;
74
+ if (playing) {
75
+ Log.trace(logLevel, `[NewVideoForPreview] Remotion playing - calling MediaPlayer.play()`);
76
+ mediaPlayer.play().catch((error) => {
77
+ Log.error('[NewVideoForPreview] Failed to play', error);
78
+ });
79
+ }
80
+ else {
81
+ Log.trace(logLevel, `[NewVideoForPreview] Remotion paused - calling MediaPlayer.pause()`);
82
+ mediaPlayer.pause();
83
+ }
84
+ }, [playing, logLevel, mediaPlayerReady]);
85
+ // sync target time with MediaPlayer
86
+ useEffect(() => {
87
+ const mediaPlayer = mediaPlayerRef.current;
88
+ if (!mediaPlayer || !mediaPlayerReady)
89
+ return;
90
+ mediaPlayer.seekTo(currentTime);
91
+ Log.trace(logLevel, `[NewVideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
92
+ lastCurrentTimeRef.current = currentTime;
93
+ }, [currentTime, logLevel, mediaPlayerReady]);
94
+ // sync MediaPlayer stalling with Remotion buffering
95
+ useEffect(() => {
96
+ const mediaPlayer = mediaPlayerRef.current;
97
+ if (!mediaPlayer || !mediaPlayerReady)
98
+ return;
99
+ mediaPlayer.onStalledChange((isStalled) => {
100
+ if (isStalled && !delayHandleRef.current) {
101
+ // Start blocking Remotion playback
102
+ delayHandleRef.current = buffer.delayPlayback();
103
+ Log.trace(logLevel, '[NewVideoForPreview] MediaPlayer stalled - blocking Remotion playback');
104
+ }
105
+ else if (!isStalled && delayHandleRef.current) {
106
+ // Unblock Remotion playback
107
+ delayHandleRef.current.unblock();
108
+ delayHandleRef.current = null;
109
+ Log.trace(logLevel, '[NewVideoForPreview] MediaPlayer unstalled - unblocking Remotion playback');
110
+ }
111
+ });
112
+ }, [mediaPlayerReady, buffer, logLevel]);
113
+ return (_jsx("canvas", { ref: canvasRef, width: videoConfig.width, height: videoConfig.height, style: style }));
114
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/media",
3
- "version": "4.0.351",
3
+ "version": "4.0.352",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/esm/index.mjs",
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "mediabunny": "1.17.0",
17
17
  "webdriverio": "9.19.2",
18
- "remotion": "4.0.351"
18
+ "remotion": "4.0.352"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",
@@ -27,7 +27,7 @@
27
27
  "react": "19.0.0",
28
28
  "react-dom": "19.0.0",
29
29
  "vitest": "3.2.4",
30
- "@remotion/eslint-config-internal": "4.0.351"
30
+ "@remotion/eslint-config-internal": "4.0.352"
31
31
  },
32
32
  "keywords": [],
33
33
  "publishConfig": {