More precise chapter marker

This commit is contained in:
Chocobozzz 2024-12-27 10:45:53 +01:00
parent acf62ba620
commit fa7d8c0ed4
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
4 changed files with 41 additions and 9 deletions

View File

@ -9,6 +9,8 @@ class ChaptersPlugin extends Plugin {
declare private chapters: VideoChapter[] declare private chapters: VideoChapter[]
declare private markers: ProgressBarMarkerComponent[] declare private markers: ProgressBarMarkerComponent[]
private activeChapter: VideoChapter
constructor (player: videojs.Player, options: videojs.ComponentOptions & ChaptersOptions) { constructor (player: videojs.Player, options: videojs.ComponentOptions & ChaptersOptions) {
super(player, options) super(player, options)
@ -23,6 +25,9 @@ class ChaptersPlugin extends Plugin {
const marker = new ProgressBarMarkerComponent(player, { timecode: chapter.timecode }) const marker = new ProgressBarMarkerComponent(player, { timecode: chapter.timecode })
marker.on('mouseenter', () => this.activeChapter = chapter)
marker.on('mouseleave', () => this.activeChapter = undefined)
this.markers.push(marker) this.markers.push(marker)
this.getSeekBar().addChild(marker) this.getSeekBar().addChild(marker)
} }
@ -38,6 +43,12 @@ class ChaptersPlugin extends Plugin {
} }
getChapter (timecode: number) { getChapter (timecode: number) {
if (this.activeChapter) {
this.player.addClass('has-chapter')
return { title: this.activeChapter.title, fixedTimecode: this.activeChapter.timecode }
}
if (this.chapters.length !== 0) { if (this.chapters.length !== 0) {
for (let i = this.chapters.length - 1; i >= 0; i--) { for (let i = this.chapters.length - 1; i >= 0; i--) {
const chapter = this.chapters[i] const chapter = this.chapters[i]
@ -45,14 +56,14 @@ class ChaptersPlugin extends Plugin {
if (chapter.timecode <= timecode) { if (chapter.timecode <= timecode) {
this.player.addClass('has-chapter') this.player.addClass('has-chapter')
return chapter.title return { title: chapter.title }
} }
} }
} }
this.player.removeClass('has-chapter') this.player.removeClass('has-chapter')
return '' return { title: '' }
} }
private getSeekBar () { private getSeekBar () {

View File

@ -1,9 +1,9 @@
import videojs from 'video.js' import videojs from 'video.js'
import { ProgressBarMarkerComponentOptions } from '../../types' import { ProgressBarMarkerComponentOptions } from '../../types'
const Component = videojs.getComponent('Component') const ClickableComponent = videojs.getComponent('ClickableComponent')
export class ProgressBarMarkerComponent extends Component { export class ProgressBarMarkerComponent extends ClickableComponent {
declare options_: ProgressBarMarkerComponentOptions & videojs.ComponentOptions declare options_: ProgressBarMarkerComponentOptions & videojs.ComponentOptions
// eslint-disable-next-line @typescript-eslint/no-useless-constructor // eslint-disable-next-line @typescript-eslint/no-useless-constructor
@ -20,7 +20,17 @@ export class ProgressBarMarkerComponent extends Component {
} }
this.player().on('durationchange', updateMarker) this.player().on('durationchange', updateMarker)
this.one('dispose', () => this.player().off('durationchange', updateMarker)) const stopPropagation = (event: Event) => event.stopPropagation()
this.on([ 'mousedown', 'touchstart' ], stopPropagation)
this.one('dispose', () => {
if (this.player()) this.player().off('durationchange', updateMarker)
if (this.el()) {
this.off([ 'mousedown', 'touchstart' ], stopPropagation)
}
})
} }
createEl () { createEl () {
@ -32,6 +42,12 @@ export class ProgressBarMarkerComponent extends Component {
}) as HTMLButtonElement }) as HTMLButtonElement
} }
handleClick (event: Event) {
event.stopPropagation()
if (this.player()) this.player().currentTime(this.options_.timecode)
}
private buildLeftStyle () { private buildLeftStyle () {
return `${(this.options_.timecode / this.player().duration()) * 100}%` return `${(this.options_.timecode / this.player().duration()) * 100}%`
} }

View File

@ -5,7 +5,6 @@ const TimeToolTip = videojs.getComponent('TimeTooltip') as any // FIXME: typings
class TimeTooltip extends TimeToolTip { class TimeTooltip extends TimeToolTip {
declare private currentTimecode: string declare private currentTimecode: string
declare private currentChapterTitle: string
write (timecode: string) { write (timecode: string) {
const player: VideoJsPlayer = this.player() const player: VideoJsPlayer = this.player()
@ -14,9 +13,15 @@ class TimeTooltip extends TimeToolTip {
if (timecode === this.currentTimecode) return if (timecode === this.currentTimecode) return
this.currentTimecode = timecode this.currentTimecode = timecode
this.currentChapterTitle = player.chapters().getChapter(timeToInt(this.currentTimecode)) const { title, fixedTimecode } = player.chapters().getChapter(timeToInt(this.currentTimecode))
if (this.currentChapterTitle) return super.write(this.currentChapterTitle + '\r\n' + this.currentTimecode) if (title) {
const timecodeStr = fixedTimecode
? videojs.formatTime(fixedTimecode, this.player()?.duration())
: this.currentTimecode
return super.write(title + '\r\n' + timecodeStr)
}
} }
return super.write(timecode) return super.write(timecode)

View File

@ -31,7 +31,7 @@ $chapter-marker-size: 9px;
cursor: pointer; cursor: pointer;
transition: transform 50ms ease-in-out, border-color 50ms ease-in-out; transition: transform 50ms ease-in-out, border-color 50ms ease-in-out;
border: 2px solid transparent; border: 2px solid transparent;
z-index: 2; // On top of mouse marker z-index: 101;
&:hover { &:hover {
transform: scale(1.5); transform: scale(1.5);