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 markers: ProgressBarMarkerComponent[]
private activeChapter: VideoChapter
constructor (player: videojs.Player, options: videojs.ComponentOptions & ChaptersOptions) {
super(player, options)
@ -23,6 +25,9 @@ class ChaptersPlugin extends Plugin {
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.getSeekBar().addChild(marker)
}
@ -38,6 +43,12 @@ class ChaptersPlugin extends Plugin {
}
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) {
for (let i = this.chapters.length - 1; i >= 0; i--) {
const chapter = this.chapters[i]
@ -45,14 +56,14 @@ class ChaptersPlugin extends Plugin {
if (chapter.timecode <= timecode) {
this.player.addClass('has-chapter')
return chapter.title
return { title: chapter.title }
}
}
}
this.player.removeClass('has-chapter')
return ''
return { title: '' }
}
private getSeekBar () {

View File

@ -1,9 +1,9 @@
import videojs from 'video.js'
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
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
@ -20,7 +20,17 @@ export class ProgressBarMarkerComponent extends Component {
}
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 () {
@ -32,6 +42,12 @@ export class ProgressBarMarkerComponent extends Component {
}) as HTMLButtonElement
}
handleClick (event: Event) {
event.stopPropagation()
if (this.player()) this.player().currentTime(this.options_.timecode)
}
private buildLeftStyle () {
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 {
declare private currentTimecode: string
declare private currentChapterTitle: string
write (timecode: string) {
const player: VideoJsPlayer = this.player()
@ -14,9 +13,15 @@ class TimeTooltip extends TimeToolTip {
if (timecode === this.currentTimecode) return
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)

View File

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