softbuilders-react-video-player 1.1.7 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -21
- package/README.md +126 -126
- package/dist/components/BigPlayButton/index.tsx +31 -31
- package/dist/components/BufferTracker/index.tsx +19 -19
- package/dist/components/ChapterTooltip/index.tsx +65 -65
- package/dist/components/ChaptersPanal/index.tsx +40 -40
- package/dist/components/ControlBar/index.d.ts +2 -1
- package/dist/components/ControlBar/index.js +19 -5
- package/dist/components/ControlBar/index.js.map +1 -1
- package/dist/components/ControlBar/index.tsx +149 -127
- package/dist/components/CreateNoteMenu/index.tsx +61 -61
- package/dist/components/CurrentTimeLabel/index.tsx +13 -13
- package/dist/components/CurrentTimeTracker/index.tsx +18 -18
- package/dist/components/Menu/index.tsx +49 -49
- package/dist/components/MenuButton/index.js +1 -1
- package/dist/components/MenuButton/index.js.map +1 -1
- package/dist/components/MenuButton/index.tsx +67 -67
- package/dist/components/NoteTooltip/index.tsx +46 -46
- package/dist/components/NotesPanal/index.tsx +34 -34
- package/dist/components/QualityMenu/index.js +2 -2
- package/dist/components/QualityMenu/index.js.map +1 -1
- package/dist/components/QualityMenu/index.tsx +122 -122
- package/dist/components/Slider/index.d.ts +1 -1
- package/dist/components/Slider/index.js +3 -3
- package/dist/components/Slider/index.js.map +1 -1
- package/dist/components/Slider/index.tsx +36 -37
- package/dist/components/Slider/style.css +49 -15
- package/dist/components/SoftBuildersVideoPlayer/index.js +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.js.map +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.tsx +110 -109
- package/dist/components/SubtitleMenu/index.js +2 -2
- package/dist/components/SubtitleMenu/index.js.map +1 -1
- package/dist/components/SubtitleMenu/index.tsx +107 -108
- package/dist/components/TimeSlider/index.js +13 -13
- package/dist/components/TimeSlider/index.tsx +107 -107
- package/dist/components/TimeSliderContainer/index.tsx +35 -35
- package/dist/components/Tooltip/index.tsx +16 -16
- package/dist/components/VideoPlayerComponent/index.d.ts +2 -1
- package/dist/components/VideoPlayerComponent/index.js +37 -34
- package/dist/components/VideoPlayerComponent/index.js.map +1 -1
- package/dist/components/VideoPlayerComponent/index.tsx +260 -249
- package/dist/components/VideoPlayerComponent/provider.tsx +82 -82
- package/dist/components/VideoPlayerComponent/style/style.css +36 -36
- package/dist/components/VolumeSlider/index.d.ts +4 -2
- package/dist/components/VolumeSlider/index.js +12 -2
- package/dist/components/VolumeSlider/index.js.map +1 -1
- package/dist/components/VolumeSlider/index.tsx +91 -52
- package/dist/components/icons/SubIcon.d.ts +3 -0
- package/dist/components/icons/SubIcon.js +4 -0
- package/dist/components/icons/SubIcon.js.map +1 -0
- package/dist/components/icons/SubIcon.tsx +28 -0
- package/dist/components/icons/index.d.ts +1 -0
- package/dist/components/icons/index.js +1 -0
- package/dist/components/icons/index.js.map +1 -1
- package/dist/components/icons/index.ts +15 -14
- package/dist/images/index.d.ts +1 -0
- package/dist/images/index.js +1 -0
- package/dist/images/index.js.map +1 -1
- package/dist/index.css +75 -3
- package/dist/index.mjs +253 -166
- package/dist/styles/tailwind.css +137 -87
- package/package.json +45 -45
package/LICENSE
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) 2024 masri-softbuilders
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 masri-softbuilders
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
@@ -1,126 +1,126 @@
|
|
1
|
-
# Usage
|
2
|
-
|
3
|
-
## install the package
|
4
|
-
|
5
|
-
```bash
|
6
|
-
npm i softbuilders-video-player
|
7
|
-
```
|
8
|
-
|
9
|
-
## How to use
|
10
|
-
|
11
|
-
```typescript
|
12
|
-
import SoftBuildersVideoPlayer, {
|
13
|
-
SoftBuildersVideoPlayerOptions,
|
14
|
-
SoftBuildersVideoPlayerChapter,
|
15
|
-
SoftBuildersVideoPlayerNote,
|
16
|
-
} from "softbuilders-video-player";
|
17
|
-
|
18
|
-
const options: SoftBuildersVideoPlayerOptions = {
|
19
|
-
autoplay: false,
|
20
|
-
controls: true,
|
21
|
-
muted: true,
|
22
|
-
fluid: true,
|
23
|
-
poster: "http://example.com/thumbnail.png", // thumbnail preview image
|
24
|
-
height: 420,
|
25
|
-
width: 720,
|
26
|
-
sources: [
|
27
|
-
{
|
28
|
-
src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.360p.vp9.webm",
|
29
|
-
type: "video/webm",
|
30
|
-
label: "360p",
|
31
|
-
},
|
32
|
-
{
|
33
|
-
src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.1080p.vp9.webm",
|
34
|
-
type: "video/webm",
|
35
|
-
label: "1080P",
|
36
|
-
},
|
37
|
-
],
|
38
|
-
tracks: [
|
39
|
-
{
|
40
|
-
kind: "captions",
|
41
|
-
src: "https://raw.githubusercontent.com/brenopolanski/html5-video-webvtt-example/master/MIB2-subtitles-pt-BR.vtt",
|
42
|
-
srclang: "en",
|
43
|
-
label: "English",
|
44
|
-
memeType: "text/vtt", // text/vtt or text/srt
|
45
|
-
default: true,
|
46
|
-
},
|
47
|
-
{
|
48
|
-
kind: "captions",
|
49
|
-
src: "https://gist.githubusercontent.com/samdutton/ca37f3adaf4e23679957b8083e061177/raw/e19399fbccbc069a2af4266e5120ae6bad62699a/sample.vtt",
|
50
|
-
srclang: "es",
|
51
|
-
label: "Espaniol",
|
52
|
-
memeType: "text/vtt", // text/vtt or text/srt
|
53
|
-
},
|
54
|
-
], // only vtt suptitilers are supported for now
|
55
|
-
};
|
56
|
-
|
57
|
-
const initNotes: SoftBuildersVideoPlayerNote[] = [
|
58
|
-
{
|
59
|
-
time: 5,
|
60
|
-
label: "Start",
|
61
|
-
},
|
62
|
-
{
|
63
|
-
time: 30,
|
64
|
-
label: "Say Hello",
|
65
|
-
},
|
66
|
-
{
|
67
|
-
time: 69,
|
68
|
-
label: "Go deep",
|
69
|
-
},
|
70
|
-
{
|
71
|
-
time: 99,
|
72
|
-
label: "Details ...",
|
73
|
-
},
|
74
|
-
{
|
75
|
-
time: 140,
|
76
|
-
label: "End",
|
77
|
-
},
|
78
|
-
];
|
79
|
-
|
80
|
-
const initChapters: SoftBuildersVideoPlayerChapter[] = [
|
81
|
-
{
|
82
|
-
startTime: 25,
|
83
|
-
endTime: 50,
|
84
|
-
title: "01 Note: **** Important ****",
|
85
|
-
},
|
86
|
-
{
|
87
|
-
startTime: 70,
|
88
|
-
endTime: 100,
|
89
|
-
title: "02 Note: To Do",
|
90
|
-
},
|
91
|
-
{ startTime: 110, endTime: 120, title: "03 Note: DIY (Do it yourself)" },
|
92
|
-
{
|
93
|
-
startTime: 125,
|
94
|
-
endTime: 140,
|
95
|
-
title: "05 Note: Conclusion ",
|
96
|
-
},
|
97
|
-
];
|
98
|
-
|
99
|
-
const Component = () => {
|
100
|
-
const handleSaveNoteAction = (time: number, note: string) => {
|
101
|
-
return new Promise((resolve) => {
|
102
|
-
resolve(true);
|
103
|
-
});
|
104
|
-
};
|
105
|
-
|
106
|
-
const onPause = (time: number) => {
|
107
|
-
console.log(`Video has been Paused at time (${time} sec)`);
|
108
|
-
};
|
109
|
-
const onPlay = (time: number) => {
|
110
|
-
console.log(`Video has been Played at time (${time} sec)`);
|
111
|
-
};
|
112
|
-
|
113
|
-
return (
|
114
|
-
<SoftBuildersVideoPlayer
|
115
|
-
options={options}
|
116
|
-
chapters={initChapters}
|
117
|
-
notes={initNotes}
|
118
|
-
handleSaveNoteAction={handleSaveNoteAction}
|
119
|
-
onPause={onPause}
|
120
|
-
onPlay={onPlay}
|
121
|
-
/>
|
122
|
-
);
|
123
|
-
};
|
124
|
-
|
125
|
-
export default Component;
|
126
|
-
```
|
1
|
+
# Usage
|
2
|
+
|
3
|
+
## install the package
|
4
|
+
|
5
|
+
```bash
|
6
|
+
npm i softbuilders-video-player
|
7
|
+
```
|
8
|
+
|
9
|
+
## How to use
|
10
|
+
|
11
|
+
```typescript
|
12
|
+
import SoftBuildersVideoPlayer, {
|
13
|
+
SoftBuildersVideoPlayerOptions,
|
14
|
+
SoftBuildersVideoPlayerChapter,
|
15
|
+
SoftBuildersVideoPlayerNote,
|
16
|
+
} from "softbuilders-video-player";
|
17
|
+
|
18
|
+
const options: SoftBuildersVideoPlayerOptions = {
|
19
|
+
autoplay: false,
|
20
|
+
controls: true,
|
21
|
+
muted: true,
|
22
|
+
fluid: true,
|
23
|
+
poster: "http://example.com/thumbnail.png", // thumbnail preview image
|
24
|
+
height: 420,
|
25
|
+
width: 720,
|
26
|
+
sources: [
|
27
|
+
{
|
28
|
+
src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.360p.vp9.webm",
|
29
|
+
type: "video/webm",
|
30
|
+
label: "360p",
|
31
|
+
},
|
32
|
+
{
|
33
|
+
src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.1080p.vp9.webm",
|
34
|
+
type: "video/webm",
|
35
|
+
label: "1080P",
|
36
|
+
},
|
37
|
+
],
|
38
|
+
tracks: [
|
39
|
+
{
|
40
|
+
kind: "captions",
|
41
|
+
src: "https://raw.githubusercontent.com/brenopolanski/html5-video-webvtt-example/master/MIB2-subtitles-pt-BR.vtt",
|
42
|
+
srclang: "en",
|
43
|
+
label: "English",
|
44
|
+
memeType: "text/vtt", // text/vtt or text/srt
|
45
|
+
default: true,
|
46
|
+
},
|
47
|
+
{
|
48
|
+
kind: "captions",
|
49
|
+
src: "https://gist.githubusercontent.com/samdutton/ca37f3adaf4e23679957b8083e061177/raw/e19399fbccbc069a2af4266e5120ae6bad62699a/sample.vtt",
|
50
|
+
srclang: "es",
|
51
|
+
label: "Espaniol",
|
52
|
+
memeType: "text/vtt", // text/vtt or text/srt
|
53
|
+
},
|
54
|
+
], // only vtt suptitilers are supported for now
|
55
|
+
};
|
56
|
+
|
57
|
+
const initNotes: SoftBuildersVideoPlayerNote[] = [
|
58
|
+
{
|
59
|
+
time: 5,
|
60
|
+
label: "Start",
|
61
|
+
},
|
62
|
+
{
|
63
|
+
time: 30,
|
64
|
+
label: "Say Hello",
|
65
|
+
},
|
66
|
+
{
|
67
|
+
time: 69,
|
68
|
+
label: "Go deep",
|
69
|
+
},
|
70
|
+
{
|
71
|
+
time: 99,
|
72
|
+
label: "Details ...",
|
73
|
+
},
|
74
|
+
{
|
75
|
+
time: 140,
|
76
|
+
label: "End",
|
77
|
+
},
|
78
|
+
];
|
79
|
+
|
80
|
+
const initChapters: SoftBuildersVideoPlayerChapter[] = [
|
81
|
+
{
|
82
|
+
startTime: 25,
|
83
|
+
endTime: 50,
|
84
|
+
title: "01 Note: **** Important ****",
|
85
|
+
},
|
86
|
+
{
|
87
|
+
startTime: 70,
|
88
|
+
endTime: 100,
|
89
|
+
title: "02 Note: To Do",
|
90
|
+
},
|
91
|
+
{ startTime: 110, endTime: 120, title: "03 Note: DIY (Do it yourself)" },
|
92
|
+
{
|
93
|
+
startTime: 125,
|
94
|
+
endTime: 140,
|
95
|
+
title: "05 Note: Conclusion ",
|
96
|
+
},
|
97
|
+
];
|
98
|
+
|
99
|
+
const Component = () => {
|
100
|
+
const handleSaveNoteAction = (time: number, note: string) => {
|
101
|
+
return new Promise((resolve) => {
|
102
|
+
resolve(true);
|
103
|
+
});
|
104
|
+
};
|
105
|
+
|
106
|
+
const onPause = (time: number) => {
|
107
|
+
console.log(`Video has been Paused at time (${time} sec)`);
|
108
|
+
};
|
109
|
+
const onPlay = (time: number) => {
|
110
|
+
console.log(`Video has been Played at time (${time} sec)`);
|
111
|
+
};
|
112
|
+
|
113
|
+
return (
|
114
|
+
<SoftBuildersVideoPlayer
|
115
|
+
options={options}
|
116
|
+
chapters={initChapters}
|
117
|
+
notes={initNotes}
|
118
|
+
handleSaveNoteAction={handleSaveNoteAction}
|
119
|
+
onPause={onPause}
|
120
|
+
onPlay={onPlay}
|
121
|
+
/>
|
122
|
+
);
|
123
|
+
};
|
124
|
+
|
125
|
+
export default Component;
|
126
|
+
```
|
@@ -1,31 +1,31 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import Player from "video.js/dist/types/player";
|
3
|
-
import { PauseIcon, PlayIcon } from "../../images";
|
4
|
-
|
5
|
-
type Props = {
|
6
|
-
player: Player | undefined;
|
7
|
-
isPaused: boolean;
|
8
|
-
setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
|
9
|
-
};
|
10
|
-
const BigPlayButton = ({ player, isPaused, setIsPaused }: Props) => {
|
11
|
-
const togglePlay = () => {
|
12
|
-
if (isPaused) player?.play();
|
13
|
-
else player?.pause();
|
14
|
-
|
15
|
-
setIsPaused(!isPaused);
|
16
|
-
};
|
17
|
-
|
18
|
-
return (
|
19
|
-
<button onClick={togglePlay}>
|
20
|
-
<div className="sb-w-16 sb-h-16 sb-rounded-full sb-bg-white/30 sb-backdrop-blur-lg sb-flex sb-items-center sb-justify-center ">
|
21
|
-
{isPaused ? (
|
22
|
-
<PlayIcon className="sb-w-4 sb-h-4" />
|
23
|
-
) : (
|
24
|
-
<PauseIcon className="sb-w-4 sb-h-4" />
|
25
|
-
)}
|
26
|
-
</div>
|
27
|
-
</button>
|
28
|
-
);
|
29
|
-
};
|
30
|
-
|
31
|
-
export default BigPlayButton;
|
1
|
+
import React from "react";
|
2
|
+
import Player from "video.js/dist/types/player";
|
3
|
+
import { PauseIcon, PlayIcon } from "../../images";
|
4
|
+
|
5
|
+
type Props = {
|
6
|
+
player: Player | undefined;
|
7
|
+
isPaused: boolean;
|
8
|
+
setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
|
9
|
+
};
|
10
|
+
const BigPlayButton = ({ player, isPaused, setIsPaused }: Props) => {
|
11
|
+
const togglePlay = () => {
|
12
|
+
if (isPaused) player?.play();
|
13
|
+
else player?.pause();
|
14
|
+
|
15
|
+
setIsPaused(!isPaused);
|
16
|
+
};
|
17
|
+
|
18
|
+
return (
|
19
|
+
<button onClick={togglePlay}>
|
20
|
+
<div className="sb-w-16 sb-h-16 sb-rounded-full sb-bg-white/30 sb-backdrop-blur-lg sb-flex sb-items-center sb-justify-center ">
|
21
|
+
{isPaused ? (
|
22
|
+
<PlayIcon className="sb-w-4 sb-h-4" />
|
23
|
+
) : (
|
24
|
+
<PauseIcon className="sb-w-4 sb-h-4" />
|
25
|
+
)}
|
26
|
+
</div>
|
27
|
+
</button>
|
28
|
+
);
|
29
|
+
};
|
30
|
+
|
31
|
+
export default BigPlayButton;
|
@@ -1,19 +1,19 @@
|
|
1
|
-
import React, { useEffect } from "react";
|
2
|
-
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
3
|
-
|
4
|
-
const BufferTracker = () => {
|
5
|
-
const { player, setDownloadedBufferTimeufferTime } =
|
6
|
-
useSoftBuildersVideoPlayerContext();
|
7
|
-
|
8
|
-
useEffect(() => {
|
9
|
-
const intervalId = setInterval(() => {
|
10
|
-
if (player) setDownloadedBufferTimeufferTime(player.bufferedEnd());
|
11
|
-
}, 1000);
|
12
|
-
|
13
|
-
// Cleanup function to clear the interval
|
14
|
-
return () => clearInterval(intervalId);
|
15
|
-
}, [player]);
|
16
|
-
return <></>;
|
17
|
-
};
|
18
|
-
|
19
|
-
export default BufferTracker;
|
1
|
+
import React, { useEffect } from "react";
|
2
|
+
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
3
|
+
|
4
|
+
const BufferTracker = () => {
|
5
|
+
const { player, setDownloadedBufferTimeufferTime } =
|
6
|
+
useSoftBuildersVideoPlayerContext();
|
7
|
+
|
8
|
+
useEffect(() => {
|
9
|
+
const intervalId = setInterval(() => {
|
10
|
+
if (player) setDownloadedBufferTimeufferTime(player.bufferedEnd());
|
11
|
+
}, 1000);
|
12
|
+
|
13
|
+
// Cleanup function to clear the interval
|
14
|
+
return () => clearInterval(intervalId);
|
15
|
+
}, [player]);
|
16
|
+
return <></>;
|
17
|
+
};
|
18
|
+
|
19
|
+
export default BufferTracker;
|
@@ -1,65 +1,65 @@
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
2
|
-
import Tooltip from "../Tooltip";
|
3
|
-
import { durationFormater } from "../../utils";
|
4
|
-
import { SoftBuildersVideoPlayerChapter } from "../../types";
|
5
|
-
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
6
|
-
type Chapter = SoftBuildersVideoPlayerChapter & {
|
7
|
-
startPercentage: number;
|
8
|
-
endPercentage: number;
|
9
|
-
};
|
10
|
-
type Props = {
|
11
|
-
chapter: Chapter;
|
12
|
-
};
|
13
|
-
const ChapterTooltip = ({ chapter }: Props) => {
|
14
|
-
const { player } = useSoftBuildersVideoPlayerContext();
|
15
|
-
|
16
|
-
const [open, setOpen] = useState(false);
|
17
|
-
const { currentTime } = useSoftBuildersVideoPlayerContext();
|
18
|
-
|
19
|
-
useEffect(() => {
|
20
|
-
if (currentTime === Math.floor(chapter.startTime)) {
|
21
|
-
setOpen(true);
|
22
|
-
|
23
|
-
setTimeout(() => {
|
24
|
-
setOpen(false);
|
25
|
-
}, 5000);
|
26
|
-
}
|
27
|
-
}, [currentTime, chapter.startTime]);
|
28
|
-
|
29
|
-
const handleClickChapter = () => {
|
30
|
-
player?.currentTime(chapter.startTime);
|
31
|
-
};
|
32
|
-
|
33
|
-
return (
|
34
|
-
<div
|
35
|
-
id={`ii-section-${chapter.title}`}
|
36
|
-
className="sb-flex sb-items-center sb-w-full sb-h-full sb-absolute sb-z-20"
|
37
|
-
style={{
|
38
|
-
left: `${chapter.startPercentage}%`,
|
39
|
-
width: `${chapter.endPercentage - chapter.startPercentage}%`,
|
40
|
-
}}
|
41
|
-
onMouseEnter={() => setOpen(true)}
|
42
|
-
onMouseLeave={() => setOpen(false)}
|
43
|
-
>
|
44
|
-
<button
|
45
|
-
id={`section-${chapter.title}`}
|
46
|
-
className="sb-h-full sb-w-full"
|
47
|
-
onClick={handleClickChapter}
|
48
|
-
>
|
49
|
-
<div className="sb-relative sb-flex sb-h-full sb-w-full sb-justify-between sb-items-center">
|
50
|
-
<Tooltip open={open}>
|
51
|
-
<div className="sb-flex sb-flex-col sb-gap-2 sb-items-center">
|
52
|
-
<p>{chapter.title}</p>
|
53
|
-
<p className="sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md">
|
54
|
-
{durationFormater(chapter.startTime)} -{" "}
|
55
|
-
{durationFormater(chapter.endTime)}
|
56
|
-
</p>
|
57
|
-
</div>
|
58
|
-
</Tooltip>
|
59
|
-
</div>
|
60
|
-
</button>
|
61
|
-
</div>
|
62
|
-
);
|
63
|
-
};
|
64
|
-
|
65
|
-
export default ChapterTooltip;
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
import Tooltip from "../Tooltip";
|
3
|
+
import { durationFormater } from "../../utils";
|
4
|
+
import { SoftBuildersVideoPlayerChapter } from "../../types";
|
5
|
+
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
6
|
+
type Chapter = SoftBuildersVideoPlayerChapter & {
|
7
|
+
startPercentage: number;
|
8
|
+
endPercentage: number;
|
9
|
+
};
|
10
|
+
type Props = {
|
11
|
+
chapter: Chapter;
|
12
|
+
};
|
13
|
+
const ChapterTooltip = ({ chapter }: Props) => {
|
14
|
+
const { player } = useSoftBuildersVideoPlayerContext();
|
15
|
+
|
16
|
+
const [open, setOpen] = useState(false);
|
17
|
+
const { currentTime } = useSoftBuildersVideoPlayerContext();
|
18
|
+
|
19
|
+
useEffect(() => {
|
20
|
+
if (currentTime === Math.floor(chapter.startTime)) {
|
21
|
+
setOpen(true);
|
22
|
+
|
23
|
+
setTimeout(() => {
|
24
|
+
setOpen(false);
|
25
|
+
}, 5000);
|
26
|
+
}
|
27
|
+
}, [currentTime, chapter.startTime]);
|
28
|
+
|
29
|
+
const handleClickChapter = () => {
|
30
|
+
player?.currentTime(chapter.startTime);
|
31
|
+
};
|
32
|
+
|
33
|
+
return (
|
34
|
+
<div
|
35
|
+
id={`ii-section-${chapter.title}`}
|
36
|
+
className="sb-flex sb-items-center sb-w-full sb-h-full sb-absolute sb-z-20"
|
37
|
+
style={{
|
38
|
+
left: `${chapter.startPercentage}%`,
|
39
|
+
width: `${chapter.endPercentage - chapter.startPercentage}%`,
|
40
|
+
}}
|
41
|
+
onMouseEnter={() => setOpen(true)}
|
42
|
+
onMouseLeave={() => setOpen(false)}
|
43
|
+
>
|
44
|
+
<button
|
45
|
+
id={`section-${chapter.title}`}
|
46
|
+
className="sb-h-full sb-w-full"
|
47
|
+
onClick={handleClickChapter}
|
48
|
+
>
|
49
|
+
<div className="sb-relative sb-flex sb-h-full sb-w-full sb-justify-between sb-items-center">
|
50
|
+
<Tooltip open={open}>
|
51
|
+
<div className="sb-flex sb-flex-col sb-gap-2 sb-items-center">
|
52
|
+
<p>{chapter.title}</p>
|
53
|
+
<p className="sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md">
|
54
|
+
{durationFormater(chapter.startTime)} -{" "}
|
55
|
+
{durationFormater(chapter.endTime)}
|
56
|
+
</p>
|
57
|
+
</div>
|
58
|
+
</Tooltip>
|
59
|
+
</div>
|
60
|
+
</button>
|
61
|
+
</div>
|
62
|
+
);
|
63
|
+
};
|
64
|
+
|
65
|
+
export default ChapterTooltip;
|
@@ -1,40 +1,40 @@
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
2
|
-
|
3
|
-
import ChapterTooltip from "../ChapterTooltip";
|
4
|
-
import { SoftBuildersVideoPlayerChapter } from "../../types";
|
5
|
-
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
6
|
-
|
7
|
-
type Chapter = SoftBuildersVideoPlayerChapter & {
|
8
|
-
startPercentage: number;
|
9
|
-
endPercentage: number;
|
10
|
-
};
|
11
|
-
type Props = {
|
12
|
-
chapters: SoftBuildersVideoPlayerChapter[];
|
13
|
-
};
|
14
|
-
const ChaptersPanal = ({ chapters }: Props) => {
|
15
|
-
const [cs, setCs] = useState<Chapter[]>([]);
|
16
|
-
const { duration } = useSoftBuildersVideoPlayerContext();
|
17
|
-
|
18
|
-
useEffect(() => {
|
19
|
-
const newCs = chapters.map((c) => {
|
20
|
-
const startPercentage = Math.floor((c.startTime * 100) / duration);
|
21
|
-
const endPercentage = Math.floor((c.endTime * 100) / duration);
|
22
|
-
return {
|
23
|
-
...c,
|
24
|
-
startPercentage,
|
25
|
-
endPercentage,
|
26
|
-
};
|
27
|
-
});
|
28
|
-
setCs(newCs);
|
29
|
-
}, [chapters, duration]);
|
30
|
-
|
31
|
-
return (
|
32
|
-
<div id="chapters-panal" className="sb-w-full sb-h-full sb-relative ">
|
33
|
-
{cs.map((c, i) => (
|
34
|
-
<ChapterTooltip key={`chapter-${i}-${c.startTime}`} chapter={c} />
|
35
|
-
))}
|
36
|
-
</div>
|
37
|
-
);
|
38
|
-
};
|
39
|
-
|
40
|
-
export default ChaptersPanal;
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
|
3
|
+
import ChapterTooltip from "../ChapterTooltip";
|
4
|
+
import { SoftBuildersVideoPlayerChapter } from "../../types";
|
5
|
+
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
6
|
+
|
7
|
+
type Chapter = SoftBuildersVideoPlayerChapter & {
|
8
|
+
startPercentage: number;
|
9
|
+
endPercentage: number;
|
10
|
+
};
|
11
|
+
type Props = {
|
12
|
+
chapters: SoftBuildersVideoPlayerChapter[];
|
13
|
+
};
|
14
|
+
const ChaptersPanal = ({ chapters }: Props) => {
|
15
|
+
const [cs, setCs] = useState<Chapter[]>([]);
|
16
|
+
const { duration } = useSoftBuildersVideoPlayerContext();
|
17
|
+
|
18
|
+
useEffect(() => {
|
19
|
+
const newCs = chapters.map((c) => {
|
20
|
+
const startPercentage = Math.floor((c.startTime * 100) / duration);
|
21
|
+
const endPercentage = Math.floor((c.endTime * 100) / duration);
|
22
|
+
return {
|
23
|
+
...c,
|
24
|
+
startPercentage,
|
25
|
+
endPercentage,
|
26
|
+
};
|
27
|
+
});
|
28
|
+
setCs(newCs);
|
29
|
+
}, [chapters, duration]);
|
30
|
+
|
31
|
+
return (
|
32
|
+
<div id="chapters-panal" className="sb-w-full sb-h-full sb-relative ">
|
33
|
+
{cs.map((c, i) => (
|
34
|
+
<ChapterTooltip key={`chapter-${i}-${c.startTime}`} chapter={c} />
|
35
|
+
))}
|
36
|
+
</div>
|
37
|
+
);
|
38
|
+
};
|
39
|
+
|
40
|
+
export default ChaptersPanal;
|
@@ -9,7 +9,8 @@ type Props<T> = {
|
|
9
9
|
notes: SoftBuildersVideoPlayerNote[];
|
10
10
|
chapters: SoftBuildersVideoPlayerChapter[];
|
11
11
|
seekStep?: number;
|
12
|
+
id?: string;
|
12
13
|
handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
|
13
14
|
};
|
14
|
-
declare const ControlBar: <T>({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep, handleSaveNoteAction, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
|
15
|
+
declare const ControlBar: <T>({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep, id, handleSaveNoteAction, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
|
15
16
|
export default ControlBar;
|