@nikelroot/video-player 0.2.10 → 0.3.0

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.
package/dist/index.cjs CHANGED
@@ -37,10 +37,98 @@ __export(index_exports, {
37
37
  module.exports = __toCommonJS(index_exports);
38
38
 
39
39
  // src/VideoPlayer.tsx
40
- var import_react3 = require("react");
40
+ var import_react4 = require("react");
41
+
42
+ // src/useAudioFallback.ts
43
+ var import_react = require("react");
44
+ function useAudioFallback(options) {
45
+ const latest = (0, import_react.useRef)(options);
46
+ latest.current = options;
47
+ const [videoOnly, setVideoOnly] = (0, import_react.useState)(false);
48
+ const mode = (0, import_react.useRef)(false);
49
+ const cooldown = (0, import_react.useRef)(0);
50
+ const audioErrors = (0, import_react.useRef)(0);
51
+ const audioErrorTimer = (0, import_react.useRef)(null);
52
+ const snapshot = (0, import_react.useRef)(null);
53
+ const switchSource = (0, import_react.useCallback)((next, failure = false) => {
54
+ const { video, fallback, onChange } = latest.current;
55
+ const element = video.current;
56
+ if (!fallback || !element || mode.current === next) return false;
57
+ snapshot.current = {
58
+ time: Number.isFinite(element.currentTime) ? element.currentTime : 0,
59
+ playing: latest.current.playingIntent.current,
60
+ rate: element.playbackRate,
61
+ volume: element.volume,
62
+ muted: element.muted
63
+ };
64
+ mode.current = next;
65
+ audioErrors.current = 0;
66
+ if (audioErrorTimer.current) clearTimeout(audioErrorTimer.current);
67
+ audioErrorTimer.current = null;
68
+ if (failure) cooldown.current = Date.now() + 15e3;
69
+ setVideoOnly(next);
70
+ onChange == null ? void 0 : onChange(next);
71
+ return true;
72
+ }, []);
73
+ const onAudioError = (0, import_react.useCallback)((data) => {
74
+ var _a, _b, _c;
75
+ if (!latest.current.fallback || mode.current) return false;
76
+ const isAudio = ((_a = data == null ? void 0 : data.frag) == null ? void 0 : _a.type) === "audio" || (data == null ? void 0 : data.parent) === "audio" || ((_b = data == null ? void 0 : data.context) == null ? void 0 : _b.type) === "audioTrack" || /^audioTrack/.test((data == null ? void 0 : data.details) || "");
77
+ if (!isAudio) return false;
78
+ if ((data == null ? void 0 : data.details) === "fragGap" && ((_c = latest.current.ranges) == null ? void 0 : _c.some((range) => {
79
+ var _a2, _b2;
80
+ const time = (_b2 = (_a2 = latest.current.video.current) == null ? void 0 : _a2.currentTime) != null ? _b2 : 0;
81
+ return time >= range.start - 0.05 && time < range.end - 0.05;
82
+ }))) return true;
83
+ audioErrors.current++;
84
+ if ((data == null ? void 0 : data.fatal) || audioErrors.current >= 2) return switchSource(true, true);
85
+ if (!audioErrorTimer.current) {
86
+ audioErrorTimer.current = setTimeout(() => {
87
+ audioErrorTimer.current = null;
88
+ switchSource(true, true);
89
+ }, 8e3);
90
+ }
91
+ return true;
92
+ }, [switchSource]);
93
+ const onAudioProgress = (0, import_react.useCallback)(() => {
94
+ audioErrors.current = 0;
95
+ if (audioErrorTimer.current) clearTimeout(audioErrorTimer.current);
96
+ audioErrorTimer.current = null;
97
+ }, []);
98
+ (0, import_react.useEffect)(() => {
99
+ mode.current = false;
100
+ setVideoOnly(false);
101
+ snapshot.current = null;
102
+ cooldown.current = 0;
103
+ onAudioProgress();
104
+ return onAudioProgress;
105
+ }, [options.primary, options.fallback, onAudioProgress]);
106
+ (0, import_react.useEffect)(() => {
107
+ const check = () => {
108
+ const { ranges, video, fallback } = latest.current;
109
+ if (!fallback || !ranges || snapshot.current) return;
110
+ const element = video.current;
111
+ if (!element) return;
112
+ const time = element.currentTime;
113
+ const available = ranges.some((range) => time >= range.start - 0.05 && time < range.end - 0.05);
114
+ if (!mode.current && !available) switchSource(true);
115
+ else if (mode.current && available && Date.now() >= cooldown.current && ranges.some((range) => time >= range.start - 0.05 && time + 4 <= range.end)) switchSource(false);
116
+ };
117
+ const timer = setInterval(check, 500);
118
+ return () => clearInterval(timer);
119
+ }, [switchSource]);
120
+ return {
121
+ videoOnly,
122
+ source: videoOnly && options.fallback ? options.fallback : options.primary,
123
+ snapshot,
124
+ switchSource,
125
+ onAudioError,
126
+ onAudioProgress
127
+ };
128
+ }
41
129
 
42
130
  // src/controls.tsx
43
- var import_react2 = require("react");
131
+ var import_react3 = require("react");
44
132
 
45
133
  // src/styles.ts
46
134
  var import_styled_components = require("styled-components");
@@ -180,6 +268,18 @@ var VideoPlayerStyles = import_styled_components.styled.div`
180
268
  align-items: center;
181
269
  }
182
270
 
271
+ .video-audio-status {
272
+ position: absolute;
273
+ top: 0.75rem;
274
+ left: 0.75rem;
275
+ padding: 0.35rem 0.6rem;
276
+ color: inherit;
277
+ background: rgb(24 27 31 / 85%);
278
+ border-radius: 0.25rem;
279
+ font-size: 0.75rem;
280
+ pointer-events: none;
281
+ }
282
+
183
283
  .video-error-overlay {
184
284
  position: absolute;
185
285
  inset: 0;
@@ -326,7 +426,7 @@ var SeekSliderStyled = import_styled_components.styled.div`
326
426
  `;
327
427
 
328
428
  // src/utils.ts
329
- var import_react = require("react");
429
+ var import_react2 = require("react");
330
430
  var formatTime = (seconds) => {
331
431
  const totalSeconds = Number.parseInt(String(seconds), 10);
332
432
  const safeSeconds = Number.isFinite(totalSeconds) ? totalSeconds : 0;
@@ -387,9 +487,9 @@ var getSnapshot = () => {
387
487
  };
388
488
  var getServerSnapshot = () => 0;
389
489
  function useWindowWidth(mobileLimit = 768) {
390
- const width = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
490
+ const width = (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
391
491
  const isMobile = width <= mobileLimit;
392
- const mobileType = (0, import_react.useMemo)(() => {
492
+ const mobileType = (0, import_react2.useMemo)(() => {
393
493
  if (width <= mobileLimit) return "mobile";
394
494
  if (width <= 1024) return "laptop";
395
495
  return "default";
@@ -430,7 +530,7 @@ var createThrottledNumberFn = (fn, waitMs) => {
430
530
  // src/controls.tsx
431
531
  var import_jsx_runtime = require("react/jsx-runtime");
432
532
  var SeekSlider = ({ playAction, duration, currentTime, seekSetTime }) => {
433
- const ref = (0, import_react2.useRef)(null);
533
+ const ref = (0, import_react3.useRef)(null);
434
534
  const clickHandler = (e) => {
435
535
  e.preventDefault();
436
536
  e.stopPropagation();
@@ -844,56 +944,67 @@ var VideoPlayerBase = (props, ref) => {
844
944
  messages: messagesProp,
845
945
  accentColor,
846
946
  videoSrc: rawVideoSrc = "",
947
+ videoOnlySrc,
948
+ audioRanges,
949
+ onAudioFallbackChange,
847
950
  ...videoProps
848
951
  } = props;
849
- const videoSrc = rawVideoSrc.replaceAll(" ", "%20").replaceAll("#", "%23");
850
- const messages = (0, import_react3.useMemo)(() => ({ ...defaultMessages, ...messagesProp }), [messagesProp]);
952
+ const primarySrc = rawVideoSrc.replaceAll(" ", "%20").replaceAll("#", "%23");
953
+ const propsRef = (0, import_react4.useRef)(props);
954
+ propsRef.current = props;
955
+ const messages = (0, import_react4.useMemo)(() => ({ ...defaultMessages, ...messagesProp }), [messagesProp]);
851
956
  const [, isMobile, mobileType] = useWindowWidth();
852
- const videoRef = (0, import_react3.useRef)(null);
853
- const hlsRef = (0, import_react3.useRef)(null);
854
- const containerRef = (0, import_react3.useRef)(null);
855
- const netRetryCount = (0, import_react3.useRef)(0);
856
- const mediaRecoverCount = (0, import_react3.useRef)(0);
857
- const fatalReloadCount = (0, import_react3.useRef)(0);
858
- const reloadTimer = (0, import_react3.useRef)(null);
859
- const stalledNudgeTimer = (0, import_react3.useRef)(null);
860
- const liveStabilityMode = (0, import_react3.useRef)(false);
861
- const liveStallEvents = (0, import_react3.useRef)([]);
862
- const controlTime = (0, import_react3.useRef)(null);
863
- const sourceLoadId = (0, import_react3.useRef)(0);
864
- const sourceLoadMode = (0, import_react3.useRef)("native");
865
- const pendingPlay = (0, import_react3.useRef)(false);
866
- const playRequestInFlight = (0, import_react3.useRef)(false);
867
- const [playingState, setPlayingState] = (0, import_react3.useState)(!!defaultPlaying);
868
- const [mutedState, setMutedState] = (0, import_react3.useState)(!!defaultMuted);
869
- const [durationState, setDurationState] = (0, import_react3.useState)(0);
870
- const [currentTimeState, setCurrentTimeState] = (0, import_react3.useState)(0);
871
- const [isFullscreen, setIsFullscreen] = (0, import_react3.useState)(false);
872
- const [showControl, setControlVisible] = (0, import_react3.useState)(true);
873
- const [errorState, setErrorState] = (0, import_react3.useState)(null);
874
- const [reloadToken, setReloadToken] = (0, import_react3.useState)(0);
875
- const showControlRef = (0, import_react3.useRef)(showControl);
957
+ const videoRef = (0, import_react4.useRef)(null);
958
+ const playbackIntent = (0, import_react4.useRef)(autoPlay || defaultPlaying || Boolean(playingProp));
959
+ const audioFallback = useAudioFallback({ primary: primarySrc, fallback: videoOnlySrc, ranges: audioRanges, video: videoRef, playingIntent: playbackIntent, onChange: onAudioFallbackChange });
960
+ const videoSrc = audioFallback.source;
961
+ const { snapshot: resumeSnapshot, onAudioError, onAudioProgress, switchSource } = audioFallback;
962
+ const hlsRef = (0, import_react4.useRef)(null);
963
+ const containerRef = (0, import_react4.useRef)(null);
964
+ const lastProgressTime = (0, import_react4.useRef)(0);
965
+ const netRetryCount = (0, import_react4.useRef)(0);
966
+ const mediaRecoverCount = (0, import_react4.useRef)(0);
967
+ const fatalReloadCount = (0, import_react4.useRef)(0);
968
+ const reloadTimer = (0, import_react4.useRef)(null);
969
+ const stalledNudgeTimer = (0, import_react4.useRef)(null);
970
+ const liveStabilityMode = (0, import_react4.useRef)(false);
971
+ const liveStallEvents = (0, import_react4.useRef)([]);
972
+ const controlTime = (0, import_react4.useRef)(null);
973
+ const sourceLoadId = (0, import_react4.useRef)(0);
974
+ const sourceLoadMode = (0, import_react4.useRef)("native");
975
+ const pendingPlay = (0, import_react4.useRef)(false);
976
+ const playRequestInFlight = (0, import_react4.useRef)(false);
977
+ const playRequestId = (0, import_react4.useRef)(0);
978
+ const [playingState, setPlayingState] = (0, import_react4.useState)(!!defaultPlaying);
979
+ const [mutedState, setMutedState] = (0, import_react4.useState)(!!defaultMuted);
980
+ const [durationState, setDurationState] = (0, import_react4.useState)(0);
981
+ const [currentTimeState, setCurrentTimeState] = (0, import_react4.useState)(0);
982
+ const [isFullscreen, setIsFullscreen] = (0, import_react4.useState)(false);
983
+ const [showControl, setControlVisible] = (0, import_react4.useState)(true);
984
+ const [errorState, setErrorState] = (0, import_react4.useState)(null);
985
+ const [reloadToken, setReloadToken] = (0, import_react4.useState)(0);
986
+ const showControlRef = (0, import_react4.useRef)(showControl);
876
987
  const playing = playingProp != null ? playingProp : playingState;
877
988
  const muted = mutedProp != null ? mutedProp : mutedState;
878
989
  const isDurationControlled = durationProp !== void 0;
879
990
  const duration = durationProp != null ? durationProp : durationState;
880
991
  const currentTime = currentTimeState;
881
992
  const fullscreenAllowed = active != null ? active : true;
882
- const onTimeChangeRef = (0, import_react3.useRef)(onTimeChange);
883
- const onDurationChangeRef = (0, import_react3.useRef)(onDurationChange);
993
+ const onTimeChangeRef = (0, import_react4.useRef)(onTimeChange);
994
+ const onDurationChangeRef = (0, import_react4.useRef)(onDurationChange);
884
995
  onTimeChangeRef.current = onTimeChange;
885
996
  onDurationChangeRef.current = onDurationChange;
886
997
  showControlRef.current = showControl;
887
998
  const { currentTime: _ignoredCurrentTime, ...domVideoProps } = videoProps;
888
- const setTimeD = (0, import_react3.useRef)(
999
+ const setTimeD = (0, import_react4.useRef)(
889
1000
  createThrottledNumberFn((value) => {
890
1001
  const v = videoRef.current;
891
1002
  if (!v) return;
892
1003
  v.currentTime = value;
893
1004
  }, 30)
894
1005
  );
895
- const setCurrentTimeUi = (0, import_react3.useRef)(createThrottledNumberFn((value) => setCurrentTimeState(value), 250));
896
- const clearTimers = (0, import_react3.useCallback)(() => {
1006
+ const setCurrentTimeUi = (0, import_react4.useRef)(createThrottledNumberFn((value) => setCurrentTimeState(value), 250));
1007
+ const clearTimers = (0, import_react4.useCallback)(() => {
897
1008
  if (reloadTimer.current) {
898
1009
  clearTimeout(reloadTimer.current);
899
1010
  reloadTimer.current = null;
@@ -907,9 +1018,11 @@ var VideoPlayerBase = (props, ref) => {
907
1018
  controlTime.current = null;
908
1019
  }
909
1020
  }, []);
910
- const resetMediaForSourceChange = (0, import_react3.useCallback)(() => {
1021
+ const resetMediaForSourceChange = (0, import_react4.useCallback)(() => {
911
1022
  clearTimers();
912
1023
  pendingPlay.current = false;
1024
+ playRequestId.current++;
1025
+ playRequestInFlight.current = false;
913
1026
  if (hlsRef.current) {
914
1027
  hlsRef.current.destroy();
915
1028
  hlsRef.current = null;
@@ -920,7 +1033,7 @@ var VideoPlayerBase = (props, ref) => {
920
1033
  video.removeAttribute("src");
921
1034
  video.load();
922
1035
  }, [clearTimers]);
923
- const releaseNativeMedia = (0, import_react3.useCallback)(() => {
1036
+ const releaseNativeMedia = (0, import_react4.useCallback)(() => {
924
1037
  const video = videoRef.current;
925
1038
  if (!video) return;
926
1039
  pendingPlay.current = false;
@@ -929,7 +1042,7 @@ var VideoPlayerBase = (props, ref) => {
929
1042
  video.removeAttribute("src");
930
1043
  video.load();
931
1044
  }, []);
932
- const ensureNativeMediaAttached = (0, import_react3.useCallback)(() => {
1045
+ const ensureNativeMediaAttached = (0, import_react4.useCallback)(() => {
933
1046
  const video = videoRef.current;
934
1047
  if (!video || sourceLoadMode.current !== "native" || isVideoSourceAttached(video)) return false;
935
1048
  video.src = videoSrc;
@@ -937,27 +1050,30 @@ var VideoPlayerBase = (props, ref) => {
937
1050
  video.load();
938
1051
  return true;
939
1052
  }, [initialTime, videoSrc]);
940
- const setNextPlaying = (0, import_react3.useCallback)(
1053
+ const setNextPlaying = (0, import_react4.useCallback)(
941
1054
  (value) => {
942
- if (playingProp === void 0) setPlayingState(value);
943
- onPlayingChange == null ? void 0 : onPlayingChange(value);
1055
+ var _a, _b;
1056
+ if (propsRef.current.playing === void 0) setPlayingState(value);
1057
+ (_b = (_a = propsRef.current).onPlayingChange) == null ? void 0 : _b.call(_a, value);
944
1058
  },
945
- [onPlayingChange, playingProp]
1059
+ []
946
1060
  );
947
- const setNextMuted = (0, import_react3.useCallback)(
1061
+ const setNextMuted = (0, import_react4.useCallback)(
948
1062
  (value) => {
949
- if (mutedProp === void 0) setMutedState(value);
1063
+ var _a, _b;
1064
+ if (propsRef.current.muted === void 0) setMutedState(value);
950
1065
  const el = videoRef.current;
951
1066
  if (el) el.muted = value;
952
- onMutedChange == null ? void 0 : onMutedChange(value);
1067
+ (_b = (_a = propsRef.current).onMutedChange) == null ? void 0 : _b.call(_a, value);
953
1068
  },
954
- [mutedProp, onMutedChange]
1069
+ []
955
1070
  );
956
- const clearErrorState = (0, import_react3.useCallback)(() => {
1071
+ const clearErrorState = (0, import_react4.useCallback)(() => {
957
1072
  setErrorState((prev) => prev ? null : prev);
958
1073
  }, []);
959
- const reportError = (0, import_react3.useCallback)(
1074
+ const reportError = (0, import_react4.useCallback)(
960
1075
  (error, data, message = messages.defaultError) => {
1076
+ var _a, _b;
961
1077
  const details = formatPlaybackErrorDetails(error, data);
962
1078
  const code = getPlaybackErrorCodeText(error);
963
1079
  setNextPlaying(false);
@@ -969,25 +1085,32 @@ var VideoPlayerBase = (props, ref) => {
969
1085
  error,
970
1086
  data
971
1087
  });
972
- onPlaybackError == null ? void 0 : onPlaybackError({ error, data, message, details });
1088
+ (_b = (_a = propsRef.current).onPlaybackError) == null ? void 0 : _b.call(_a, { error, data, message, details });
973
1089
  },
974
- [messages.defaultError, onPlaybackError, setNextPlaying]
1090
+ [messages.defaultError, setNextPlaying]
975
1091
  );
976
- const notifyActiveChange = (0, import_react3.useCallback)(
1092
+ const notifyActiveChange = (0, import_react4.useCallback)(
977
1093
  (video, reason) => {
978
- onActiveChange == null ? void 0 : onActiveChange({ video, reason });
1094
+ var _a, _b;
1095
+ (_b = (_a = propsRef.current).onActiveChange) == null ? void 0 : _b.call(_a, { video, reason });
979
1096
  },
980
- [onActiveChange]
1097
+ []
981
1098
  );
982
- const onTime = (0, import_react3.useCallback)(() => {
1099
+ const onTime = (0, import_react4.useCallback)(() => {
983
1100
  var _a;
984
1101
  const el = videoRef.current;
985
1102
  if (!el) return;
986
1103
  const nextTime = Number.isFinite(el.currentTime) ? el.currentTime : 0;
1104
+ if (!el.paused && !el.seeking && nextTime > lastProgressTime.current + 0.5) {
1105
+ netRetryCount.current = 0;
1106
+ fatalReloadCount.current = 0;
1107
+ mediaRecoverCount.current = 0;
1108
+ lastProgressTime.current = nextTime;
1109
+ }
987
1110
  setCurrentTimeUi.current(nextTime);
988
1111
  (_a = onTimeChangeRef.current) == null ? void 0 : _a.call(onTimeChangeRef, nextTime, el);
989
1112
  }, []);
990
- const onDur = (0, import_react3.useCallback)(() => {
1113
+ const onDur = (0, import_react4.useCallback)(() => {
991
1114
  var _a;
992
1115
  const el = videoRef.current;
993
1116
  if (!el) return;
@@ -995,8 +1118,9 @@ var VideoPlayerBase = (props, ref) => {
995
1118
  if (!isDurationControlled) setDurationState(nextDuration);
996
1119
  (_a = onDurationChangeRef.current) == null ? void 0 : _a.call(onDurationChangeRef, nextDuration, el);
997
1120
  }, [isDurationControlled]);
998
- const setVideoEl = (0, import_react3.useCallback)(
1121
+ const setVideoEl = (0, import_react4.useCallback)(
999
1122
  (el) => {
1123
+ var _a, _b, _c;
1000
1124
  const prev = videoRef.current;
1001
1125
  if (prev === el) return;
1002
1126
  if (prev) {
@@ -1005,18 +1129,18 @@ var VideoPlayerBase = (props, ref) => {
1005
1129
  exclusiveMediaReleasers.delete(prev);
1006
1130
  }
1007
1131
  videoRef.current = el;
1008
- assignRef(externalVideoRef, el);
1009
- onVideoRefChange == null ? void 0 : onVideoRefChange(el);
1132
+ assignRef(propsRef.current.videoRef, el);
1133
+ (_b = (_a = propsRef.current).onVideoRefChange) == null ? void 0 : _b.call(_a, el);
1010
1134
  notifyActiveChange(el, "ref");
1011
1135
  if (!el) return;
1012
- el.muted = muted;
1136
+ el.muted = (_c = propsRef.current.muted) != null ? _c : mutedState;
1013
1137
  el.addEventListener("timeupdate", onTime);
1014
1138
  el.addEventListener("durationchange", onDur);
1015
1139
  exclusiveMediaReleasers.set(el, releaseNativeMedia);
1016
1140
  },
1017
- [externalVideoRef, muted, notifyActiveChange, onDur, onTime, onVideoRefChange, releaseNativeMedia]
1141
+ [notifyActiveChange, onDur, onTime, releaseNativeMedia]
1018
1142
  );
1019
- const pauseOtherVideos = (0, import_react3.useCallback)(
1143
+ const pauseOtherVideos = (0, import_react4.useCallback)(
1020
1144
  (el) => {
1021
1145
  if (!exclusivePlayback) return;
1022
1146
  if (typeof exclusivePlayback === "object") {
@@ -1032,20 +1156,25 @@ var VideoPlayerBase = (props, ref) => {
1032
1156
  },
1033
1157
  [exclusivePlayback]
1034
1158
  );
1035
- const playAction = (0, import_react3.useCallback)(async () => {
1159
+ const playAction = (0, import_react4.useCallback)(async () => {
1036
1160
  const el = videoRef.current;
1037
1161
  if (!el) return;
1162
+ const requestId = ++playRequestId.current;
1038
1163
  pendingPlay.current = true;
1164
+ playbackIntent.current = true;
1165
+ if (resumeSnapshot.current) resumeSnapshot.current.playing = true;
1039
1166
  pauseOtherVideos(el);
1040
1167
  ensureNativeMediaAttached();
1041
1168
  try {
1042
1169
  playRequestInFlight.current = true;
1043
1170
  await el.play();
1171
+ if (requestId !== playRequestId.current || videoRef.current !== el) return;
1044
1172
  pendingPlay.current = false;
1045
1173
  clearErrorState();
1046
1174
  setNextPlaying(true);
1047
1175
  notifyActiveChange(el, "play");
1048
1176
  } catch (e) {
1177
+ if (requestId !== playRequestId.current || videoRef.current !== el) return;
1049
1178
  if (isInterruptedPlayRequestError(e)) {
1050
1179
  pendingPlay.current = true;
1051
1180
  return;
@@ -1054,7 +1183,7 @@ var VideoPlayerBase = (props, ref) => {
1054
1183
  console.debug(e);
1055
1184
  reportError(e, { type: "play" }, messages.playFailed);
1056
1185
  } finally {
1057
- playRequestInFlight.current = false;
1186
+ if (requestId === playRequestId.current) playRequestInFlight.current = false;
1058
1187
  }
1059
1188
  if (scrollTo === true) {
1060
1189
  const rect = el.getBoundingClientRect();
@@ -1077,15 +1206,17 @@ var VideoPlayerBase = (props, ref) => {
1077
1206
  scrollTo,
1078
1207
  setNextPlaying
1079
1208
  ]);
1080
- const pauseAction = (0, import_react3.useCallback)(() => {
1209
+ const pauseAction = (0, import_react4.useCallback)(() => {
1081
1210
  const el = videoRef.current;
1082
1211
  if (!el) return;
1083
1212
  pendingPlay.current = false;
1213
+ if (resumeSnapshot.current) resumeSnapshot.current.playing = false;
1214
+ playbackIntent.current = false;
1084
1215
  el.pause();
1085
1216
  setNextPlaying(false);
1086
1217
  notifyActiveChange(el, "pause");
1087
1218
  }, [notifyActiveChange, setNextPlaying]);
1088
- const seekSetTime = (0, import_react3.useCallback)(
1219
+ const seekSetTime = (0, import_react4.useCallback)(
1089
1220
  (value) => {
1090
1221
  const el = videoRef.current;
1091
1222
  if (!el) return;
@@ -1097,7 +1228,7 @@ var VideoPlayerBase = (props, ref) => {
1097
1228
  },
1098
1229
  [duration, notifyActiveChange]
1099
1230
  );
1100
- const seekPrevAction = (0, import_react3.useCallback)(
1231
+ const seekPrevAction = (0, import_react4.useCallback)(
1101
1232
  (sec = 15) => {
1102
1233
  const el = videoRef.current;
1103
1234
  if (!el) return;
@@ -1105,7 +1236,7 @@ var VideoPlayerBase = (props, ref) => {
1105
1236
  },
1106
1237
  [seekSetTime]
1107
1238
  );
1108
- const seekNextAction = (0, import_react3.useCallback)(
1239
+ const seekNextAction = (0, import_react4.useCallback)(
1109
1240
  (sec = 15) => {
1110
1241
  const el = videoRef.current;
1111
1242
  if (!el) return;
@@ -1113,7 +1244,7 @@ var VideoPlayerBase = (props, ref) => {
1113
1244
  },
1114
1245
  [seekSetTime]
1115
1246
  );
1116
- const toggleAction = (0, import_react3.useCallback)(
1247
+ const toggleAction = (0, import_react4.useCallback)(
1117
1248
  (force) => {
1118
1249
  const el = videoRef.current;
1119
1250
  if (!el) return;
@@ -1125,12 +1256,12 @@ var VideoPlayerBase = (props, ref) => {
1125
1256
  },
1126
1257
  [pauseAction, playAction]
1127
1258
  );
1128
- const nudgeOnStall = (0, import_react3.useCallback)(() => {
1259
+ const nudgeOnStall = (0, import_react4.useCallback)(() => {
1129
1260
  const v = videoRef.current;
1130
1261
  if (!v) return;
1131
1262
  v.currentTime = Math.max(0, v.currentTime + 0.05);
1132
1263
  }, []);
1133
- const shouldSwitchLiveToStability = (0, import_react3.useCallback)(() => {
1264
+ const shouldSwitchLiveToStability = (0, import_react4.useCallback)(() => {
1134
1265
  if (!live || liveStabilityMode.current) return false;
1135
1266
  const now = Date.now();
1136
1267
  liveStallEvents.current = [...liveStallEvents.current.filter((ts) => now - ts <= LIVE_STALL_WINDOW_MS), now];
@@ -1139,7 +1270,7 @@ var VideoPlayerBase = (props, ref) => {
1139
1270
  liveStallEvents.current = [];
1140
1271
  return true;
1141
1272
  }, [live]);
1142
- const resolvedHlsConfig = (0, import_react3.useCallback)(() => {
1273
+ const resolvedHlsConfig = (0, import_react4.useCallback)(() => {
1143
1274
  const modeConfig = live ? liveHlsConfig : vodHlsConfig;
1144
1275
  const base = live ? confLiveStability : confVod;
1145
1276
  return withCredentialsConfig(
@@ -1151,8 +1282,8 @@ var VideoPlayerBase = (props, ref) => {
1151
1282
  hlsCredentials
1152
1283
  );
1153
1284
  }, [hlsConfig, hlsCredentials, live, liveHlsConfig, vodHlsConfig]);
1154
- const loadVideo = (0, import_react3.useCallback)(
1155
- async (startAt = initialTime, loadId = sourceLoadId.current) => {
1285
+ const loadVideo = (0, import_react4.useCallback)(
1286
+ async (startAt = ((_b) => (_b = ((_a) => (_a = resumeSnapshot.current) == null ? void 0 : _a.time)()) != null ? _b : initialTime)(), loadId = sourceLoadId.current) => {
1156
1287
  const startVideoRef = videoRef.current;
1157
1288
  if (!startVideoRef) return;
1158
1289
  sourceLoadMode.current = "hls";
@@ -1160,6 +1291,7 @@ var VideoPlayerBase = (props, ref) => {
1160
1291
  try {
1161
1292
  HlsCtor = await loadHlsCtor();
1162
1293
  } catch (error) {
1294
+ if (loadId !== sourceLoadId.current || videoRef.current !== startVideoRef) return;
1163
1295
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1164
1296
  return;
1165
1297
  }
@@ -1171,10 +1303,11 @@ var VideoPlayerBase = (props, ref) => {
1171
1303
  hlsRef.current = h;
1172
1304
  const isStaleLoad = () => loadId !== sourceLoadId.current || hlsRef.current !== h || videoRef.current !== video;
1173
1305
  h.on(HlsCtor.Events.ERROR, (_evt, data) => {
1174
- var _a, _b;
1306
+ var _a2, _b2;
1175
1307
  if (isStaleLoad()) return;
1176
1308
  const { type: errorType, details, fatal } = data;
1177
- if (details === HlsCtor.ErrorDetails.BUFFER_APPEND_ERROR || details === "bufferAppendingError") return;
1309
+ if (onAudioError(data)) return;
1310
+ if (!fatal && (details === HlsCtor.ErrorDetails.BUFFER_APPEND_ERROR || details === "bufferAppendingError")) return;
1178
1311
  if (!fatal) {
1179
1312
  switch (details) {
1180
1313
  case HlsCtor.ErrorDetails.BUFFER_STALLED_ERROR:
@@ -1186,7 +1319,7 @@ var VideoPlayerBase = (props, ref) => {
1186
1319
  }, 200);
1187
1320
  }
1188
1321
  if (shouldSwitchLiveToStability()) {
1189
- const resumeTime2 = ((_a = videoRef.current) == null ? void 0 : _a.currentTime) || 0;
1322
+ const resumeTime2 = ((_a2 = videoRef.current) == null ? void 0 : _a2.currentTime) || 0;
1190
1323
  clearTimers();
1191
1324
  reloadTimer.current = setTimeout(() => {
1192
1325
  if (hlsRef.current) {
@@ -1201,7 +1334,7 @@ var VideoPlayerBase = (props, ref) => {
1201
1334
  return;
1202
1335
  }
1203
1336
  }
1204
- const resumeTime = ((_b = videoRef.current) == null ? void 0 : _b.currentTime) || 0;
1337
+ const resumeTime = ((_b2 = videoRef.current) == null ? void 0 : _b2.currentTime) || 0;
1205
1338
  if (errorType === HlsCtor.ErrorTypes.NETWORK_ERROR) {
1206
1339
  if (netRetryCount.current < MAX_NET_RETRIES) {
1207
1340
  netRetryCount.current += 1;
@@ -1265,21 +1398,25 @@ var VideoPlayerBase = (props, ref) => {
1265
1398
  });
1266
1399
  h.on(HlsCtor.Events.MANIFEST_PARSED, () => {
1267
1400
  if (isStaleLoad()) return;
1268
- fatalReloadCount.current = 0;
1269
- netRetryCount.current = 0;
1270
- mediaRecoverCount.current = 0;
1271
- if (!live && startAt > 0) {
1401
+ if (startAt > 0) {
1272
1402
  h.startLoad(startAt);
1273
1403
  video.currentTime = startAt;
1274
1404
  } else {
1275
1405
  h.startLoad();
1276
1406
  }
1277
- if (autoPlay) void playAction();
1407
+ if (resumeSnapshot.current ? resumeSnapshot.current.playing : autoPlay) void playAction();
1408
+ });
1409
+ h.on(HlsCtor.Events.FRAG_BUFFERED, (_evt, data) => {
1410
+ if (isStaleLoad()) return;
1411
+ if (data.frag.type === "audio") onAudioProgress();
1278
1412
  });
1279
1413
  h.attachMedia(video);
1280
1414
  },
1281
1415
  [
1282
1416
  autoPlay,
1417
+ onAudioError,
1418
+ onAudioProgress,
1419
+ resumeSnapshot,
1283
1420
  clearErrorState,
1284
1421
  clearTimers,
1285
1422
  initialTime,
@@ -1294,21 +1431,23 @@ var VideoPlayerBase = (props, ref) => {
1294
1431
  videoSrc
1295
1432
  ]
1296
1433
  );
1297
- const loadVideoNative = (0, import_react3.useCallback)(
1434
+ const loadVideoNative = (0, import_react4.useCallback)(
1298
1435
  (loadId = sourceLoadId.current, options) => {
1436
+ var _a, _b;
1299
1437
  if (loadId !== sourceLoadId.current) return;
1300
1438
  const video = videoRef.current;
1301
1439
  if (!video) return;
1302
1440
  sourceLoadMode.current = "native";
1303
1441
  video.src = videoSrc;
1304
1442
  if (!(options == null ? void 0 : options.metadataOnly)) {
1305
- video.currentTime = initialTime;
1306
- if (autoPlay) void playAction();
1443
+ video.currentTime = (_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime;
1444
+ if (resumeSnapshot.current ? resumeSnapshot.current.playing : autoPlay) void playAction();
1307
1445
  }
1308
1446
  },
1309
1447
  [autoPlay, initialTime, playAction, videoSrc]
1310
1448
  );
1311
- const loadVideoHls = (0, import_react3.useCallback)(async (loadId = sourceLoadId.current) => {
1449
+ const loadVideoHls = (0, import_react4.useCallback)(async (loadId = sourceLoadId.current) => {
1450
+ var _a, _b;
1312
1451
  const video = videoRef.current;
1313
1452
  const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
1314
1453
  sourceLoadMode.current = "hls";
@@ -1316,13 +1455,14 @@ var VideoPlayerBase = (props, ref) => {
1316
1455
  try {
1317
1456
  HlsCtor = await loadHlsCtor();
1318
1457
  } catch (error) {
1458
+ if (loadId !== sourceLoadId.current || videoRef.current !== video) return;
1319
1459
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1320
1460
  return;
1321
1461
  }
1322
1462
  if (loadId !== sourceLoadId.current) return;
1323
1463
  if (!videoRef.current || videoRef.current !== video) return;
1324
1464
  if (HlsCtor.isSupported()) {
1325
- void loadVideo(initialTime, loadId);
1465
+ void loadVideo((_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime, loadId);
1326
1466
  return;
1327
1467
  }
1328
1468
  if (canNativeHls) {
@@ -1331,7 +1471,8 @@ var VideoPlayerBase = (props, ref) => {
1331
1471
  }
1332
1472
  reportError(null, { type: "hls", src: videoSrc, reason: "HLS is not supported in this browser" }, messages.unsupported);
1333
1473
  }, [initialTime, loadVideo, loadVideoNative, messages.streamLoadFailed, messages.unsupported, reportError, videoSrc]);
1334
- const destroy = (0, import_react3.useCallback)(() => {
1474
+ const destroy = (0, import_react4.useCallback)(() => {
1475
+ var _a, _b;
1335
1476
  clearTimers();
1336
1477
  if (hlsRef.current) {
1337
1478
  hlsRef.current.destroy();
@@ -1347,27 +1488,25 @@ var VideoPlayerBase = (props, ref) => {
1347
1488
  if (activeExclusiveVideo === v) activeExclusiveVideo = null;
1348
1489
  }
1349
1490
  videoRef.current = null;
1350
- onVideoRefChange == null ? void 0 : onVideoRefChange(null);
1491
+ (_b = (_a = propsRef.current).onVideoRefChange) == null ? void 0 : _b.call(_a, null);
1351
1492
  notifyActiveChange(null, "destroy");
1352
1493
  setNextPlaying(false);
1353
- if (durationProp === void 0) setDurationState(0);
1494
+ if (propsRef.current.duration === void 0) setDurationState(0);
1354
1495
  setCurrentTimeUi.current.cancel();
1355
1496
  setCurrentTimeState(0);
1356
1497
  }, [
1357
1498
  clearTimers,
1358
- durationProp,
1359
1499
  notifyActiveChange,
1360
1500
  onDur,
1361
1501
  onTime,
1362
- onVideoRefChange,
1363
1502
  setNextPlaying
1364
1503
  ]);
1365
- const videoClickHandler = (0, import_react3.useCallback)(() => {
1504
+ const videoClickHandler = (0, import_react4.useCallback)(() => {
1366
1505
  if (!handleClick) return;
1367
1506
  if (playOnClick) toggleAction();
1368
1507
  onVideoClick == null ? void 0 : onVideoClick();
1369
1508
  }, [handleClick, onVideoClick, playOnClick, toggleAction]);
1370
- const fullScreenAction = (0, import_react3.useCallback)(() => {
1509
+ const fullScreenAction = (0, import_react4.useCallback)(() => {
1371
1510
  if (typeof document === "undefined") return;
1372
1511
  const doc = document;
1373
1512
  const videoEl = videoRef.current;
@@ -1392,33 +1531,51 @@ var VideoPlayerBase = (props, ref) => {
1392
1531
  else if (videoEl.webkitEnterFullscreen) void videoEl.webkitEnterFullscreen();
1393
1532
  }
1394
1533
  }, [fullscreenAllowed]);
1395
- const videoDbClickHandler = (0, import_react3.useCallback)(() => {
1534
+ const videoDbClickHandler = (0, import_react4.useCallback)(() => {
1396
1535
  if (!handleClick) return;
1397
1536
  fullScreenAction();
1398
1537
  onVideoDoubleClick == null ? void 0 : onVideoDoubleClick();
1399
1538
  }, [fullScreenAction, handleClick, onVideoDoubleClick]);
1400
- const showClickHandler = (0, import_react3.useCallback)(() => {
1539
+ const showClickHandler = (0, import_react4.useCallback)(() => {
1401
1540
  setControlVisible((st) => !st);
1402
1541
  }, []);
1403
- const retryLoadHandler = (0, import_react3.useCallback)(() => {
1542
+ const retryLoadHandler = (0, import_react4.useCallback)(() => {
1404
1543
  clearErrorState();
1405
1544
  setReloadToken((value) => value + 1);
1406
1545
  }, [clearErrorState]);
1407
- const videoErrorHandler = (0, import_react3.useCallback)(() => {
1546
+ const videoErrorHandler = (0, import_react4.useCallback)(() => {
1408
1547
  const video = videoRef.current;
1409
1548
  const error = video == null ? void 0 : video.error;
1410
1549
  const src = (video == null ? void 0 : video.currentSrc) || videoSrc;
1411
1550
  if (hlsRef.current && src.startsWith("blob:")) return;
1551
+ if (switchSource(true, true)) return;
1412
1552
  pendingPlay.current = false;
1413
1553
  reportError(error, { type: "native", src }, getNativeVideoErrorMessage(error, messages));
1414
- }, [messages, reportError, videoSrc]);
1415
- const videoLoadedHandler = (0, import_react3.useCallback)(() => {
1554
+ }, [messages, reportError, switchSource, videoSrc]);
1555
+ const videoLoadedHandler = (0, import_react4.useCallback)(() => {
1416
1556
  clearErrorState();
1557
+ const saved = resumeSnapshot.current;
1558
+ const element = videoRef.current;
1559
+ if (saved && element && element.readyState >= HTMLMediaElement.HAVE_METADATA) {
1560
+ let time = saved.time;
1561
+ if (element.seekable.length) {
1562
+ const start = element.seekable.start(0);
1563
+ const end = element.seekable.end(element.seekable.length - 1);
1564
+ time = Math.max(start, Math.min(time, Math.max(start, end - 0.05)));
1565
+ }
1566
+ element.currentTime = time;
1567
+ element.playbackRate = saved.rate;
1568
+ element.volume = saved.volume;
1569
+ element.muted = saved.muted;
1570
+ resumeSnapshot.current = null;
1571
+ if (saved.playing) void playAction();
1572
+ else pauseAction();
1573
+ }
1417
1574
  if (playRequestInFlight.current) return;
1418
1575
  if (!pendingPlay.current || active === false || !canAttemptPlayback(videoRef.current)) return;
1419
1576
  void playAction();
1420
- }, [active, clearErrorState, playAction]);
1421
- const mouseMoveHandler = (0, import_react3.useCallback)(() => {
1577
+ }, [active, clearErrorState, playAction, pauseAction, resumeSnapshot]);
1578
+ const mouseMoveHandler = (0, import_react4.useCallback)(() => {
1422
1579
  if (controlTime.current) clearTimeout(controlTime.current);
1423
1580
  if (!showControlRef.current) {
1424
1581
  showControlRef.current = true;
@@ -1429,7 +1586,7 @@ var VideoPlayerBase = (props, ref) => {
1429
1586
  setControlVisible(false);
1430
1587
  }, 1e3 * 10);
1431
1588
  }, []);
1432
- (0, import_react3.useImperativeHandle)(
1589
+ (0, import_react4.useImperativeHandle)(
1433
1590
  ref,
1434
1591
  () => ({
1435
1592
  play: playAction,
@@ -1440,22 +1597,26 @@ var VideoPlayerBase = (props, ref) => {
1440
1597
  }),
1441
1598
  [fullScreenAction, pauseAction, playAction, seekSetTime]
1442
1599
  );
1443
- (0, import_react3.useEffect)(() => {
1600
+ (0, import_react4.useEffect)(() => {
1444
1601
  const el = videoRef.current;
1445
1602
  if (!el) return;
1446
1603
  el.muted = muted;
1447
1604
  }, [muted]);
1448
- (0, import_react3.useEffect)(() => {
1605
+ (0, import_react4.useEffect)(() => {
1449
1606
  if (playingProp === void 0) return;
1450
1607
  if (playingProp) void playAction();
1451
1608
  else pauseAction();
1452
1609
  }, [pauseAction, playAction, playingProp]);
1453
- (0, import_react3.useEffect)(() => {
1610
+ (0, import_react4.useEffect)(() => {
1454
1611
  if (active !== false) return;
1455
1612
  releaseNativeMedia();
1456
1613
  }, [active, releaseNativeMedia]);
1457
- (0, import_react3.useEffect)(() => {
1614
+ const sourceLoaders = (0, import_react4.useRef)({ loadVideo, loadVideoHls, loadVideoNative });
1615
+ sourceLoaders.current = { loadVideo, loadVideoHls, loadVideoNative };
1616
+ (0, import_react4.useEffect)(() => {
1617
+ var _a, _b, _c, _d;
1458
1618
  if (!videoRef.current) return;
1619
+ const { loadVideo: loadVideo2, loadVideoHls: loadVideoHls2, loadVideoNative: loadVideoNative2 } = sourceLoaders.current;
1459
1620
  const loadId = sourceLoadId.current + 1;
1460
1621
  sourceLoadId.current = loadId;
1461
1622
  clearErrorState();
@@ -1464,20 +1625,21 @@ var VideoPlayerBase = (props, ref) => {
1464
1625
  mediaRecoverCount.current = 0;
1465
1626
  liveStabilityMode.current = false;
1466
1627
  liveStallEvents.current = [];
1628
+ lastProgressTime.current = (_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime;
1467
1629
  resetMediaForSourceChange();
1468
1630
  const nextSourceLoadMode = getSourceLoadMode(sourceType, type, videoSrc);
1469
1631
  sourceLoadMode.current = nextSourceLoadMode;
1470
1632
  if (active === false) {
1471
1633
  if (nextSourceLoadMode === "native" && preload === "metadata") {
1472
- loadVideoNative(loadId, { metadataOnly: true });
1634
+ loadVideoNative2(loadId, { metadataOnly: true });
1473
1635
  }
1474
1636
  return;
1475
1637
  }
1476
1638
  if (nextSourceLoadMode === "hls") {
1477
- if (sourceType === "hls") void loadVideo(initialTime, loadId);
1478
- else void loadVideoHls(loadId);
1639
+ if (sourceType === "hls") void loadVideo2((_d = (_c = resumeSnapshot.current) == null ? void 0 : _c.time) != null ? _d : initialTime, loadId);
1640
+ else void loadVideoHls2(loadId);
1479
1641
  } else {
1480
- loadVideoNative(loadId);
1642
+ loadVideoNative2(loadId);
1481
1643
  }
1482
1644
  return () => {
1483
1645
  sourceLoadId.current += 1;
@@ -1486,9 +1648,6 @@ var VideoPlayerBase = (props, ref) => {
1486
1648
  }, [
1487
1649
  clearErrorState,
1488
1650
  active,
1489
- loadVideo,
1490
- loadVideoHls,
1491
- loadVideoNative,
1492
1651
  initialTime,
1493
1652
  resetMediaForSourceChange,
1494
1653
  reloadKey,
@@ -1497,12 +1656,13 @@ var VideoPlayerBase = (props, ref) => {
1497
1656
  type,
1498
1657
  videoSrc
1499
1658
  ]);
1500
- (0, import_react3.useEffect)(() => {
1659
+ (0, import_react4.useEffect)(() => {
1501
1660
  if (!autoPlay) return;
1661
+ if (resumeSnapshot.current) return;
1502
1662
  if (!canAttemptPlayback(videoRef.current)) return;
1503
1663
  void playAction();
1504
1664
  }, [autoPlay, playAction]);
1505
- (0, import_react3.useEffect)(() => {
1665
+ (0, import_react4.useEffect)(() => {
1506
1666
  if (typeof document === "undefined") return;
1507
1667
  const handleKeyDown = (event) => {
1508
1668
  if (event.code !== "KeyF") return;
@@ -1517,7 +1677,7 @@ var VideoPlayerBase = (props, ref) => {
1517
1677
  document.removeEventListener("keydown", handleKeyDown);
1518
1678
  };
1519
1679
  }, [active, fullScreenAction]);
1520
- (0, import_react3.useEffect)(() => {
1680
+ (0, import_react4.useEffect)(() => {
1521
1681
  if (typeof document === "undefined") return;
1522
1682
  const doc = document;
1523
1683
  const handleFsChange = () => {
@@ -1535,15 +1695,15 @@ var VideoPlayerBase = (props, ref) => {
1535
1695
  document.removeEventListener("MSFullscreenChange", handleFsChange);
1536
1696
  };
1537
1697
  }, []);
1538
- (0, import_react3.useEffect)(() => {
1698
+ (0, import_react4.useEffect)(() => {
1539
1699
  return () => {
1540
1700
  setTimeD.current.cancel();
1541
1701
  setCurrentTimeUi.current.cancel();
1542
1702
  destroy();
1543
1703
  };
1544
1704
  }, [destroy]);
1545
- const lastActiveState = (0, import_react3.useRef)(active);
1546
- (0, import_react3.useEffect)(() => {
1705
+ const lastActiveState = (0, import_react4.useRef)(active);
1706
+ (0, import_react4.useEffect)(() => {
1547
1707
  const prevActive = lastActiveState.current;
1548
1708
  lastActiveState.current = active;
1549
1709
  if (active === true && prevActive !== true) {
@@ -1588,8 +1748,13 @@ var VideoPlayerBase = (props, ref) => {
1588
1748
  muted,
1589
1749
  preload,
1590
1750
  loop,
1591
- onPlay: () => setNextPlaying(true),
1592
- onPause: () => setNextPlaying(false),
1751
+ onPlay: () => {
1752
+ playbackIntent.current = true;
1753
+ setNextPlaying(true);
1754
+ },
1755
+ onPause: () => {
1756
+ if (!resumeSnapshot.current) setNextPlaying(false);
1757
+ },
1593
1758
  onEnded: () => setNextPlaying(false),
1594
1759
  onLoadedMetadata: videoLoadedHandler,
1595
1760
  onLoadedData: videoLoadedHandler,
@@ -1600,6 +1765,7 @@ var VideoPlayerBase = (props, ref) => {
1600
1765
  poster
1601
1766
  }
1602
1767
  ),
1768
+ audioFallback.videoOnly && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "status", className: "video-audio-status", children: "\u0417\u0432\u0443\u043A \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D" }),
1603
1769
  errorState && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "video-error-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "video-error-content", children: [
1604
1770
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "video-error-title", children: errorState.message }),
1605
1771
  errorState.details.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "video-error-details", children: errorState.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "video-error-detail", children: detail }, detail)) }),
@@ -1630,7 +1796,7 @@ var VideoPlayerBase = (props, ref) => {
1630
1796
  }
1631
1797
  );
1632
1798
  };
1633
- var VideoPlayer = (0, import_react3.memo)((0, import_react3.forwardRef)(VideoPlayerBase));
1799
+ var VideoPlayer = (0, import_react4.memo)((0, import_react4.forwardRef)(VideoPlayerBase));
1634
1800
  var VideoPlayer_default = VideoPlayer;
1635
1801
  // Annotate the CommonJS export names for ESM import in node:
1636
1802
  0 && (module.exports = {