customvidplayer 0.0.14 → 0.0.16
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.
@@ -11,6 +11,7 @@ declare namespace VideoPlayer {
|
|
11
11
|
const sections: PropTypes.Validator<(PropTypes.InferProps<{
|
12
12
|
name: PropTypes.Validator<string>;
|
13
13
|
timestamp: PropTypes.Validator<number>;
|
14
|
+
color: PropTypes.Requireable<string>;
|
14
15
|
}> | null | undefined)[]>;
|
15
16
|
const onSectionChange: PropTypes.Requireable<(...args: any[]) => any>;
|
16
17
|
const theme: PropTypes.Requireable<object>;
|
@@ -61,6 +61,9 @@ var VideoPlayer = function VideoPlayer(_a) {
|
|
61
61
|
var _b = (0, react_1.useState)(0),
|
62
62
|
currentSectionIndex = _b[0],
|
63
63
|
setCurrentSectionIndex = _b[1];
|
64
|
+
var _c = (0, react_1.useState)(false),
|
65
|
+
isPlaying = _c[0],
|
66
|
+
setIsPlaying = _c[1];
|
64
67
|
var skipToNextSection = function skipToNextSection() {
|
65
68
|
if (currentSectionIndex < sections.length - 1) {
|
66
69
|
var nextSection = sections[currentSectionIndex + 1];
|
@@ -70,14 +73,29 @@ var VideoPlayer = function VideoPlayer(_a) {
|
|
70
73
|
}
|
71
74
|
};
|
72
75
|
var handleTimeUpdate = function handleTimeUpdate() {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
if (videoRef.current) {
|
77
|
+
var currentTime_1 = videoRef.current.currentTime;
|
78
|
+
var currentSection = sections.find(function (section, index) {
|
79
|
+
return currentTime_1 >= section.timestamp && (index === sections.length - 1 || currentTime_1 < sections[index + 1].timestamp);
|
80
|
+
});
|
81
|
+
if (currentSection && sections[currentSectionIndex] !== currentSection) {
|
82
|
+
var newIndex = sections.indexOf(currentSection);
|
83
|
+
setCurrentSectionIndex(newIndex);
|
84
|
+
if (onSectionChange) onSectionChange(currentSection);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
};
|
88
|
+
var playVideo = function playVideo() {
|
89
|
+
videoRef.current.play();
|
90
|
+
setIsPlaying(true);
|
91
|
+
};
|
92
|
+
var pauseVideo = function pauseVideo() {
|
93
|
+
videoRef.current.pause();
|
94
|
+
setIsPlaying(false);
|
95
|
+
};
|
96
|
+
var skipForward = function skipForward() {
|
97
|
+
if (videoRef.current) {
|
98
|
+
videoRef.current.currentTime += 10;
|
81
99
|
}
|
82
100
|
};
|
83
101
|
return react_1["default"].createElement("div", {
|
@@ -85,20 +103,41 @@ var VideoPlayer = function VideoPlayer(_a) {
|
|
85
103
|
style: __assign({}, theme)
|
86
104
|
}, react_1["default"].createElement("video", {
|
87
105
|
src: videoSrc,
|
88
|
-
controls:
|
106
|
+
controls: false,
|
89
107
|
ref: videoRef,
|
90
108
|
onTimeUpdate: handleTimeUpdate,
|
91
109
|
className: "video-element"
|
92
|
-
}), react_1["default"].createElement("
|
110
|
+
}), react_1["default"].createElement("div", {
|
111
|
+
className: "bottom-bar",
|
112
|
+
style: {
|
113
|
+
backgroundColor: theme.bottomBarColor || '#000'
|
114
|
+
}
|
115
|
+
}, react_1["default"].createElement("button", {
|
116
|
+
onClick: isPlaying ? pauseVideo : playVideo
|
117
|
+
}, isPlaying ? 'Pause' : 'Play'), react_1["default"].createElement("button", {
|
118
|
+
onClick: skipForward
|
119
|
+
}, "Skip 10s"), react_1["default"].createElement("button", {
|
93
120
|
onClick: skipToNextSection,
|
94
121
|
className: "skip-button"
|
95
|
-
}, "Skip"))
|
122
|
+
}, "Skip")), react_1["default"].createElement("div", {
|
123
|
+
className: "progress-bar"
|
124
|
+
}, sections.map(function (section, index) {
|
125
|
+
return react_1["default"].createElement("div", {
|
126
|
+
key: index,
|
127
|
+
className: "section-indicator",
|
128
|
+
style: {
|
129
|
+
left: videoRef.current ? "".concat(section.timestamp / videoRef.current.duration * 100, "%") : '0%',
|
130
|
+
backgroundColor: section.color || '#007bff'
|
131
|
+
}
|
132
|
+
}, section.name);
|
133
|
+
})));
|
96
134
|
};
|
97
135
|
VideoPlayer.propTypes = {
|
98
136
|
videoSrc: prop_types_1["default"].string.isRequired,
|
99
137
|
sections: prop_types_1["default"].arrayOf(prop_types_1["default"].shape({
|
100
138
|
name: prop_types_1["default"].string.isRequired,
|
101
|
-
timestamp: prop_types_1["default"].number.isRequired
|
139
|
+
timestamp: prop_types_1["default"].number.isRequired,
|
140
|
+
color: prop_types_1["default"].string
|
102
141
|
})).isRequired,
|
103
142
|
onSectionChange: prop_types_1["default"].func,
|
104
143
|
theme: prop_types_1["default"].object
|
package/package.json
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
import React, { useState, useRef } from "react";
|
1
|
+
import React, { useState, useRef, useEffect } from "react";
|
2
2
|
import PropTypes from "prop-types";
|
3
3
|
import "./../styles/defaultTheme.css";
|
4
4
|
|
5
5
|
const VideoPlayer = ({ videoSrc, sections, onSectionChange, theme }) => {
|
6
6
|
const videoRef = useRef(null);
|
7
7
|
const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
|
8
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
8
9
|
|
9
10
|
const skipToNextSection = () => {
|
10
11
|
if (currentSectionIndex < sections.length - 1) {
|
@@ -16,17 +17,35 @@ const VideoPlayer = ({ videoSrc, sections, onSectionChange, theme }) => {
|
|
16
17
|
};
|
17
18
|
|
18
19
|
const handleTimeUpdate = () => {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
if (videoRef.current) {
|
21
|
+
const currentTime = videoRef.current.currentTime;
|
22
|
+
const currentSection = sections.find(
|
23
|
+
(section, index) =>
|
24
|
+
currentTime >= section.timestamp &&
|
25
|
+
(index === sections.length - 1 || currentTime < sections[index + 1].timestamp)
|
26
|
+
);
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
if (currentSection && sections[currentSectionIndex] !== currentSection) {
|
29
|
+
const newIndex = sections.indexOf(currentSection);
|
30
|
+
setCurrentSectionIndex(newIndex);
|
31
|
+
if (onSectionChange) onSectionChange(currentSection);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
};
|
35
|
+
|
36
|
+
const playVideo = () => {
|
37
|
+
videoRef.current.play();
|
38
|
+
setIsPlaying(true);
|
39
|
+
};
|
40
|
+
|
41
|
+
const pauseVideo = () => {
|
42
|
+
videoRef.current.pause();
|
43
|
+
setIsPlaying(false);
|
44
|
+
};
|
45
|
+
|
46
|
+
const skipForward = () => {
|
47
|
+
if (videoRef.current) {
|
48
|
+
videoRef.current.currentTime += 10;
|
30
49
|
}
|
31
50
|
};
|
32
51
|
|
@@ -34,14 +53,34 @@ const VideoPlayer = ({ videoSrc, sections, onSectionChange, theme }) => {
|
|
34
53
|
<div className="video-player" style={{ ...theme }}>
|
35
54
|
<video
|
36
55
|
src={videoSrc}
|
37
|
-
controls
|
56
|
+
controls={false}
|
38
57
|
ref={videoRef}
|
39
58
|
onTimeUpdate={handleTimeUpdate}
|
40
59
|
className="video-element"
|
41
60
|
/>
|
42
|
-
<
|
43
|
-
|
44
|
-
|
61
|
+
<div className="bottom-bar" style={{ backgroundColor: theme.bottomBarColor || '#000' }}>
|
62
|
+
<button onClick={isPlaying ? pauseVideo : playVideo}>
|
63
|
+
{isPlaying ? 'Pause' : 'Play'}
|
64
|
+
</button>
|
65
|
+
<button onClick={skipForward}>Skip 10s</button>
|
66
|
+
<button onClick={skipToNextSection} className="skip-button">
|
67
|
+
Skip
|
68
|
+
</button>
|
69
|
+
</div>
|
70
|
+
<div className="progress-bar">
|
71
|
+
{sections.map((section, index) => (
|
72
|
+
<div
|
73
|
+
key={index}
|
74
|
+
className="section-indicator"
|
75
|
+
style={{
|
76
|
+
left: videoRef.current ? `${(section.timestamp / videoRef.current.duration) * 100}%` : '0%',
|
77
|
+
backgroundColor: section.color || '#007bff',
|
78
|
+
}}
|
79
|
+
>
|
80
|
+
{section.name}
|
81
|
+
</div>
|
82
|
+
))}
|
83
|
+
</div>
|
45
84
|
</div>
|
46
85
|
);
|
47
86
|
};
|
@@ -52,6 +91,7 @@ VideoPlayer.propTypes = {
|
|
52
91
|
PropTypes.shape({
|
53
92
|
name: PropTypes.string.isRequired,
|
54
93
|
timestamp: PropTypes.number.isRequired,
|
94
|
+
color: PropTypes.string,
|
55
95
|
})
|
56
96
|
).isRequired,
|
57
97
|
onSectionChange: PropTypes.func,
|
@@ -27,4 +27,24 @@
|
|
27
27
|
margin: 5px 0;
|
28
28
|
color: #007bff;
|
29
29
|
}
|
30
|
+
|
31
|
+
.bottom-bar {
|
32
|
+
display: flex;
|
33
|
+
justify-content: space-between;
|
34
|
+
padding: 10px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.progress-bar {
|
38
|
+
position: relative;
|
39
|
+
height: 5px;
|
40
|
+
background: #ccc;
|
41
|
+
margin-top: 5px;
|
42
|
+
}
|
43
|
+
|
44
|
+
.section-indicator {
|
45
|
+
position: absolute;
|
46
|
+
width: 5px;
|
47
|
+
height: 100%;
|
48
|
+
background: #007bff; /* Default color */
|
49
|
+
}
|
30
50
|
|