aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/assets/player/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-08-28 10:55:04 +0200
committerChocobozzz <me@florianbigard.com>2023-08-28 16:17:31 +0200
commit77b70702d2193d78bf6fbd07f0fc7335e34957f8 (patch)
tree1a0aed540054286c9a8b10c4890cc0f718e00458 /client/src/assets/player/shared
parent7113f32a87bd6b2868154fed20bde1a1633c190e (diff)
downloadPeerTube-77b70702d2193d78bf6fbd07f0fc7335e34957f8.tar.gz
PeerTube-77b70702d2193d78bf6fbd07f0fc7335e34957f8.tar.zst
PeerTube-77b70702d2193d78bf6fbd07f0fc7335e34957f8.zip
Add video chapters support
Diffstat (limited to 'client/src/assets/player/shared')
-rw-r--r--client/src/assets/player/shared/control-bar/chapters-plugin.ts64
-rw-r--r--client/src/assets/player/shared/control-bar/index.ts2
-rw-r--r--client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts24
-rw-r--r--client/src/assets/player/shared/control-bar/storyboard-plugin.ts4
-rw-r--r--client/src/assets/player/shared/control-bar/time-tooltip.ts20
5 files changed, 113 insertions, 1 deletions
diff --git a/client/src/assets/player/shared/control-bar/chapters-plugin.ts b/client/src/assets/player/shared/control-bar/chapters-plugin.ts
new file mode 100644
index 000000000..5be081694
--- /dev/null
+++ b/client/src/assets/player/shared/control-bar/chapters-plugin.ts
@@ -0,0 +1,64 @@
1import videojs from 'video.js'
2import { ChaptersOptions } from '../../types'
3import { VideoChapter } from '@peertube/peertube-models'
4import { ProgressBarMarkerComponent } from './progress-bar-marker-component'
5
6const Plugin = videojs.getPlugin('plugin')
7
8class ChaptersPlugin extends Plugin {
9 private chapters: VideoChapter[] = []
10 private markers: ProgressBarMarkerComponent[] = []
11
12 constructor (player: videojs.Player, options: videojs.ComponentOptions & ChaptersOptions) {
13 super(player, options)
14
15 this.chapters = options.chapters
16
17 this.player.ready(() => {
18 player.addClass('vjs-chapters')
19
20 this.player.one('durationchange', () => {
21 for (const chapter of this.chapters) {
22 if (chapter.timecode === 0) continue
23
24 const marker = new ProgressBarMarkerComponent(player, { timecode: chapter.timecode })
25
26 this.markers.push(marker)
27 this.getSeekBar().addChild(marker)
28 }
29 })
30 })
31 }
32
33 dispose () {
34 for (const marker of this.markers) {
35 this.getSeekBar().removeChild(marker)
36 }
37 }
38
39 getChapter (timecode: number) {
40 if (this.chapters.length !== 0) {
41 for (let i = this.chapters.length - 1; i >= 0; i--) {
42 const chapter = this.chapters[i]
43
44 if (chapter.timecode <= timecode) {
45 this.player.addClass('has-chapter')
46
47 return chapter.title
48 }
49 }
50 }
51
52 this.player.removeClass('has-chapter')
53
54 return ''
55 }
56
57 private getSeekBar () {
58 return this.player.getDescendant('ControlBar', 'ProgressControl', 'SeekBar')
59 }
60}
61
62videojs.registerPlugin('chapters', ChaptersPlugin)
63
64export { ChaptersPlugin }
diff --git a/client/src/assets/player/shared/control-bar/index.ts b/client/src/assets/player/shared/control-bar/index.ts
index 9307027f6..091e876e2 100644
--- a/client/src/assets/player/shared/control-bar/index.ts
+++ b/client/src/assets/player/shared/control-bar/index.ts
@@ -1,6 +1,8 @@
1export * from './chapters-plugin'
1export * from './next-previous-video-button' 2export * from './next-previous-video-button'
2export * from './p2p-info-button' 3export * from './p2p-info-button'
3export * from './peertube-link-button' 4export * from './peertube-link-button'
4export * from './peertube-live-display' 5export * from './peertube-live-display'
5export * from './storyboard-plugin' 6export * from './storyboard-plugin'
6export * from './theater-button' 7export * from './theater-button'
8export * from './time-tooltip'
diff --git a/client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts b/client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts
new file mode 100644
index 000000000..50965ec71
--- /dev/null
+++ b/client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts
@@ -0,0 +1,24 @@
1import videojs from 'video.js'
2import { ProgressBarMarkerComponentOptions } from '../../types'
3
4const Component = videojs.getComponent('Component')
5
6export class ProgressBarMarkerComponent extends Component {
7 options_: ProgressBarMarkerComponentOptions & videojs.ComponentOptions
8
9 // eslint-disable-next-line @typescript-eslint/no-useless-constructor
10 constructor (player: videojs.Player, options?: ProgressBarMarkerComponentOptions & videojs.ComponentOptions) {
11 super(player, options)
12 }
13
14 createEl () {
15 const left = (this.options_.timecode / this.player().duration()) * 100
16
17 return videojs.dom.createEl('span', {
18 className: 'vjs-marker',
19 style: `left: ${left}%`
20 }) as HTMLButtonElement
21 }
22}
23
24videojs.registerComponent('ProgressBarMarkerComponent', ProgressBarMarkerComponent)
diff --git a/client/src/assets/player/shared/control-bar/storyboard-plugin.ts b/client/src/assets/player/shared/control-bar/storyboard-plugin.ts
index 80c69b5f2..91d7f451e 100644
--- a/client/src/assets/player/shared/control-bar/storyboard-plugin.ts
+++ b/client/src/assets/player/shared/control-bar/storyboard-plugin.ts
@@ -141,7 +141,9 @@ class StoryboardPlugin extends Plugin {
141 const ctop = Math.floor(position / columns) * -scaledHeight 141 const ctop = Math.floor(position / columns) * -scaledHeight
142 142
143 const bgSize = `${imgWidth * scaleFactor}px ${imgHeight * scaleFactor}px` 143 const bgSize = `${imgWidth * scaleFactor}px ${imgHeight * scaleFactor}px`
144 const topOffset = -scaledHeight - 60 144
145 const timeTooltip = this.player.el().querySelector('.vjs-time-tooltip')
146 const topOffset = -scaledHeight + parseInt(getComputedStyle(timeTooltip).top.replace('px', '')) - 20
145 147
146 const previewHalfSize = Math.round(scaledWidth / 2) 148 const previewHalfSize = Math.round(scaledWidth / 2)
147 let left = seekBarRect.width * seekBarX - previewHalfSize 149 let left = seekBarRect.width * seekBarX - previewHalfSize
diff --git a/client/src/assets/player/shared/control-bar/time-tooltip.ts b/client/src/assets/player/shared/control-bar/time-tooltip.ts
new file mode 100644
index 000000000..2ed4f9acd
--- /dev/null
+++ b/client/src/assets/player/shared/control-bar/time-tooltip.ts
@@ -0,0 +1,20 @@
1import { timeToInt } from '@peertube/peertube-core-utils'
2import videojs, { VideoJsPlayer } from 'video.js'
3
4const TimeToolTip = videojs.getComponent('TimeTooltip') as any // FIXME: typings don't have write method
5
6class TimeTooltip extends TimeToolTip {
7
8 write (timecode: string) {
9 const player: VideoJsPlayer = this.player()
10
11 if (player.usingPlugin('chapters')) {
12 const chapterTitle = player.chapters().getChapter(timeToInt(timecode))
13 if (chapterTitle) return super.write(chapterTitle + '\r\n' + timecode)
14 }
15
16 return super.write(timecode)
17 }
18}
19
20videojs.registerComponent('TimeTooltip', TimeTooltip)