deepsea-components 5.18.13 → 5.18.14

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.
@@ -42,30 +42,48 @@ __webpack_require__.d(__webpack_exports__, {
42
42
  });
43
43
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
44
44
  const external_react_namespaceObject = require("react");
45
+ const external_deepsea_tools_namespaceObject = require("deepsea-tools");
45
46
  const external_hls_js_namespaceObject = require("hls.js");
46
47
  var external_hls_js_default = /*#__PURE__*/ __webpack_require__.n(external_hls_js_namespaceObject);
47
- const HlsPlayer = ({ ref, src, ...rest })=>{
48
+ const HlsPlayer = ({ ref, src: source, onHlsError, onHlsUnsupported, ...rest })=>{
48
49
  const video = (0, external_react_namespaceObject.useRef)(null);
49
50
  (0, external_react_namespaceObject.useImperativeHandle)(ref, ()=>video.current, []);
51
+ const src = null == source ? void 0 : source.trim();
52
+ const onHlsErrorLatest = (0, external_react_namespaceObject.useEffectEvent)((0, external_deepsea_tools_namespaceObject.optionalFn)(onHlsError));
53
+ const onHlsUnsupportedLatest = (0, external_react_namespaceObject.useEffectEvent)((0, external_deepsea_tools_namespaceObject.optionalFn)(onHlsUnsupported));
50
54
  (0, external_react_namespaceObject.useEffect)(()=>{
51
55
  const { current: player } = video;
52
56
  if (!player || !src) return;
53
57
  let hls = null;
54
58
  if (external_hls_js_default().isSupported()) {
55
- hls = new (external_hls_js_default())();
56
- hls.loadSource(src);
57
- hls.attachMedia(player);
58
- hls.on(external_hls_js_default().Events.ERROR, (event, data)=>{
59
- console.log(event);
60
- console.log(data);
59
+ const instance = new (external_hls_js_default())();
60
+ let hasRetriedNetworkError = false;
61
+ let hasRecoveredMediaError = false;
62
+ hls = instance;
63
+ instance.loadSource(src);
64
+ instance.attachMedia(player);
65
+ instance.on(external_hls_js_default().Events.ERROR, (_event, data)=>{
66
+ onHlsErrorLatest(data);
67
+ if (!data.fatal) return;
68
+ if (data.type === external_hls_js_namespaceObject.ErrorTypes.NETWORK_ERROR && !hasRetriedNetworkError) {
69
+ hasRetriedNetworkError = true;
70
+ instance.startLoad();
71
+ return;
72
+ }
73
+ if (data.type === external_hls_js_namespaceObject.ErrorTypes.MEDIA_ERROR && !hasRecoveredMediaError) {
74
+ hasRecoveredMediaError = true;
75
+ instance.recoverMediaError();
76
+ return;
77
+ }
78
+ instance.destroy();
79
+ if (hls === instance) hls = null;
61
80
  });
62
81
  } else if (player.canPlayType("application/vnd.apple.mpegurl")) player.src = src;
82
+ else onHlsUnsupportedLatest();
63
83
  return ()=>{
64
- if (hls) hls.destroy();
65
- if (player) {
66
- player.src = "";
67
- player.load();
68
- }
84
+ null == hls || hls.destroy();
85
+ player.removeAttribute("src");
86
+ player.load();
69
87
  };
70
88
  }, [
71
89
  src
@@ -1,5 +1,7 @@
1
1
  import { type ComponentProps, type FC } from "react";
2
- export interface HlsPlayerProps extends Omit<ComponentProps<"video">, "src" | "children"> {
3
- src: string;
2
+ import { type ErrorData } from "hls.js";
3
+ export interface HlsPlayerProps extends Omit<ComponentProps<"video">, "children"> {
4
+ onHlsError?: (data: ErrorData) => void;
5
+ onHlsUnsupported?: () => void;
4
6
  }
5
7
  export declare const HlsPlayer: FC<HlsPlayerProps>;
@@ -1,29 +1,47 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { useEffect, useImperativeHandle, useRef } from "react";
4
- import hls_0 from "hls.js";
5
- const HlsPlayer = ({ ref, src, ...rest })=>{
3
+ import { useEffect, useEffectEvent, useImperativeHandle, useRef } from "react";
4
+ import { optionalFn } from "deepsea-tools";
5
+ import hls_0, { ErrorTypes } from "hls.js";
6
+ const HlsPlayer = ({ ref, src: source, onHlsError, onHlsUnsupported, ...rest })=>{
6
7
  const video = useRef(null);
7
8
  useImperativeHandle(ref, ()=>video.current, []);
9
+ const src = null == source ? void 0 : source.trim();
10
+ const onHlsErrorLatest = useEffectEvent(optionalFn(onHlsError));
11
+ const onHlsUnsupportedLatest = useEffectEvent(optionalFn(onHlsUnsupported));
8
12
  useEffect(()=>{
9
13
  const { current: player } = video;
10
14
  if (!player || !src) return;
11
15
  let hls = null;
12
16
  if (hls_0.isSupported()) {
13
- hls = new hls_0();
14
- hls.loadSource(src);
15
- hls.attachMedia(player);
16
- hls.on(hls_0.Events.ERROR, (event, data)=>{
17
- console.log(event);
18
- console.log(data);
17
+ const instance = new hls_0();
18
+ let hasRetriedNetworkError = false;
19
+ let hasRecoveredMediaError = false;
20
+ hls = instance;
21
+ instance.loadSource(src);
22
+ instance.attachMedia(player);
23
+ instance.on(hls_0.Events.ERROR, (_event, data)=>{
24
+ onHlsErrorLatest(data);
25
+ if (!data.fatal) return;
26
+ if (data.type === ErrorTypes.NETWORK_ERROR && !hasRetriedNetworkError) {
27
+ hasRetriedNetworkError = true;
28
+ instance.startLoad();
29
+ return;
30
+ }
31
+ if (data.type === ErrorTypes.MEDIA_ERROR && !hasRecoveredMediaError) {
32
+ hasRecoveredMediaError = true;
33
+ instance.recoverMediaError();
34
+ return;
35
+ }
36
+ instance.destroy();
37
+ if (hls === instance) hls = null;
19
38
  });
20
39
  } else if (player.canPlayType("application/vnd.apple.mpegurl")) player.src = src;
40
+ else onHlsUnsupportedLatest();
21
41
  return ()=>{
22
- if (hls) hls.destroy();
23
- if (player) {
24
- player.src = "";
25
- player.load();
26
- }
42
+ null == hls || hls.destroy();
43
+ player.removeAttribute("src");
44
+ player.load();
27
45
  };
28
46
  }, [
29
47
  src
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepsea-components",
3
- "version": "5.18.13",
3
+ "version": "5.18.14",
4
4
  "description": "格数科技自用组件库",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,49 +1,65 @@
1
1
  "use client"
2
2
 
3
- import { type ComponentProps, type FC, useEffect, useImperativeHandle, useRef } from "react"
3
+ import { type ComponentProps, type FC, useEffect, useEffectEvent, useImperativeHandle, useRef } from "react"
4
4
 
5
- import Hls from "hls.js"
5
+ import { optionalFn } from "deepsea-tools"
6
+ import Hls, { type ErrorData, ErrorTypes } from "hls.js"
6
7
 
7
- export interface HlsPlayerProps extends Omit<ComponentProps<"video">, "src" | "children"> {
8
- src: string
8
+ export interface HlsPlayerProps extends Omit<ComponentProps<"video">, "children"> {
9
+ onHlsError?: (data: ErrorData) => void
10
+ onHlsUnsupported?: () => void
9
11
  }
10
12
 
11
- export const HlsPlayer: FC<HlsPlayerProps> = ({ ref, src, ...rest }) => {
13
+ export const HlsPlayer: FC<HlsPlayerProps> = ({ ref, src: source, onHlsError, onHlsUnsupported, ...rest }) => {
12
14
  const video = useRef<HTMLVideoElement>(null)
13
15
 
14
16
  useImperativeHandle(ref, () => video.current!, [])
15
17
 
18
+ const src = source?.trim()
19
+ const onHlsErrorLatest = useEffectEvent(optionalFn(onHlsError))
20
+ const onHlsUnsupportedLatest = useEffectEvent(optionalFn(onHlsUnsupported))
21
+
16
22
  useEffect(() => {
17
23
  const { current: player } = video
18
24
  if (!player || !src) return
19
25
 
20
26
  let hls: Hls | null = null
21
27
 
22
- // 1. 优先检查是否支持 hls.js (MSE 模式)
23
- // 这将覆盖 Chrome, Firefox, Edge 等现代浏览器,绕过它们不成熟或过于严格的原生 HLS 引擎
24
28
  if (Hls.isSupported()) {
25
- hls = new Hls()
26
- hls.loadSource(src)
27
- hls.attachMedia(player)
28
-
29
- // 绑定错误监听以便调试
30
- hls.on(Hls.Events.ERROR, (event, data) => {
31
- console.log(event)
32
- console.log(data)
33
- })
34
- }
29
+ const instance = new Hls()
30
+ let hasRetriedNetworkError = false
31
+ let hasRecoveredMediaError = false
35
32
 
36
- // 2. 只有在 hls.js 不可用时,才尝试原生播放 (主要针对 iOS Safari 和 macOS Safari)
37
- else if (player.canPlayType("application/vnd.apple.mpegurl")) player.src = src
33
+ hls = instance
34
+ instance.loadSource(src)
35
+ instance.attachMedia(player)
38
36
 
39
- return () => {
40
- if (hls) hls.destroy()
37
+ instance.on(Hls.Events.ERROR, (_event, data) => {
38
+ onHlsErrorLatest(data)
39
+ if (!data.fatal) return
40
+
41
+ if (data.type === ErrorTypes.NETWORK_ERROR && !hasRetriedNetworkError) {
42
+ hasRetriedNetworkError = true
43
+ instance.startLoad()
44
+ return
45
+ }
41
46
 
42
- // 清理原生 src,防止切换地址时内存泄漏
43
- if (player) {
44
- player.src = ""
45
- player.load()
46
- }
47
+ if (data.type === ErrorTypes.MEDIA_ERROR && !hasRecoveredMediaError) {
48
+ hasRecoveredMediaError = true
49
+ instance.recoverMediaError()
50
+ return
51
+ }
52
+
53
+ instance.destroy()
54
+ if (hls === instance) hls = null
55
+ })
56
+ } else if (player.canPlayType("application/vnd.apple.mpegurl")) player.src = src
57
+ else onHlsUnsupportedLatest()
58
+
59
+ return () => {
60
+ hls?.destroy()
61
+ player.removeAttribute("src")
62
+ player.load()
47
63
  }
48
64
  }, [src])
49
65