77 type DeferredPromise ,
88} from 'maverick.js/std' ;
99
10- import { TimeRange , type MediaSrc } from '../../core' ;
10+ import { TextTrack , TimeRange , type MediaSrc } from '../../core' ;
1111import { QualitySymbol } from '../../core/quality/symbols' ;
1212import { ListSymbol } from '../../foundation/list/symbols' ;
1313import { RAFLoop } from '../../foundation/observers/raf-loop' ;
@@ -24,7 +24,7 @@ import {
2424 type VimeoEventPayload ,
2525} from './embed/event' ;
2626import type { VimeoMessage } from './embed/message' ;
27- import type { VimeoOEmbedData , VimeoQuality , VimeoVideoInfo } from './embed/misc' ;
27+ import type { VimeoChapter , VimeoQuality , VimeoVideoInfo } from './embed/misc' ;
2828import type { VimeoParams } from './embed/params' ;
2929import { getVimeoVideoInfo , resolveVimeoVideoId } from './utils' ;
3030
@@ -67,6 +67,7 @@ export class VimeoProvider
6767 protected _currentSrc : MediaSrc < string > | null = null ;
6868 protected _currentCue : VTTCue | null = null ;
6969 protected _timeRAF = new RAFLoop ( this . _onAnimationFrame . bind ( this ) ) ;
70+ private _chaptersTrack : TextTrack | null = null ;
7071
7172 protected get _notify ( ) {
7273 return this . _ctx . delegate . _notify ;
@@ -350,8 +351,7 @@ export class VimeoProvider
350351 // We can't control visibility of vimeo captions whilst getting complete info on cues.
351352 // this._remote('getTextTracks');
352353
353- // TODO: need a test video to implement.
354- // this._remote('getChapters');
354+ this . _remote ( 'getChapters' ) ;
355355 } )
356356 . catch ( ( e ) => {
357357 if ( videoId !== this . _videoId ( ) ) return ;
@@ -385,6 +385,7 @@ export class VimeoProvider
385385 // this._onTextTracksChange(data as VimeoTextTrack[], trigger);
386386 // break;
387387 case 'getChapters' :
388+ this . _onChaptersChange ( data as VimeoChapter [ ] ) ;
388389 break ;
389390 case 'getQualities' :
390391 this . _onQualitiesChange ( data as VimeoQuality [ ] , trigger ) ;
@@ -482,6 +483,36 @@ export class VimeoProvider
482483 // track?.addCue(this._currentCue, trigger);
483484 // }
484485
486+ protected _onChaptersChange ( chapters : VimeoChapter [ ] ) {
487+ this . _removeChapters ( ) ;
488+
489+ if ( ! chapters . length ) return ;
490+
491+ const track = new TextTrack ( {
492+ kind : 'chapters' ,
493+ default : true ,
494+ } ) ,
495+ { duration } = this . _ctx . $state ;
496+
497+ for ( let i = 0 ; i < chapters . length ; i ++ ) {
498+ const chapter = chapters [ i ] ,
499+ nextChapter = chapters [ i + 1 ] ;
500+
501+ track . addCue (
502+ new window . VTTCue ( chapter . startTime , nextChapter ?. startTime ?? duration ( ) , chapter . title ) ,
503+ ) ;
504+ }
505+
506+ this . _chaptersTrack = track ;
507+ this . _ctx . textTracks . add ( track ) ;
508+ }
509+
510+ protected _removeChapters ( ) {
511+ if ( ! this . _chaptersTrack ) return ;
512+ this . _ctx . textTracks . remove ( this . _chaptersTrack ) ;
513+ this . _chaptersTrack = null ;
514+ }
515+
485516 protected _onQualitiesChange ( qualities : VimeoQuality [ ] , trigger : Event ) {
486517 this . _ctx . qualities [ QualitySymbol . _enableAuto ] = qualities . some ( ( q ) => q . id === 'auto' )
487518 ? ( ) => {
@@ -646,5 +677,6 @@ export class VimeoProvider
646677 this . _videoInfoPromise = null ;
647678 this . _currentCue = null ;
648679 this . _pro . set ( false ) ;
680+ this . _removeChapters ( ) ;
649681 }
650682}
0 commit comments