More precise chapter marker
This commit is contained in:
parent
acf62ba620
commit
fa7d8c0ed4
|
@ -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 () {
|
||||||
|
|
|
@ -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}%`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue