@nikelroot/video-player 0.1.3 → 0.1.5
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 +5 -0
- package/dist/index.cjs +41 -5
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +41 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,13 +17,18 @@ npm install react react-dom styled-components
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
19
|
```tsx
|
|
20
|
+
import { useRef } from 'react';
|
|
20
21
|
import VideoPlayer from '@nikelroot/video-player';
|
|
21
22
|
|
|
22
23
|
export function Example() {
|
|
24
|
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
25
|
+
|
|
23
26
|
return (
|
|
24
27
|
<VideoPlayer
|
|
28
|
+
videoRef={videoRef}
|
|
25
29
|
videoSrc="https://example.com/stream.m3u8"
|
|
26
30
|
controlsVariant="full"
|
|
31
|
+
active={true}
|
|
27
32
|
live={false}
|
|
28
33
|
autoPlay={false}
|
|
29
34
|
onTimeChange={(time) => console.log(time)}
|
package/dist/index.cjs
CHANGED
|
@@ -87,6 +87,15 @@ var VideoPlayerControlStyles = import_styled_components.styled.div`
|
|
|
87
87
|
outline: none;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
.video-player-control-button:disabled {
|
|
91
|
+
opacity: 0.42;
|
|
92
|
+
cursor: not-allowed;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.video-player-control-button:disabled:hover {
|
|
96
|
+
background: rgba(255, 255, 255, 0.12);
|
|
97
|
+
}
|
|
98
|
+
|
|
90
99
|
.video-player-icon {
|
|
91
100
|
width: 17px;
|
|
92
101
|
height: 17px;
|
|
@@ -482,11 +491,23 @@ var Icon = ({ name }) => {
|
|
|
482
491
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { "aria-hidden": "true", className: "video-player-icon", focusable: "false", viewBox: "0 0 24 24", children: paths[name] });
|
|
483
492
|
};
|
|
484
493
|
var ControlButton = ({
|
|
494
|
+
disabled,
|
|
485
495
|
icon,
|
|
486
496
|
label,
|
|
487
497
|
onClick
|
|
488
498
|
}) => {
|
|
489
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
500
|
+
"button",
|
|
501
|
+
{
|
|
502
|
+
"aria-label": label,
|
|
503
|
+
className: "video-player-control-button",
|
|
504
|
+
disabled,
|
|
505
|
+
onClick: () => void onClick(),
|
|
506
|
+
title: label,
|
|
507
|
+
type: "button",
|
|
508
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { name: icon })
|
|
509
|
+
}
|
|
510
|
+
);
|
|
490
511
|
};
|
|
491
512
|
var stopControlClick = (e) => {
|
|
492
513
|
e.preventDefault();
|
|
@@ -496,6 +517,7 @@ var VideoPlayerControls = (props) => {
|
|
|
496
517
|
const {
|
|
497
518
|
variant,
|
|
498
519
|
fullScreenAction,
|
|
520
|
+
fullscreenAllowed,
|
|
499
521
|
showControl,
|
|
500
522
|
playAction,
|
|
501
523
|
pauseAction,
|
|
@@ -521,7 +543,7 @@ var VideoPlayerControls = (props) => {
|
|
|
521
543
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VideoPlayerControlStyles, { $isMobile: isMobile, onClick: stopControlClick, $showControl: showControl, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "video-player-control-row", children: [
|
|
522
544
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "full" }),
|
|
523
545
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { icon: muted ? "mute" : "sound", label: muted ? "Unmute" : "Mute", onClick: () => onMutedChange(!muted) }),
|
|
524
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
546
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { disabled: !fullscreenAllowed, icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
525
547
|
] }) });
|
|
526
548
|
}
|
|
527
549
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VideoPlayerControlStyles, { $isMobile: isMobile, onClick: stopControlClick, $showControl: showControl, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "video-player-control-row", children: [
|
|
@@ -533,7 +555,7 @@ var VideoPlayerControls = (props) => {
|
|
|
533
555
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SeekSlider, { playAction, duration, currentTime, seekSetTime }),
|
|
534
556
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TimeBlock, { duration, currentTime }),
|
|
535
557
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { icon: muted ? "mute" : "sound", label: muted ? "Unmute" : "Mute", onClick: () => onMutedChange(!muted) }),
|
|
536
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
558
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlButton, { disabled: !fullscreenAllowed, icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
537
559
|
] }) });
|
|
538
560
|
};
|
|
539
561
|
|
|
@@ -740,9 +762,18 @@ var isLikelyHlsSource = (src) => {
|
|
|
740
762
|
return /\.m3u8($|[?#])/i.test(src);
|
|
741
763
|
}
|
|
742
764
|
};
|
|
765
|
+
var assignRef = (ref, value) => {
|
|
766
|
+
if (!ref) return;
|
|
767
|
+
if (typeof ref === "function") {
|
|
768
|
+
ref(value);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
ref.current = value;
|
|
772
|
+
};
|
|
743
773
|
var VideoPlayerBase = (props, ref) => {
|
|
744
774
|
const {
|
|
745
775
|
controlsVariant = "none",
|
|
776
|
+
active,
|
|
746
777
|
autoPlay = false,
|
|
747
778
|
preload = "metadata",
|
|
748
779
|
loop = false,
|
|
@@ -760,6 +791,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
760
791
|
alwaysShowSegments = false,
|
|
761
792
|
initialTime = 0,
|
|
762
793
|
reloadKey,
|
|
794
|
+
videoRef: externalVideoRef,
|
|
763
795
|
onVideoRefChange,
|
|
764
796
|
handleClick = true,
|
|
765
797
|
onPointerDown,
|
|
@@ -815,6 +847,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
815
847
|
const muted = mutedProp != null ? mutedProp : mutedState;
|
|
816
848
|
const duration = durationProp != null ? durationProp : durationState;
|
|
817
849
|
const currentTime = currentTimeProp != null ? currentTimeProp : currentTimeState;
|
|
850
|
+
const fullscreenAllowed = active != null ? active : true;
|
|
818
851
|
const setTimeD = (0, import_react2.useRef)(
|
|
819
852
|
createThrottledNumberFn((value) => {
|
|
820
853
|
const v = videoRef.current;
|
|
@@ -901,6 +934,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
901
934
|
prev.removeEventListener("durationchange", onDur);
|
|
902
935
|
}
|
|
903
936
|
videoRef.current = el;
|
|
937
|
+
assignRef(externalVideoRef, el);
|
|
904
938
|
onVideoRefChange == null ? void 0 : onVideoRefChange(el);
|
|
905
939
|
notifyActiveChange(el, "ref");
|
|
906
940
|
if (!el) return;
|
|
@@ -908,7 +942,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
908
942
|
el.addEventListener("timeupdate", onTime);
|
|
909
943
|
el.addEventListener("durationchange", onDur);
|
|
910
944
|
},
|
|
911
|
-
[muted, notifyActiveChange, onDur, onTime, onVideoRefChange]
|
|
945
|
+
[externalVideoRef, muted, notifyActiveChange, onDur, onTime, onVideoRefChange]
|
|
912
946
|
);
|
|
913
947
|
const pauseOtherVideos = (0, import_react2.useCallback)(
|
|
914
948
|
(el) => {
|
|
@@ -1235,6 +1269,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1235
1269
|
else if (doc.msExitFullscreen) void doc.msExitFullscreen();
|
|
1236
1270
|
return;
|
|
1237
1271
|
}
|
|
1272
|
+
if (!fullscreenAllowed) return;
|
|
1238
1273
|
if (containerEl) {
|
|
1239
1274
|
if (containerEl.requestFullscreen) void containerEl.requestFullscreen();
|
|
1240
1275
|
else if (containerEl.webkitRequestFullscreen) void containerEl.webkitRequestFullscreen();
|
|
@@ -1246,7 +1281,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1246
1281
|
if (videoEl.requestFullscreen) void videoEl.requestFullscreen();
|
|
1247
1282
|
else if (videoEl.webkitEnterFullscreen) void videoEl.webkitEnterFullscreen();
|
|
1248
1283
|
}
|
|
1249
|
-
}, []);
|
|
1284
|
+
}, [fullscreenAllowed]);
|
|
1250
1285
|
const videoDbClickHandler = (0, import_react2.useCallback)(() => {
|
|
1251
1286
|
if (!handleClick) return;
|
|
1252
1287
|
fullScreenAction();
|
|
@@ -1429,6 +1464,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1429
1464
|
{
|
|
1430
1465
|
variant: controlsVariant,
|
|
1431
1466
|
fullScreenAction,
|
|
1467
|
+
fullscreenAllowed,
|
|
1432
1468
|
showControl,
|
|
1433
1469
|
playAction,
|
|
1434
1470
|
pauseAction,
|
package/dist/index.d.cts
CHANGED
|
@@ -37,6 +37,7 @@ interface VideoPlayerProps extends Omit<React.VideoHTMLAttributes<HTMLVideoEleme
|
|
|
37
37
|
sourceType?: 'auto' | 'hls' | 'native';
|
|
38
38
|
type?: string;
|
|
39
39
|
controlsVariant: ControlsVariant;
|
|
40
|
+
active?: boolean;
|
|
40
41
|
autoPlay?: boolean;
|
|
41
42
|
preload?: '' | 'none' | 'auto' | 'metadata';
|
|
42
43
|
loop?: boolean;
|
|
@@ -61,6 +62,7 @@ interface VideoPlayerProps extends Omit<React.VideoHTMLAttributes<HTMLVideoEleme
|
|
|
61
62
|
duration?: number;
|
|
62
63
|
onTimeChange?: (time: number, video: HTMLVideoElement) => void;
|
|
63
64
|
onDurationChange?: (duration: number, video: HTMLVideoElement) => void;
|
|
65
|
+
videoRef?: React.Ref<HTMLVideoElement>;
|
|
64
66
|
onVideoRefChange?: (video: HTMLVideoElement | null) => void;
|
|
65
67
|
onActiveChange?: (payload: VideoPlayerActiveChangePayload) => void;
|
|
66
68
|
onPlaybackError?: (payload: VideoPlayerPlaybackError) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ interface VideoPlayerProps extends Omit<React.VideoHTMLAttributes<HTMLVideoEleme
|
|
|
37
37
|
sourceType?: 'auto' | 'hls' | 'native';
|
|
38
38
|
type?: string;
|
|
39
39
|
controlsVariant: ControlsVariant;
|
|
40
|
+
active?: boolean;
|
|
40
41
|
autoPlay?: boolean;
|
|
41
42
|
preload?: '' | 'none' | 'auto' | 'metadata';
|
|
42
43
|
loop?: boolean;
|
|
@@ -61,6 +62,7 @@ interface VideoPlayerProps extends Omit<React.VideoHTMLAttributes<HTMLVideoEleme
|
|
|
61
62
|
duration?: number;
|
|
62
63
|
onTimeChange?: (time: number, video: HTMLVideoElement) => void;
|
|
63
64
|
onDurationChange?: (duration: number, video: HTMLVideoElement) => void;
|
|
65
|
+
videoRef?: React.Ref<HTMLVideoElement>;
|
|
64
66
|
onVideoRefChange?: (video: HTMLVideoElement | null) => void;
|
|
65
67
|
onActiveChange?: (payload: VideoPlayerActiveChangePayload) => void;
|
|
66
68
|
onPlaybackError?: (payload: VideoPlayerPlaybackError) => void;
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,15 @@ var VideoPlayerControlStyles = styled.div`
|
|
|
58
58
|
outline: none;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
.video-player-control-button:disabled {
|
|
62
|
+
opacity: 0.42;
|
|
63
|
+
cursor: not-allowed;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.video-player-control-button:disabled:hover {
|
|
67
|
+
background: rgba(255, 255, 255, 0.12);
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
.video-player-icon {
|
|
62
71
|
width: 17px;
|
|
63
72
|
height: 17px;
|
|
@@ -453,11 +462,23 @@ var Icon = ({ name }) => {
|
|
|
453
462
|
return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", className: "video-player-icon", focusable: "false", viewBox: "0 0 24 24", children: paths[name] });
|
|
454
463
|
};
|
|
455
464
|
var ControlButton = ({
|
|
465
|
+
disabled,
|
|
456
466
|
icon,
|
|
457
467
|
label,
|
|
458
468
|
onClick
|
|
459
469
|
}) => {
|
|
460
|
-
return /* @__PURE__ */ jsx(
|
|
470
|
+
return /* @__PURE__ */ jsx(
|
|
471
|
+
"button",
|
|
472
|
+
{
|
|
473
|
+
"aria-label": label,
|
|
474
|
+
className: "video-player-control-button",
|
|
475
|
+
disabled,
|
|
476
|
+
onClick: () => void onClick(),
|
|
477
|
+
title: label,
|
|
478
|
+
type: "button",
|
|
479
|
+
children: /* @__PURE__ */ jsx(Icon, { name: icon })
|
|
480
|
+
}
|
|
481
|
+
);
|
|
461
482
|
};
|
|
462
483
|
var stopControlClick = (e) => {
|
|
463
484
|
e.preventDefault();
|
|
@@ -467,6 +488,7 @@ var VideoPlayerControls = (props) => {
|
|
|
467
488
|
const {
|
|
468
489
|
variant,
|
|
469
490
|
fullScreenAction,
|
|
491
|
+
fullscreenAllowed,
|
|
470
492
|
showControl,
|
|
471
493
|
playAction,
|
|
472
494
|
pauseAction,
|
|
@@ -492,7 +514,7 @@ var VideoPlayerControls = (props) => {
|
|
|
492
514
|
return /* @__PURE__ */ jsx(VideoPlayerControlStyles, { $isMobile: isMobile, onClick: stopControlClick, $showControl: showControl, children: /* @__PURE__ */ jsxs("div", { className: "video-player-control-row", children: [
|
|
493
515
|
/* @__PURE__ */ jsx("div", { className: "full" }),
|
|
494
516
|
/* @__PURE__ */ jsx(ControlButton, { icon: muted ? "mute" : "sound", label: muted ? "Unmute" : "Mute", onClick: () => onMutedChange(!muted) }),
|
|
495
|
-
/* @__PURE__ */ jsx(ControlButton, { icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
517
|
+
/* @__PURE__ */ jsx(ControlButton, { disabled: !fullscreenAllowed, icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
496
518
|
] }) });
|
|
497
519
|
}
|
|
498
520
|
return /* @__PURE__ */ jsx(VideoPlayerControlStyles, { $isMobile: isMobile, onClick: stopControlClick, $showControl: showControl, children: /* @__PURE__ */ jsxs("div", { className: "video-player-control-row", children: [
|
|
@@ -504,7 +526,7 @@ var VideoPlayerControls = (props) => {
|
|
|
504
526
|
/* @__PURE__ */ jsx(SeekSlider, { playAction, duration, currentTime, seekSetTime }),
|
|
505
527
|
/* @__PURE__ */ jsx(TimeBlock, { duration, currentTime }),
|
|
506
528
|
/* @__PURE__ */ jsx(ControlButton, { icon: muted ? "mute" : "sound", label: muted ? "Unmute" : "Mute", onClick: () => onMutedChange(!muted) }),
|
|
507
|
-
/* @__PURE__ */ jsx(ControlButton, { icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
529
|
+
/* @__PURE__ */ jsx(ControlButton, { disabled: !fullscreenAllowed, icon: "fullscreen", label: "Fullscreen", onClick: fullScreenAction })
|
|
508
530
|
] }) });
|
|
509
531
|
};
|
|
510
532
|
|
|
@@ -711,9 +733,18 @@ var isLikelyHlsSource = (src) => {
|
|
|
711
733
|
return /\.m3u8($|[?#])/i.test(src);
|
|
712
734
|
}
|
|
713
735
|
};
|
|
736
|
+
var assignRef = (ref, value) => {
|
|
737
|
+
if (!ref) return;
|
|
738
|
+
if (typeof ref === "function") {
|
|
739
|
+
ref(value);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
ref.current = value;
|
|
743
|
+
};
|
|
714
744
|
var VideoPlayerBase = (props, ref) => {
|
|
715
745
|
const {
|
|
716
746
|
controlsVariant = "none",
|
|
747
|
+
active,
|
|
717
748
|
autoPlay = false,
|
|
718
749
|
preload = "metadata",
|
|
719
750
|
loop = false,
|
|
@@ -731,6 +762,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
731
762
|
alwaysShowSegments = false,
|
|
732
763
|
initialTime = 0,
|
|
733
764
|
reloadKey,
|
|
765
|
+
videoRef: externalVideoRef,
|
|
734
766
|
onVideoRefChange,
|
|
735
767
|
handleClick = true,
|
|
736
768
|
onPointerDown,
|
|
@@ -786,6 +818,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
786
818
|
const muted = mutedProp != null ? mutedProp : mutedState;
|
|
787
819
|
const duration = durationProp != null ? durationProp : durationState;
|
|
788
820
|
const currentTime = currentTimeProp != null ? currentTimeProp : currentTimeState;
|
|
821
|
+
const fullscreenAllowed = active != null ? active : true;
|
|
789
822
|
const setTimeD = useRef(
|
|
790
823
|
createThrottledNumberFn((value) => {
|
|
791
824
|
const v = videoRef.current;
|
|
@@ -872,6 +905,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
872
905
|
prev.removeEventListener("durationchange", onDur);
|
|
873
906
|
}
|
|
874
907
|
videoRef.current = el;
|
|
908
|
+
assignRef(externalVideoRef, el);
|
|
875
909
|
onVideoRefChange == null ? void 0 : onVideoRefChange(el);
|
|
876
910
|
notifyActiveChange(el, "ref");
|
|
877
911
|
if (!el) return;
|
|
@@ -879,7 +913,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
879
913
|
el.addEventListener("timeupdate", onTime);
|
|
880
914
|
el.addEventListener("durationchange", onDur);
|
|
881
915
|
},
|
|
882
|
-
[muted, notifyActiveChange, onDur, onTime, onVideoRefChange]
|
|
916
|
+
[externalVideoRef, muted, notifyActiveChange, onDur, onTime, onVideoRefChange]
|
|
883
917
|
);
|
|
884
918
|
const pauseOtherVideos = useCallback(
|
|
885
919
|
(el) => {
|
|
@@ -1206,6 +1240,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1206
1240
|
else if (doc.msExitFullscreen) void doc.msExitFullscreen();
|
|
1207
1241
|
return;
|
|
1208
1242
|
}
|
|
1243
|
+
if (!fullscreenAllowed) return;
|
|
1209
1244
|
if (containerEl) {
|
|
1210
1245
|
if (containerEl.requestFullscreen) void containerEl.requestFullscreen();
|
|
1211
1246
|
else if (containerEl.webkitRequestFullscreen) void containerEl.webkitRequestFullscreen();
|
|
@@ -1217,7 +1252,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1217
1252
|
if (videoEl.requestFullscreen) void videoEl.requestFullscreen();
|
|
1218
1253
|
else if (videoEl.webkitEnterFullscreen) void videoEl.webkitEnterFullscreen();
|
|
1219
1254
|
}
|
|
1220
|
-
}, []);
|
|
1255
|
+
}, [fullscreenAllowed]);
|
|
1221
1256
|
const videoDbClickHandler = useCallback(() => {
|
|
1222
1257
|
if (!handleClick) return;
|
|
1223
1258
|
fullScreenAction();
|
|
@@ -1400,6 +1435,7 @@ var VideoPlayerBase = (props, ref) => {
|
|
|
1400
1435
|
{
|
|
1401
1436
|
variant: controlsVariant,
|
|
1402
1437
|
fullScreenAction,
|
|
1438
|
+
fullscreenAllowed,
|
|
1403
1439
|
showControl,
|
|
1404
1440
|
playAction,
|
|
1405
1441
|
pauseAction,
|