@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/README.md +22 -0
- package/dist/index.cjs +291 -125
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +288 -122
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,16 +2,104 @@
|
|
|
2
2
|
import {
|
|
3
3
|
forwardRef,
|
|
4
4
|
memo,
|
|
5
|
-
useCallback,
|
|
6
|
-
useEffect,
|
|
5
|
+
useCallback as useCallback2,
|
|
6
|
+
useEffect as useEffect2,
|
|
7
7
|
useImperativeHandle,
|
|
8
8
|
useMemo as useMemo2,
|
|
9
|
-
useRef as
|
|
10
|
-
useState
|
|
9
|
+
useRef as useRef3,
|
|
10
|
+
useState as useState2
|
|
11
11
|
} from "react";
|
|
12
12
|
|
|
13
|
+
// src/useAudioFallback.ts
|
|
14
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
15
|
+
function useAudioFallback(options) {
|
|
16
|
+
const latest = useRef(options);
|
|
17
|
+
latest.current = options;
|
|
18
|
+
const [videoOnly, setVideoOnly] = useState(false);
|
|
19
|
+
const mode = useRef(false);
|
|
20
|
+
const cooldown = useRef(0);
|
|
21
|
+
const audioErrors = useRef(0);
|
|
22
|
+
const audioErrorTimer = useRef(null);
|
|
23
|
+
const snapshot = useRef(null);
|
|
24
|
+
const switchSource = useCallback((next, failure = false) => {
|
|
25
|
+
const { video, fallback, onChange } = latest.current;
|
|
26
|
+
const element = video.current;
|
|
27
|
+
if (!fallback || !element || mode.current === next) return false;
|
|
28
|
+
snapshot.current = {
|
|
29
|
+
time: Number.isFinite(element.currentTime) ? element.currentTime : 0,
|
|
30
|
+
playing: latest.current.playingIntent.current,
|
|
31
|
+
rate: element.playbackRate,
|
|
32
|
+
volume: element.volume,
|
|
33
|
+
muted: element.muted
|
|
34
|
+
};
|
|
35
|
+
mode.current = next;
|
|
36
|
+
audioErrors.current = 0;
|
|
37
|
+
if (audioErrorTimer.current) clearTimeout(audioErrorTimer.current);
|
|
38
|
+
audioErrorTimer.current = null;
|
|
39
|
+
if (failure) cooldown.current = Date.now() + 15e3;
|
|
40
|
+
setVideoOnly(next);
|
|
41
|
+
onChange == null ? void 0 : onChange(next);
|
|
42
|
+
return true;
|
|
43
|
+
}, []);
|
|
44
|
+
const onAudioError = useCallback((data) => {
|
|
45
|
+
var _a, _b, _c;
|
|
46
|
+
if (!latest.current.fallback || mode.current) return false;
|
|
47
|
+
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) || "");
|
|
48
|
+
if (!isAudio) return false;
|
|
49
|
+
if ((data == null ? void 0 : data.details) === "fragGap" && ((_c = latest.current.ranges) == null ? void 0 : _c.some((range) => {
|
|
50
|
+
var _a2, _b2;
|
|
51
|
+
const time = (_b2 = (_a2 = latest.current.video.current) == null ? void 0 : _a2.currentTime) != null ? _b2 : 0;
|
|
52
|
+
return time >= range.start - 0.05 && time < range.end - 0.05;
|
|
53
|
+
}))) return true;
|
|
54
|
+
audioErrors.current++;
|
|
55
|
+
if ((data == null ? void 0 : data.fatal) || audioErrors.current >= 2) return switchSource(true, true);
|
|
56
|
+
if (!audioErrorTimer.current) {
|
|
57
|
+
audioErrorTimer.current = setTimeout(() => {
|
|
58
|
+
audioErrorTimer.current = null;
|
|
59
|
+
switchSource(true, true);
|
|
60
|
+
}, 8e3);
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}, [switchSource]);
|
|
64
|
+
const onAudioProgress = useCallback(() => {
|
|
65
|
+
audioErrors.current = 0;
|
|
66
|
+
if (audioErrorTimer.current) clearTimeout(audioErrorTimer.current);
|
|
67
|
+
audioErrorTimer.current = null;
|
|
68
|
+
}, []);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
mode.current = false;
|
|
71
|
+
setVideoOnly(false);
|
|
72
|
+
snapshot.current = null;
|
|
73
|
+
cooldown.current = 0;
|
|
74
|
+
onAudioProgress();
|
|
75
|
+
return onAudioProgress;
|
|
76
|
+
}, [options.primary, options.fallback, onAudioProgress]);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
const check = () => {
|
|
79
|
+
const { ranges, video, fallback } = latest.current;
|
|
80
|
+
if (!fallback || !ranges || snapshot.current) return;
|
|
81
|
+
const element = video.current;
|
|
82
|
+
if (!element) return;
|
|
83
|
+
const time = element.currentTime;
|
|
84
|
+
const available = ranges.some((range) => time >= range.start - 0.05 && time < range.end - 0.05);
|
|
85
|
+
if (!mode.current && !available) switchSource(true);
|
|
86
|
+
else if (mode.current && available && Date.now() >= cooldown.current && ranges.some((range) => time >= range.start - 0.05 && time + 4 <= range.end)) switchSource(false);
|
|
87
|
+
};
|
|
88
|
+
const timer = setInterval(check, 500);
|
|
89
|
+
return () => clearInterval(timer);
|
|
90
|
+
}, [switchSource]);
|
|
91
|
+
return {
|
|
92
|
+
videoOnly,
|
|
93
|
+
source: videoOnly && options.fallback ? options.fallback : options.primary,
|
|
94
|
+
snapshot,
|
|
95
|
+
switchSource,
|
|
96
|
+
onAudioError,
|
|
97
|
+
onAudioProgress
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
13
101
|
// src/controls.tsx
|
|
14
|
-
import { useRef } from "react";
|
|
102
|
+
import { useRef as useRef2 } from "react";
|
|
15
103
|
|
|
16
104
|
// src/styles.ts
|
|
17
105
|
import { css, styled } from "styled-components";
|
|
@@ -151,6 +239,18 @@ var VideoPlayerStyles = styled.div`
|
|
|
151
239
|
align-items: center;
|
|
152
240
|
}
|
|
153
241
|
|
|
242
|
+
.video-audio-status {
|
|
243
|
+
position: absolute;
|
|
244
|
+
top: 0.75rem;
|
|
245
|
+
left: 0.75rem;
|
|
246
|
+
padding: 0.35rem 0.6rem;
|
|
247
|
+
color: inherit;
|
|
248
|
+
background: rgb(24 27 31 / 85%);
|
|
249
|
+
border-radius: 0.25rem;
|
|
250
|
+
font-size: 0.75rem;
|
|
251
|
+
pointer-events: none;
|
|
252
|
+
}
|
|
253
|
+
|
|
154
254
|
.video-error-overlay {
|
|
155
255
|
position: absolute;
|
|
156
256
|
inset: 0;
|
|
@@ -401,7 +501,7 @@ var createThrottledNumberFn = (fn, waitMs) => {
|
|
|
401
501
|
// src/controls.tsx
|
|
402
502
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
403
503
|
var SeekSlider = ({ playAction, duration, currentTime, seekSetTime }) => {
|
|
404
|
-
const ref =
|
|
504
|
+
const ref = useRef2(null);
|
|
405
505
|
const clickHandler = (e) => {
|
|
406
506
|
e.preventDefault();
|
|
407
507
|
e.stopPropagation();
|
|
@@ -815,56 +915,67 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
815
915
|
messages: messagesProp,
|
|
816
916
|
accentColor,
|
|
817
917
|
videoSrc: rawVideoSrc = "",
|
|
918
|
+
videoOnlySrc,
|
|
919
|
+
audioRanges,
|
|
920
|
+
onAudioFallbackChange,
|
|
818
921
|
...videoProps
|
|
819
922
|
} = props;
|
|
820
|
-
const
|
|
923
|
+
const primarySrc = rawVideoSrc.replaceAll(" ", "%20").replaceAll("#", "%23");
|
|
924
|
+
const propsRef = useRef3(props);
|
|
925
|
+
propsRef.current = props;
|
|
821
926
|
const messages = useMemo2(() => ({ ...defaultMessages, ...messagesProp }), [messagesProp]);
|
|
822
927
|
const [, isMobile, mobileType] = useWindowWidth();
|
|
823
|
-
const videoRef =
|
|
824
|
-
const
|
|
825
|
-
const
|
|
826
|
-
const
|
|
827
|
-
const
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
const
|
|
831
|
-
const
|
|
832
|
-
const
|
|
833
|
-
const
|
|
834
|
-
const
|
|
835
|
-
const
|
|
836
|
-
const
|
|
837
|
-
const
|
|
838
|
-
const
|
|
839
|
-
const
|
|
840
|
-
const
|
|
841
|
-
const
|
|
842
|
-
const
|
|
843
|
-
const
|
|
844
|
-
const [
|
|
845
|
-
const [
|
|
846
|
-
const
|
|
928
|
+
const videoRef = useRef3(null);
|
|
929
|
+
const playbackIntent = useRef3(autoPlay || defaultPlaying || Boolean(playingProp));
|
|
930
|
+
const audioFallback = useAudioFallback({ primary: primarySrc, fallback: videoOnlySrc, ranges: audioRanges, video: videoRef, playingIntent: playbackIntent, onChange: onAudioFallbackChange });
|
|
931
|
+
const videoSrc = audioFallback.source;
|
|
932
|
+
const { snapshot: resumeSnapshot, onAudioError, onAudioProgress, switchSource } = audioFallback;
|
|
933
|
+
const hlsRef = useRef3(null);
|
|
934
|
+
const containerRef = useRef3(null);
|
|
935
|
+
const lastProgressTime = useRef3(0);
|
|
936
|
+
const netRetryCount = useRef3(0);
|
|
937
|
+
const mediaRecoverCount = useRef3(0);
|
|
938
|
+
const fatalReloadCount = useRef3(0);
|
|
939
|
+
const reloadTimer = useRef3(null);
|
|
940
|
+
const stalledNudgeTimer = useRef3(null);
|
|
941
|
+
const liveStabilityMode = useRef3(false);
|
|
942
|
+
const liveStallEvents = useRef3([]);
|
|
943
|
+
const controlTime = useRef3(null);
|
|
944
|
+
const sourceLoadId = useRef3(0);
|
|
945
|
+
const sourceLoadMode = useRef3("native");
|
|
946
|
+
const pendingPlay = useRef3(false);
|
|
947
|
+
const playRequestInFlight = useRef3(false);
|
|
948
|
+
const playRequestId = useRef3(0);
|
|
949
|
+
const [playingState, setPlayingState] = useState2(!!defaultPlaying);
|
|
950
|
+
const [mutedState, setMutedState] = useState2(!!defaultMuted);
|
|
951
|
+
const [durationState, setDurationState] = useState2(0);
|
|
952
|
+
const [currentTimeState, setCurrentTimeState] = useState2(0);
|
|
953
|
+
const [isFullscreen, setIsFullscreen] = useState2(false);
|
|
954
|
+
const [showControl, setControlVisible] = useState2(true);
|
|
955
|
+
const [errorState, setErrorState] = useState2(null);
|
|
956
|
+
const [reloadToken, setReloadToken] = useState2(0);
|
|
957
|
+
const showControlRef = useRef3(showControl);
|
|
847
958
|
const playing = playingProp != null ? playingProp : playingState;
|
|
848
959
|
const muted = mutedProp != null ? mutedProp : mutedState;
|
|
849
960
|
const isDurationControlled = durationProp !== void 0;
|
|
850
961
|
const duration = durationProp != null ? durationProp : durationState;
|
|
851
962
|
const currentTime = currentTimeState;
|
|
852
963
|
const fullscreenAllowed = active != null ? active : true;
|
|
853
|
-
const onTimeChangeRef =
|
|
854
|
-
const onDurationChangeRef =
|
|
964
|
+
const onTimeChangeRef = useRef3(onTimeChange);
|
|
965
|
+
const onDurationChangeRef = useRef3(onDurationChange);
|
|
855
966
|
onTimeChangeRef.current = onTimeChange;
|
|
856
967
|
onDurationChangeRef.current = onDurationChange;
|
|
857
968
|
showControlRef.current = showControl;
|
|
858
969
|
const { currentTime: _ignoredCurrentTime, ...domVideoProps } = videoProps;
|
|
859
|
-
const setTimeD =
|
|
970
|
+
const setTimeD = useRef3(
|
|
860
971
|
createThrottledNumberFn((value) => {
|
|
861
972
|
const v = videoRef.current;
|
|
862
973
|
if (!v) return;
|
|
863
974
|
v.currentTime = value;
|
|
864
975
|
}, 30)
|
|
865
976
|
);
|
|
866
|
-
const setCurrentTimeUi =
|
|
867
|
-
const clearTimers =
|
|
977
|
+
const setCurrentTimeUi = useRef3(createThrottledNumberFn((value) => setCurrentTimeState(value), 250));
|
|
978
|
+
const clearTimers = useCallback2(() => {
|
|
868
979
|
if (reloadTimer.current) {
|
|
869
980
|
clearTimeout(reloadTimer.current);
|
|
870
981
|
reloadTimer.current = null;
|
|
@@ -878,9 +989,11 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
878
989
|
controlTime.current = null;
|
|
879
990
|
}
|
|
880
991
|
}, []);
|
|
881
|
-
const resetMediaForSourceChange =
|
|
992
|
+
const resetMediaForSourceChange = useCallback2(() => {
|
|
882
993
|
clearTimers();
|
|
883
994
|
pendingPlay.current = false;
|
|
995
|
+
playRequestId.current++;
|
|
996
|
+
playRequestInFlight.current = false;
|
|
884
997
|
if (hlsRef.current) {
|
|
885
998
|
hlsRef.current.destroy();
|
|
886
999
|
hlsRef.current = null;
|
|
@@ -891,7 +1004,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
891
1004
|
video.removeAttribute("src");
|
|
892
1005
|
video.load();
|
|
893
1006
|
}, [clearTimers]);
|
|
894
|
-
const releaseNativeMedia =
|
|
1007
|
+
const releaseNativeMedia = useCallback2(() => {
|
|
895
1008
|
const video = videoRef.current;
|
|
896
1009
|
if (!video) return;
|
|
897
1010
|
pendingPlay.current = false;
|
|
@@ -900,7 +1013,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
900
1013
|
video.removeAttribute("src");
|
|
901
1014
|
video.load();
|
|
902
1015
|
}, []);
|
|
903
|
-
const ensureNativeMediaAttached =
|
|
1016
|
+
const ensureNativeMediaAttached = useCallback2(() => {
|
|
904
1017
|
const video = videoRef.current;
|
|
905
1018
|
if (!video || sourceLoadMode.current !== "native" || isVideoSourceAttached(video)) return false;
|
|
906
1019
|
video.src = videoSrc;
|
|
@@ -908,27 +1021,30 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
908
1021
|
video.load();
|
|
909
1022
|
return true;
|
|
910
1023
|
}, [initialTime, videoSrc]);
|
|
911
|
-
const setNextPlaying =
|
|
1024
|
+
const setNextPlaying = useCallback2(
|
|
912
1025
|
(value) => {
|
|
913
|
-
|
|
914
|
-
|
|
1026
|
+
var _a, _b;
|
|
1027
|
+
if (propsRef.current.playing === void 0) setPlayingState(value);
|
|
1028
|
+
(_b = (_a = propsRef.current).onPlayingChange) == null ? void 0 : _b.call(_a, value);
|
|
915
1029
|
},
|
|
916
|
-
[
|
|
1030
|
+
[]
|
|
917
1031
|
);
|
|
918
|
-
const setNextMuted =
|
|
1032
|
+
const setNextMuted = useCallback2(
|
|
919
1033
|
(value) => {
|
|
920
|
-
|
|
1034
|
+
var _a, _b;
|
|
1035
|
+
if (propsRef.current.muted === void 0) setMutedState(value);
|
|
921
1036
|
const el = videoRef.current;
|
|
922
1037
|
if (el) el.muted = value;
|
|
923
|
-
onMutedChange == null ? void 0 :
|
|
1038
|
+
(_b = (_a = propsRef.current).onMutedChange) == null ? void 0 : _b.call(_a, value);
|
|
924
1039
|
},
|
|
925
|
-
[
|
|
1040
|
+
[]
|
|
926
1041
|
);
|
|
927
|
-
const clearErrorState =
|
|
1042
|
+
const clearErrorState = useCallback2(() => {
|
|
928
1043
|
setErrorState((prev) => prev ? null : prev);
|
|
929
1044
|
}, []);
|
|
930
|
-
const reportError =
|
|
1045
|
+
const reportError = useCallback2(
|
|
931
1046
|
(error, data, message = messages.defaultError) => {
|
|
1047
|
+
var _a, _b;
|
|
932
1048
|
const details = formatPlaybackErrorDetails(error, data);
|
|
933
1049
|
const code = getPlaybackErrorCodeText(error);
|
|
934
1050
|
setNextPlaying(false);
|
|
@@ -940,25 +1056,32 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
940
1056
|
error,
|
|
941
1057
|
data
|
|
942
1058
|
});
|
|
943
|
-
onPlaybackError == null ? void 0 :
|
|
1059
|
+
(_b = (_a = propsRef.current).onPlaybackError) == null ? void 0 : _b.call(_a, { error, data, message, details });
|
|
944
1060
|
},
|
|
945
|
-
[messages.defaultError,
|
|
1061
|
+
[messages.defaultError, setNextPlaying]
|
|
946
1062
|
);
|
|
947
|
-
const notifyActiveChange =
|
|
1063
|
+
const notifyActiveChange = useCallback2(
|
|
948
1064
|
(video, reason) => {
|
|
949
|
-
|
|
1065
|
+
var _a, _b;
|
|
1066
|
+
(_b = (_a = propsRef.current).onActiveChange) == null ? void 0 : _b.call(_a, { video, reason });
|
|
950
1067
|
},
|
|
951
|
-
[
|
|
1068
|
+
[]
|
|
952
1069
|
);
|
|
953
|
-
const onTime =
|
|
1070
|
+
const onTime = useCallback2(() => {
|
|
954
1071
|
var _a;
|
|
955
1072
|
const el = videoRef.current;
|
|
956
1073
|
if (!el) return;
|
|
957
1074
|
const nextTime = Number.isFinite(el.currentTime) ? el.currentTime : 0;
|
|
1075
|
+
if (!el.paused && !el.seeking && nextTime > lastProgressTime.current + 0.5) {
|
|
1076
|
+
netRetryCount.current = 0;
|
|
1077
|
+
fatalReloadCount.current = 0;
|
|
1078
|
+
mediaRecoverCount.current = 0;
|
|
1079
|
+
lastProgressTime.current = nextTime;
|
|
1080
|
+
}
|
|
958
1081
|
setCurrentTimeUi.current(nextTime);
|
|
959
1082
|
(_a = onTimeChangeRef.current) == null ? void 0 : _a.call(onTimeChangeRef, nextTime, el);
|
|
960
1083
|
}, []);
|
|
961
|
-
const onDur =
|
|
1084
|
+
const onDur = useCallback2(() => {
|
|
962
1085
|
var _a;
|
|
963
1086
|
const el = videoRef.current;
|
|
964
1087
|
if (!el) return;
|
|
@@ -966,8 +1089,9 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
966
1089
|
if (!isDurationControlled) setDurationState(nextDuration);
|
|
967
1090
|
(_a = onDurationChangeRef.current) == null ? void 0 : _a.call(onDurationChangeRef, nextDuration, el);
|
|
968
1091
|
}, [isDurationControlled]);
|
|
969
|
-
const setVideoEl =
|
|
1092
|
+
const setVideoEl = useCallback2(
|
|
970
1093
|
(el) => {
|
|
1094
|
+
var _a, _b, _c;
|
|
971
1095
|
const prev = videoRef.current;
|
|
972
1096
|
if (prev === el) return;
|
|
973
1097
|
if (prev) {
|
|
@@ -976,18 +1100,18 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
976
1100
|
exclusiveMediaReleasers.delete(prev);
|
|
977
1101
|
}
|
|
978
1102
|
videoRef.current = el;
|
|
979
|
-
assignRef(
|
|
980
|
-
onVideoRefChange == null ? void 0 :
|
|
1103
|
+
assignRef(propsRef.current.videoRef, el);
|
|
1104
|
+
(_b = (_a = propsRef.current).onVideoRefChange) == null ? void 0 : _b.call(_a, el);
|
|
981
1105
|
notifyActiveChange(el, "ref");
|
|
982
1106
|
if (!el) return;
|
|
983
|
-
el.muted = muted;
|
|
1107
|
+
el.muted = (_c = propsRef.current.muted) != null ? _c : mutedState;
|
|
984
1108
|
el.addEventListener("timeupdate", onTime);
|
|
985
1109
|
el.addEventListener("durationchange", onDur);
|
|
986
1110
|
exclusiveMediaReleasers.set(el, releaseNativeMedia);
|
|
987
1111
|
},
|
|
988
|
-
[
|
|
1112
|
+
[notifyActiveChange, onDur, onTime, releaseNativeMedia]
|
|
989
1113
|
);
|
|
990
|
-
const pauseOtherVideos =
|
|
1114
|
+
const pauseOtherVideos = useCallback2(
|
|
991
1115
|
(el) => {
|
|
992
1116
|
if (!exclusivePlayback) return;
|
|
993
1117
|
if (typeof exclusivePlayback === "object") {
|
|
@@ -1003,20 +1127,25 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1003
1127
|
},
|
|
1004
1128
|
[exclusivePlayback]
|
|
1005
1129
|
);
|
|
1006
|
-
const playAction =
|
|
1130
|
+
const playAction = useCallback2(async () => {
|
|
1007
1131
|
const el = videoRef.current;
|
|
1008
1132
|
if (!el) return;
|
|
1133
|
+
const requestId = ++playRequestId.current;
|
|
1009
1134
|
pendingPlay.current = true;
|
|
1135
|
+
playbackIntent.current = true;
|
|
1136
|
+
if (resumeSnapshot.current) resumeSnapshot.current.playing = true;
|
|
1010
1137
|
pauseOtherVideos(el);
|
|
1011
1138
|
ensureNativeMediaAttached();
|
|
1012
1139
|
try {
|
|
1013
1140
|
playRequestInFlight.current = true;
|
|
1014
1141
|
await el.play();
|
|
1142
|
+
if (requestId !== playRequestId.current || videoRef.current !== el) return;
|
|
1015
1143
|
pendingPlay.current = false;
|
|
1016
1144
|
clearErrorState();
|
|
1017
1145
|
setNextPlaying(true);
|
|
1018
1146
|
notifyActiveChange(el, "play");
|
|
1019
1147
|
} catch (e) {
|
|
1148
|
+
if (requestId !== playRequestId.current || videoRef.current !== el) return;
|
|
1020
1149
|
if (isInterruptedPlayRequestError(e)) {
|
|
1021
1150
|
pendingPlay.current = true;
|
|
1022
1151
|
return;
|
|
@@ -1025,7 +1154,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1025
1154
|
console.debug(e);
|
|
1026
1155
|
reportError(e, { type: "play" }, messages.playFailed);
|
|
1027
1156
|
} finally {
|
|
1028
|
-
playRequestInFlight.current = false;
|
|
1157
|
+
if (requestId === playRequestId.current) playRequestInFlight.current = false;
|
|
1029
1158
|
}
|
|
1030
1159
|
if (scrollTo === true) {
|
|
1031
1160
|
const rect = el.getBoundingClientRect();
|
|
@@ -1048,15 +1177,17 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1048
1177
|
scrollTo,
|
|
1049
1178
|
setNextPlaying
|
|
1050
1179
|
]);
|
|
1051
|
-
const pauseAction =
|
|
1180
|
+
const pauseAction = useCallback2(() => {
|
|
1052
1181
|
const el = videoRef.current;
|
|
1053
1182
|
if (!el) return;
|
|
1054
1183
|
pendingPlay.current = false;
|
|
1184
|
+
if (resumeSnapshot.current) resumeSnapshot.current.playing = false;
|
|
1185
|
+
playbackIntent.current = false;
|
|
1055
1186
|
el.pause();
|
|
1056
1187
|
setNextPlaying(false);
|
|
1057
1188
|
notifyActiveChange(el, "pause");
|
|
1058
1189
|
}, [notifyActiveChange, setNextPlaying]);
|
|
1059
|
-
const seekSetTime =
|
|
1190
|
+
const seekSetTime = useCallback2(
|
|
1060
1191
|
(value) => {
|
|
1061
1192
|
const el = videoRef.current;
|
|
1062
1193
|
if (!el) return;
|
|
@@ -1068,7 +1199,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1068
1199
|
},
|
|
1069
1200
|
[duration, notifyActiveChange]
|
|
1070
1201
|
);
|
|
1071
|
-
const seekPrevAction =
|
|
1202
|
+
const seekPrevAction = useCallback2(
|
|
1072
1203
|
(sec = 15) => {
|
|
1073
1204
|
const el = videoRef.current;
|
|
1074
1205
|
if (!el) return;
|
|
@@ -1076,7 +1207,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1076
1207
|
},
|
|
1077
1208
|
[seekSetTime]
|
|
1078
1209
|
);
|
|
1079
|
-
const seekNextAction =
|
|
1210
|
+
const seekNextAction = useCallback2(
|
|
1080
1211
|
(sec = 15) => {
|
|
1081
1212
|
const el = videoRef.current;
|
|
1082
1213
|
if (!el) return;
|
|
@@ -1084,7 +1215,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1084
1215
|
},
|
|
1085
1216
|
[seekSetTime]
|
|
1086
1217
|
);
|
|
1087
|
-
const toggleAction =
|
|
1218
|
+
const toggleAction = useCallback2(
|
|
1088
1219
|
(force) => {
|
|
1089
1220
|
const el = videoRef.current;
|
|
1090
1221
|
if (!el) return;
|
|
@@ -1096,12 +1227,12 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1096
1227
|
},
|
|
1097
1228
|
[pauseAction, playAction]
|
|
1098
1229
|
);
|
|
1099
|
-
const nudgeOnStall =
|
|
1230
|
+
const nudgeOnStall = useCallback2(() => {
|
|
1100
1231
|
const v = videoRef.current;
|
|
1101
1232
|
if (!v) return;
|
|
1102
1233
|
v.currentTime = Math.max(0, v.currentTime + 0.05);
|
|
1103
1234
|
}, []);
|
|
1104
|
-
const shouldSwitchLiveToStability =
|
|
1235
|
+
const shouldSwitchLiveToStability = useCallback2(() => {
|
|
1105
1236
|
if (!live || liveStabilityMode.current) return false;
|
|
1106
1237
|
const now = Date.now();
|
|
1107
1238
|
liveStallEvents.current = [...liveStallEvents.current.filter((ts) => now - ts <= LIVE_STALL_WINDOW_MS), now];
|
|
@@ -1110,7 +1241,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1110
1241
|
liveStallEvents.current = [];
|
|
1111
1242
|
return true;
|
|
1112
1243
|
}, [live]);
|
|
1113
|
-
const resolvedHlsConfig =
|
|
1244
|
+
const resolvedHlsConfig = useCallback2(() => {
|
|
1114
1245
|
const modeConfig = live ? liveHlsConfig : vodHlsConfig;
|
|
1115
1246
|
const base = live ? confLiveStability : confVod;
|
|
1116
1247
|
return withCredentialsConfig(
|
|
@@ -1122,8 +1253,8 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1122
1253
|
hlsCredentials
|
|
1123
1254
|
);
|
|
1124
1255
|
}, [hlsConfig, hlsCredentials, live, liveHlsConfig, vodHlsConfig]);
|
|
1125
|
-
const loadVideo =
|
|
1126
|
-
async (startAt = initialTime, loadId = sourceLoadId.current) => {
|
|
1256
|
+
const loadVideo = useCallback2(
|
|
1257
|
+
async (startAt = ((_b) => (_b = ((_a) => (_a = resumeSnapshot.current) == null ? void 0 : _a.time)()) != null ? _b : initialTime)(), loadId = sourceLoadId.current) => {
|
|
1127
1258
|
const startVideoRef = videoRef.current;
|
|
1128
1259
|
if (!startVideoRef) return;
|
|
1129
1260
|
sourceLoadMode.current = "hls";
|
|
@@ -1131,6 +1262,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1131
1262
|
try {
|
|
1132
1263
|
HlsCtor = await loadHlsCtor();
|
|
1133
1264
|
} catch (error) {
|
|
1265
|
+
if (loadId !== sourceLoadId.current || videoRef.current !== startVideoRef) return;
|
|
1134
1266
|
reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
|
|
1135
1267
|
return;
|
|
1136
1268
|
}
|
|
@@ -1142,10 +1274,11 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1142
1274
|
hlsRef.current = h;
|
|
1143
1275
|
const isStaleLoad = () => loadId !== sourceLoadId.current || hlsRef.current !== h || videoRef.current !== video;
|
|
1144
1276
|
h.on(HlsCtor.Events.ERROR, (_evt, data) => {
|
|
1145
|
-
var
|
|
1277
|
+
var _a2, _b2;
|
|
1146
1278
|
if (isStaleLoad()) return;
|
|
1147
1279
|
const { type: errorType, details, fatal } = data;
|
|
1148
|
-
if (
|
|
1280
|
+
if (onAudioError(data)) return;
|
|
1281
|
+
if (!fatal && (details === HlsCtor.ErrorDetails.BUFFER_APPEND_ERROR || details === "bufferAppendingError")) return;
|
|
1149
1282
|
if (!fatal) {
|
|
1150
1283
|
switch (details) {
|
|
1151
1284
|
case HlsCtor.ErrorDetails.BUFFER_STALLED_ERROR:
|
|
@@ -1157,7 +1290,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1157
1290
|
}, 200);
|
|
1158
1291
|
}
|
|
1159
1292
|
if (shouldSwitchLiveToStability()) {
|
|
1160
|
-
const resumeTime2 = ((
|
|
1293
|
+
const resumeTime2 = ((_a2 = videoRef.current) == null ? void 0 : _a2.currentTime) || 0;
|
|
1161
1294
|
clearTimers();
|
|
1162
1295
|
reloadTimer.current = setTimeout(() => {
|
|
1163
1296
|
if (hlsRef.current) {
|
|
@@ -1172,7 +1305,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1172
1305
|
return;
|
|
1173
1306
|
}
|
|
1174
1307
|
}
|
|
1175
|
-
const resumeTime = ((
|
|
1308
|
+
const resumeTime = ((_b2 = videoRef.current) == null ? void 0 : _b2.currentTime) || 0;
|
|
1176
1309
|
if (errorType === HlsCtor.ErrorTypes.NETWORK_ERROR) {
|
|
1177
1310
|
if (netRetryCount.current < MAX_NET_RETRIES) {
|
|
1178
1311
|
netRetryCount.current += 1;
|
|
@@ -1236,21 +1369,25 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1236
1369
|
});
|
|
1237
1370
|
h.on(HlsCtor.Events.MANIFEST_PARSED, () => {
|
|
1238
1371
|
if (isStaleLoad()) return;
|
|
1239
|
-
|
|
1240
|
-
netRetryCount.current = 0;
|
|
1241
|
-
mediaRecoverCount.current = 0;
|
|
1242
|
-
if (!live && startAt > 0) {
|
|
1372
|
+
if (startAt > 0) {
|
|
1243
1373
|
h.startLoad(startAt);
|
|
1244
1374
|
video.currentTime = startAt;
|
|
1245
1375
|
} else {
|
|
1246
1376
|
h.startLoad();
|
|
1247
1377
|
}
|
|
1248
|
-
if (autoPlay) void playAction();
|
|
1378
|
+
if (resumeSnapshot.current ? resumeSnapshot.current.playing : autoPlay) void playAction();
|
|
1379
|
+
});
|
|
1380
|
+
h.on(HlsCtor.Events.FRAG_BUFFERED, (_evt, data) => {
|
|
1381
|
+
if (isStaleLoad()) return;
|
|
1382
|
+
if (data.frag.type === "audio") onAudioProgress();
|
|
1249
1383
|
});
|
|
1250
1384
|
h.attachMedia(video);
|
|
1251
1385
|
},
|
|
1252
1386
|
[
|
|
1253
1387
|
autoPlay,
|
|
1388
|
+
onAudioError,
|
|
1389
|
+
onAudioProgress,
|
|
1390
|
+
resumeSnapshot,
|
|
1254
1391
|
clearErrorState,
|
|
1255
1392
|
clearTimers,
|
|
1256
1393
|
initialTime,
|
|
@@ -1265,21 +1402,23 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1265
1402
|
videoSrc
|
|
1266
1403
|
]
|
|
1267
1404
|
);
|
|
1268
|
-
const loadVideoNative =
|
|
1405
|
+
const loadVideoNative = useCallback2(
|
|
1269
1406
|
(loadId = sourceLoadId.current, options) => {
|
|
1407
|
+
var _a, _b;
|
|
1270
1408
|
if (loadId !== sourceLoadId.current) return;
|
|
1271
1409
|
const video = videoRef.current;
|
|
1272
1410
|
if (!video) return;
|
|
1273
1411
|
sourceLoadMode.current = "native";
|
|
1274
1412
|
video.src = videoSrc;
|
|
1275
1413
|
if (!(options == null ? void 0 : options.metadataOnly)) {
|
|
1276
|
-
video.currentTime = initialTime;
|
|
1277
|
-
if (autoPlay) void playAction();
|
|
1414
|
+
video.currentTime = (_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime;
|
|
1415
|
+
if (resumeSnapshot.current ? resumeSnapshot.current.playing : autoPlay) void playAction();
|
|
1278
1416
|
}
|
|
1279
1417
|
},
|
|
1280
1418
|
[autoPlay, initialTime, playAction, videoSrc]
|
|
1281
1419
|
);
|
|
1282
|
-
const loadVideoHls =
|
|
1420
|
+
const loadVideoHls = useCallback2(async (loadId = sourceLoadId.current) => {
|
|
1421
|
+
var _a, _b;
|
|
1283
1422
|
const video = videoRef.current;
|
|
1284
1423
|
const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
|
|
1285
1424
|
sourceLoadMode.current = "hls";
|
|
@@ -1287,13 +1426,14 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1287
1426
|
try {
|
|
1288
1427
|
HlsCtor = await loadHlsCtor();
|
|
1289
1428
|
} catch (error) {
|
|
1429
|
+
if (loadId !== sourceLoadId.current || videoRef.current !== video) return;
|
|
1290
1430
|
reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
|
|
1291
1431
|
return;
|
|
1292
1432
|
}
|
|
1293
1433
|
if (loadId !== sourceLoadId.current) return;
|
|
1294
1434
|
if (!videoRef.current || videoRef.current !== video) return;
|
|
1295
1435
|
if (HlsCtor.isSupported()) {
|
|
1296
|
-
void loadVideo(initialTime, loadId);
|
|
1436
|
+
void loadVideo((_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime, loadId);
|
|
1297
1437
|
return;
|
|
1298
1438
|
}
|
|
1299
1439
|
if (canNativeHls) {
|
|
@@ -1302,7 +1442,8 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1302
1442
|
}
|
|
1303
1443
|
reportError(null, { type: "hls", src: videoSrc, reason: "HLS is not supported in this browser" }, messages.unsupported);
|
|
1304
1444
|
}, [initialTime, loadVideo, loadVideoNative, messages.streamLoadFailed, messages.unsupported, reportError, videoSrc]);
|
|
1305
|
-
const destroy =
|
|
1445
|
+
const destroy = useCallback2(() => {
|
|
1446
|
+
var _a, _b;
|
|
1306
1447
|
clearTimers();
|
|
1307
1448
|
if (hlsRef.current) {
|
|
1308
1449
|
hlsRef.current.destroy();
|
|
@@ -1318,27 +1459,25 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1318
1459
|
if (activeExclusiveVideo === v) activeExclusiveVideo = null;
|
|
1319
1460
|
}
|
|
1320
1461
|
videoRef.current = null;
|
|
1321
|
-
onVideoRefChange == null ? void 0 :
|
|
1462
|
+
(_b = (_a = propsRef.current).onVideoRefChange) == null ? void 0 : _b.call(_a, null);
|
|
1322
1463
|
notifyActiveChange(null, "destroy");
|
|
1323
1464
|
setNextPlaying(false);
|
|
1324
|
-
if (
|
|
1465
|
+
if (propsRef.current.duration === void 0) setDurationState(0);
|
|
1325
1466
|
setCurrentTimeUi.current.cancel();
|
|
1326
1467
|
setCurrentTimeState(0);
|
|
1327
1468
|
}, [
|
|
1328
1469
|
clearTimers,
|
|
1329
|
-
durationProp,
|
|
1330
1470
|
notifyActiveChange,
|
|
1331
1471
|
onDur,
|
|
1332
1472
|
onTime,
|
|
1333
|
-
onVideoRefChange,
|
|
1334
1473
|
setNextPlaying
|
|
1335
1474
|
]);
|
|
1336
|
-
const videoClickHandler =
|
|
1475
|
+
const videoClickHandler = useCallback2(() => {
|
|
1337
1476
|
if (!handleClick) return;
|
|
1338
1477
|
if (playOnClick) toggleAction();
|
|
1339
1478
|
onVideoClick == null ? void 0 : onVideoClick();
|
|
1340
1479
|
}, [handleClick, onVideoClick, playOnClick, toggleAction]);
|
|
1341
|
-
const fullScreenAction =
|
|
1480
|
+
const fullScreenAction = useCallback2(() => {
|
|
1342
1481
|
if (typeof document === "undefined") return;
|
|
1343
1482
|
const doc = document;
|
|
1344
1483
|
const videoEl = videoRef.current;
|
|
@@ -1363,33 +1502,51 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1363
1502
|
else if (videoEl.webkitEnterFullscreen) void videoEl.webkitEnterFullscreen();
|
|
1364
1503
|
}
|
|
1365
1504
|
}, [fullscreenAllowed]);
|
|
1366
|
-
const videoDbClickHandler =
|
|
1505
|
+
const videoDbClickHandler = useCallback2(() => {
|
|
1367
1506
|
if (!handleClick) return;
|
|
1368
1507
|
fullScreenAction();
|
|
1369
1508
|
onVideoDoubleClick == null ? void 0 : onVideoDoubleClick();
|
|
1370
1509
|
}, [fullScreenAction, handleClick, onVideoDoubleClick]);
|
|
1371
|
-
const showClickHandler =
|
|
1510
|
+
const showClickHandler = useCallback2(() => {
|
|
1372
1511
|
setControlVisible((st) => !st);
|
|
1373
1512
|
}, []);
|
|
1374
|
-
const retryLoadHandler =
|
|
1513
|
+
const retryLoadHandler = useCallback2(() => {
|
|
1375
1514
|
clearErrorState();
|
|
1376
1515
|
setReloadToken((value) => value + 1);
|
|
1377
1516
|
}, [clearErrorState]);
|
|
1378
|
-
const videoErrorHandler =
|
|
1517
|
+
const videoErrorHandler = useCallback2(() => {
|
|
1379
1518
|
const video = videoRef.current;
|
|
1380
1519
|
const error = video == null ? void 0 : video.error;
|
|
1381
1520
|
const src = (video == null ? void 0 : video.currentSrc) || videoSrc;
|
|
1382
1521
|
if (hlsRef.current && src.startsWith("blob:")) return;
|
|
1522
|
+
if (switchSource(true, true)) return;
|
|
1383
1523
|
pendingPlay.current = false;
|
|
1384
1524
|
reportError(error, { type: "native", src }, getNativeVideoErrorMessage(error, messages));
|
|
1385
|
-
}, [messages, reportError, videoSrc]);
|
|
1386
|
-
const videoLoadedHandler =
|
|
1525
|
+
}, [messages, reportError, switchSource, videoSrc]);
|
|
1526
|
+
const videoLoadedHandler = useCallback2(() => {
|
|
1387
1527
|
clearErrorState();
|
|
1528
|
+
const saved = resumeSnapshot.current;
|
|
1529
|
+
const element = videoRef.current;
|
|
1530
|
+
if (saved && element && element.readyState >= HTMLMediaElement.HAVE_METADATA) {
|
|
1531
|
+
let time = saved.time;
|
|
1532
|
+
if (element.seekable.length) {
|
|
1533
|
+
const start = element.seekable.start(0);
|
|
1534
|
+
const end = element.seekable.end(element.seekable.length - 1);
|
|
1535
|
+
time = Math.max(start, Math.min(time, Math.max(start, end - 0.05)));
|
|
1536
|
+
}
|
|
1537
|
+
element.currentTime = time;
|
|
1538
|
+
element.playbackRate = saved.rate;
|
|
1539
|
+
element.volume = saved.volume;
|
|
1540
|
+
element.muted = saved.muted;
|
|
1541
|
+
resumeSnapshot.current = null;
|
|
1542
|
+
if (saved.playing) void playAction();
|
|
1543
|
+
else pauseAction();
|
|
1544
|
+
}
|
|
1388
1545
|
if (playRequestInFlight.current) return;
|
|
1389
1546
|
if (!pendingPlay.current || active === false || !canAttemptPlayback(videoRef.current)) return;
|
|
1390
1547
|
void playAction();
|
|
1391
|
-
}, [active, clearErrorState, playAction]);
|
|
1392
|
-
const mouseMoveHandler =
|
|
1548
|
+
}, [active, clearErrorState, playAction, pauseAction, resumeSnapshot]);
|
|
1549
|
+
const mouseMoveHandler = useCallback2(() => {
|
|
1393
1550
|
if (controlTime.current) clearTimeout(controlTime.current);
|
|
1394
1551
|
if (!showControlRef.current) {
|
|
1395
1552
|
showControlRef.current = true;
|
|
@@ -1411,22 +1568,26 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1411
1568
|
}),
|
|
1412
1569
|
[fullScreenAction, pauseAction, playAction, seekSetTime]
|
|
1413
1570
|
);
|
|
1414
|
-
|
|
1571
|
+
useEffect2(() => {
|
|
1415
1572
|
const el = videoRef.current;
|
|
1416
1573
|
if (!el) return;
|
|
1417
1574
|
el.muted = muted;
|
|
1418
1575
|
}, [muted]);
|
|
1419
|
-
|
|
1576
|
+
useEffect2(() => {
|
|
1420
1577
|
if (playingProp === void 0) return;
|
|
1421
1578
|
if (playingProp) void playAction();
|
|
1422
1579
|
else pauseAction();
|
|
1423
1580
|
}, [pauseAction, playAction, playingProp]);
|
|
1424
|
-
|
|
1581
|
+
useEffect2(() => {
|
|
1425
1582
|
if (active !== false) return;
|
|
1426
1583
|
releaseNativeMedia();
|
|
1427
1584
|
}, [active, releaseNativeMedia]);
|
|
1428
|
-
|
|
1585
|
+
const sourceLoaders = useRef3({ loadVideo, loadVideoHls, loadVideoNative });
|
|
1586
|
+
sourceLoaders.current = { loadVideo, loadVideoHls, loadVideoNative };
|
|
1587
|
+
useEffect2(() => {
|
|
1588
|
+
var _a, _b, _c, _d;
|
|
1429
1589
|
if (!videoRef.current) return;
|
|
1590
|
+
const { loadVideo: loadVideo2, loadVideoHls: loadVideoHls2, loadVideoNative: loadVideoNative2 } = sourceLoaders.current;
|
|
1430
1591
|
const loadId = sourceLoadId.current + 1;
|
|
1431
1592
|
sourceLoadId.current = loadId;
|
|
1432
1593
|
clearErrorState();
|
|
@@ -1435,20 +1596,21 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1435
1596
|
mediaRecoverCount.current = 0;
|
|
1436
1597
|
liveStabilityMode.current = false;
|
|
1437
1598
|
liveStallEvents.current = [];
|
|
1599
|
+
lastProgressTime.current = (_b = (_a = resumeSnapshot.current) == null ? void 0 : _a.time) != null ? _b : initialTime;
|
|
1438
1600
|
resetMediaForSourceChange();
|
|
1439
1601
|
const nextSourceLoadMode = getSourceLoadMode(sourceType, type, videoSrc);
|
|
1440
1602
|
sourceLoadMode.current = nextSourceLoadMode;
|
|
1441
1603
|
if (active === false) {
|
|
1442
1604
|
if (nextSourceLoadMode === "native" && preload === "metadata") {
|
|
1443
|
-
|
|
1605
|
+
loadVideoNative2(loadId, { metadataOnly: true });
|
|
1444
1606
|
}
|
|
1445
1607
|
return;
|
|
1446
1608
|
}
|
|
1447
1609
|
if (nextSourceLoadMode === "hls") {
|
|
1448
|
-
if (sourceType === "hls") void
|
|
1449
|
-
else void
|
|
1610
|
+
if (sourceType === "hls") void loadVideo2((_d = (_c = resumeSnapshot.current) == null ? void 0 : _c.time) != null ? _d : initialTime, loadId);
|
|
1611
|
+
else void loadVideoHls2(loadId);
|
|
1450
1612
|
} else {
|
|
1451
|
-
|
|
1613
|
+
loadVideoNative2(loadId);
|
|
1452
1614
|
}
|
|
1453
1615
|
return () => {
|
|
1454
1616
|
sourceLoadId.current += 1;
|
|
@@ -1457,9 +1619,6 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1457
1619
|
}, [
|
|
1458
1620
|
clearErrorState,
|
|
1459
1621
|
active,
|
|
1460
|
-
loadVideo,
|
|
1461
|
-
loadVideoHls,
|
|
1462
|
-
loadVideoNative,
|
|
1463
1622
|
initialTime,
|
|
1464
1623
|
resetMediaForSourceChange,
|
|
1465
1624
|
reloadKey,
|
|
@@ -1468,12 +1627,13 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1468
1627
|
type,
|
|
1469
1628
|
videoSrc
|
|
1470
1629
|
]);
|
|
1471
|
-
|
|
1630
|
+
useEffect2(() => {
|
|
1472
1631
|
if (!autoPlay) return;
|
|
1632
|
+
if (resumeSnapshot.current) return;
|
|
1473
1633
|
if (!canAttemptPlayback(videoRef.current)) return;
|
|
1474
1634
|
void playAction();
|
|
1475
1635
|
}, [autoPlay, playAction]);
|
|
1476
|
-
|
|
1636
|
+
useEffect2(() => {
|
|
1477
1637
|
if (typeof document === "undefined") return;
|
|
1478
1638
|
const handleKeyDown = (event) => {
|
|
1479
1639
|
if (event.code !== "KeyF") return;
|
|
@@ -1488,7 +1648,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1488
1648
|
document.removeEventListener("keydown", handleKeyDown);
|
|
1489
1649
|
};
|
|
1490
1650
|
}, [active, fullScreenAction]);
|
|
1491
|
-
|
|
1651
|
+
useEffect2(() => {
|
|
1492
1652
|
if (typeof document === "undefined") return;
|
|
1493
1653
|
const doc = document;
|
|
1494
1654
|
const handleFsChange = () => {
|
|
@@ -1506,15 +1666,15 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1506
1666
|
document.removeEventListener("MSFullscreenChange", handleFsChange);
|
|
1507
1667
|
};
|
|
1508
1668
|
}, []);
|
|
1509
|
-
|
|
1669
|
+
useEffect2(() => {
|
|
1510
1670
|
return () => {
|
|
1511
1671
|
setTimeD.current.cancel();
|
|
1512
1672
|
setCurrentTimeUi.current.cancel();
|
|
1513
1673
|
destroy();
|
|
1514
1674
|
};
|
|
1515
1675
|
}, [destroy]);
|
|
1516
|
-
const lastActiveState =
|
|
1517
|
-
|
|
1676
|
+
const lastActiveState = useRef3(active);
|
|
1677
|
+
useEffect2(() => {
|
|
1518
1678
|
const prevActive = lastActiveState.current;
|
|
1519
1679
|
lastActiveState.current = active;
|
|
1520
1680
|
if (active === true && prevActive !== true) {
|
|
@@ -1559,8 +1719,13 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1559
1719
|
muted,
|
|
1560
1720
|
preload,
|
|
1561
1721
|
loop,
|
|
1562
|
-
onPlay: () =>
|
|
1563
|
-
|
|
1722
|
+
onPlay: () => {
|
|
1723
|
+
playbackIntent.current = true;
|
|
1724
|
+
setNextPlaying(true);
|
|
1725
|
+
},
|
|
1726
|
+
onPause: () => {
|
|
1727
|
+
if (!resumeSnapshot.current) setNextPlaying(false);
|
|
1728
|
+
},
|
|
1564
1729
|
onEnded: () => setNextPlaying(false),
|
|
1565
1730
|
onLoadedMetadata: videoLoadedHandler,
|
|
1566
1731
|
onLoadedData: videoLoadedHandler,
|
|
@@ -1571,6 +1736,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1571
1736
|
poster
|
|
1572
1737
|
}
|
|
1573
1738
|
),
|
|
1739
|
+
audioFallback.videoOnly && /* @__PURE__ */ jsx2("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" }),
|
|
1574
1740
|
errorState && /* @__PURE__ */ jsx2("div", { className: "video-error-overlay", children: /* @__PURE__ */ jsxs2("div", { className: "video-error-content", children: [
|
|
1575
1741
|
/* @__PURE__ */ jsx2("div", { className: "video-error-title", children: errorState.message }),
|
|
1576
1742
|
errorState.details.length > 0 && /* @__PURE__ */ jsx2("div", { className: "video-error-details", children: errorState.details.map((detail) => /* @__PURE__ */ jsx2("div", { className: "video-error-detail", children: detail }, detail)) }),
|