xxf_react 0.6.0 → 0.6.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"XVideo.d.ts","sourceRoot":"","sources":["../../../src/media/components/XVideo.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAMV,SAAS,EACT,mBAAmB,EACnB,SAAS,EACZ,MAAM,OAAO,CAAA;AAOd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC;IACtF;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAE3B;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,kBAAkB,CAAC,EAAE,SAAS,CAAA;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,SAAS,CAAC,GAAG,IAAI,CAAA;IAE1D;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAE7C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,MAAM,CAAC,EACI,GAAG,EACH,MAAM,EACN,qBAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EACP,OAAgB,EAChB,WAAkB,EAClB,WAAyB,EACzB,GAAG,UAAU,EAChB,EAAE,WAAW,qBAiWpC"}
1
+ {"version":3,"file":"XVideo.d.ts","sourceRoot":"","sources":["../../../src/media/components/XVideo.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAMV,SAAS,EACT,mBAAmB,EACnB,SAAS,EACZ,MAAM,OAAO,CAAA;AAOd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC;IACtF;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAE3B;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,kBAAkB,CAAC,EAAE,SAAS,CAAA;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,SAAS,CAAC,GAAG,IAAI,CAAA;IAE1D;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAE7C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,MAAM,CAAC,EACI,GAAG,EACH,MAAM,EACN,qBAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EACP,OAAgB,EAChB,WAAkB,EAClB,WAAyB,EACzB,GAAG,UAAU,EAChB,EAAE,WAAW,qBAgXpC"}
@@ -156,21 +156,29 @@ export function XVideo({ src, poster, posterFadeOutDuration = 300, bufferingIndi
156
156
  checkAndSetReady();
157
157
  }, [playState.canPlay, checkAndSetReady]);
158
158
  /**
159
- * Effect: 播放结束或出错时显示封面
159
+ * Effect: 暂停、播放结束或出错时显示封面
160
160
  *
161
+ * 视频暂停时,重新显示封面
161
162
  * 视频播放结束时,重新显示封面,避免最后一帧可能是黑屏的问题
162
163
  * 视频播放出错时,重新显示封面,作为错误指示器的背景
163
164
  *
164
- * 当视频重新播放时(ended true 变为 false),封面会通过
165
- * 正常的 checkAndSetReady 流程再次淡出
165
+ * 当视频重新播放时,封面会通过正常的 checkAndSetReady 流程再次淡出
166
+ *
167
+ * 注意:必须同时重置 firstFrameRenderedRef,否则 checkAndSetReady 会立即再次隐藏封面
166
168
  */
167
169
  useEffect(() => {
168
- if ((playState.ended || playState.error) && poster) {
169
- // 播放结束或出错,显示封面
170
+ if (poster && (playState.ended || playState.error || !playState.playing)) {
171
+ // 清理淡出定时器,防止正在进行的淡出继续执行
172
+ if (fadeOutTimerRef.current) {
173
+ clearTimeout(fadeOutTimerRef.current);
174
+ fadeOutTimerRef.current = null;
175
+ }
176
+ // 重置第一帧标记,防止 checkAndSetReady 立即隐藏封面
177
+ firstFrameRenderedRef.current = false;
170
178
  setShowPoster(true);
171
179
  setIsReady(false);
172
180
  }
173
- }, [playState.ended, playState.error, poster]);
181
+ }, [playState.ended, playState.error, playState.playing, poster]);
174
182
  /**
175
183
  * Effect: 通过 currentTime 检测第一帧(回退方案)
176
184
  *
@@ -178,13 +186,15 @@ export function XVideo({ src, poster, posterFadeOutDuration = 300, bufferingIndi
178
186
  * 使用 currentTime > 0 作为第一帧渲染的近似检测
179
187
  *
180
188
  * 原理:currentTime > 0 表示视频已开始播放,此时第一帧大概率已渲染
189
+ *
190
+ * 注意:必须检查 playState.playing,否则暂停时 currentTime > 0 会立即触发封面隐藏
181
191
  */
182
192
  useEffect(() => {
183
- if (!firstFrameRenderedRef.current && playState.currentTime > 0) {
193
+ if (!firstFrameRenderedRef.current && playState.currentTime > 0 && playState.playing) {
184
194
  firstFrameRenderedRef.current = true;
185
195
  checkAndSetReady();
186
196
  }
187
- }, [playState.currentTime, checkAndSetReady]);
197
+ }, [playState.currentTime, playState.playing, checkAndSetReady]);
188
198
  /**
189
199
  * Effect: 第一帧检测 - 优先使用 requestVideoFrameCallback
190
200
  *
@@ -197,7 +207,9 @@ export function XVideo({ src, poster, posterFadeOutDuration = 300, bufferingIndi
197
207
  * 3. 第一帧渲染时标记 firstFrameRendered 并检查就绪状态
198
208
  * 4. cleanup 时取消回调,防止组件卸载后执行
199
209
  *
200
- * 注意:cleanedUp flag 用于防止组件卸载后的状态更新(React 严格模式下的竞态条件)
210
+ * 注意:
211
+ * - cleanedUp flag 用于防止组件卸载后的状态更新(React 严格模式下的竞态条件)
212
+ * - 必须检查 playState.playing,否则暂停时可能错误触发
201
213
  */
202
214
  useEffect(() => {
203
215
  const video = videoRef.current;
@@ -206,6 +218,9 @@ export function XVideo({ src, poster, posterFadeOutDuration = 300, bufferingIndi
206
218
  // 如果已经检测到第一帧,无需重复检测
207
219
  if (firstFrameRenderedRef.current)
208
220
  return;
221
+ // 视频未播放时不注册回调
222
+ if (!playState.playing)
223
+ return;
209
224
  // 检查浏览器是否支持 requestVideoFrameCallback
210
225
  const supportsVideoFrameCallback = 'requestVideoFrameCallback' in HTMLVideoElement.prototype;
211
226
  if (supportsVideoFrameCallback) {
@@ -226,7 +241,7 @@ export function XVideo({ src, poster, posterFadeOutDuration = 300, bufferingIndi
226
241
  };
227
242
  }
228
243
  // 不支持 requestVideoFrameCallback 的浏览器由 currentTime effect 处理
229
- }, [src, videoRef, checkAndSetReady]);
244
+ }, [src, videoRef, playState.playing, checkAndSetReady]);
230
245
  // ==================== 渲染逻辑 ====================
231
246
  /**
232
247
  * 封面元素 - 使用 useMemo 优化
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xxf_react",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",