1- import { DefaultPlayerEvents } from '../../enums/DefaultPlayerEvents.mjs' ;
2- import { PlayerModes } from '../../enums/PlayerModes.mjs' ;
3- import { RequestUtils } from '../../utils/RequestUtils.mjs' ;
4- import DashPlayer from '../dash/DashPlayer.mjs' ;
5- import { Vimeo2Dash } from './Vimeo2Dash.mjs' ;
1+ import { DefaultPlayerEvents } from '../../enums/DefaultPlayerEvents.mjs' ;
2+ import { PlayerModes } from '../../enums/PlayerModes.mjs' ;
3+ import { RequestUtils } from '../../utils/RequestUtils.mjs' ;
4+ import HLSPlayer from "../hls/HLSPlayer.mjs" ;
65
7- export default class VMPlayer extends DashPlayer {
6+ export default class VMPlayer extends HLSPlayer {
87 constructor ( client , options ) {
98 super ( client , options ) ;
109 }
1110
1211 async setSource ( source ) {
1312 try {
14- let manifest ;
15- try {
16- const hc = [ ] ;
13+ const isEmbed = ! source . url . includes ( 'config?' ) ;
14+ const hc = [ ] ;
15+ if ( Array . isArray ( source . headers ) ) {
16+ source . headers . forEach ( ( h ) => {
17+ hc . push ( {
18+ operation : 'set' ,
19+ header : h . name ,
20+ value : h . value ,
21+ } ) ;
22+ } ) ;
23+ } else {
1724 for ( const key in source . headers ) {
1825 if ( Object . hasOwn ( source . headers , key ) ) {
1926 hc . push ( {
@@ -23,27 +30,36 @@ export default class VMPlayer extends DashPlayer {
2330 } ) ;
2431 }
2532 }
33+ }
2634
27- const xhr = await RequestUtils . request ( {
28- url : source . url ,
29- header_commands : hc ,
30- responseType : 'json' ,
31- } ) ;
35+ const xhr = await RequestUtils . request ( {
36+ url : source . url ,
37+ header_commands : hc ,
38+ responseType : isEmbed ? 'text' : 'json' ,
39+ } ) ;
3240
33- const convert = new Vimeo2Dash ( ) ;
34- manifest = convert . playlistToDash ( source . url , xhr . response ) ;
35- } catch ( e ) {
36- throw e ;
41+ const config = xhr . response ;
42+ const hls = ! isEmbed ? config ?. request ?. files ?. hls : this . extractVimeoHlsUrlFromIframePlayer ( config ) ;
43+ if ( ! hls || ! hls . cdns ) {
44+ throw new Error ( 'Vimeo HLS data not found' ) ;
3745 }
46+ const defaultCdn =
47+ hls . default_cdn && hls . cdns [ hls . default_cdn ]
48+ ? hls . default_cdn
49+ : Object . keys ( hls . cdns ) [ 0 ] ;
50+
51+ let hlsUrl = hls . cdns [ defaultCdn ] . url ;
52+
53+ if ( ! hlsUrl ) {
54+ throw new Error ( 'Vimeo HLS URL missing' ) ;
55+ }
56+
57+ hlsUrl = hlsUrl . replace ( / \\ u 0 0 2 6 / g, '&' ) ;
3858
39- this . oldSource = source ;
40- const blob = new Blob ( [ manifest ] , {
41- type : 'application/dash+xml' ,
42- } ) ;
43- const uri = URL . createObjectURL ( blob ) ;
4459 this . source = source . copy ( ) ;
45- this . source . url = uri ;
46- this . source . mode = PlayerModes . ACCELERATED_DASH ;
60+ this . source . url = hlsUrl ;
61+ this . source . mode = PlayerModes . ACCELERATED_HLS ;
62+
4763 } catch ( e ) {
4864 console . error ( e ) ;
4965 this . emit ( DefaultPlayerEvents . ERROR , e ) ;
@@ -63,4 +79,57 @@ export default class VMPlayer extends DashPlayer {
6379 getSource ( ) {
6480 return this . source ;
6581 }
82+
83+ extractVimeoHlsUrlFromIframePlayer ( html ) {
84+
85+ const config = this . extractJsonConfig ( html , 'window.playerConfig =' ) ;
86+
87+ if ( ! config ) {
88+ throw new Error ( 'Vimeo iframe: playerConfig not found' ) ;
89+ }
90+
91+ return config ?. request ?. files ?. hls ;
92+ }
93+
94+ extractJsonConfig ( html , prefix ) {
95+ const startIndex = html . indexOf ( prefix ) ;
96+ if ( startIndex === - 1 ) return null ;
97+
98+ // Move past the prefix
99+ let i = startIndex + prefix . length ;
100+
101+ // Find the first '{'
102+ while ( i < html . length && html [ i ] !== '{' ) {
103+ i ++ ;
104+ }
105+
106+ if ( i >= html . length ) return null ;
107+
108+ const jsonStart = i ;
109+ let braceCount = 0 ;
110+ let foundStart = false ;
111+
112+ // Iterate to find the matching closing brace
113+ for ( ; i < html . length ; i ++ ) {
114+ if ( html [ i ] === '{' ) {
115+ braceCount ++ ;
116+ foundStart = true ;
117+ } else if ( html [ i ] === '}' ) {
118+ braceCount -- ;
119+ }
120+
121+ if ( foundStart && braceCount === 0 ) {
122+ // We found the end of the object
123+ const jsonString = html . substring ( jsonStart , i + 1 ) ;
124+ try {
125+ return JSON . parse ( jsonString ) ;
126+ } catch ( e ) {
127+ return null ;
128+ }
129+ }
130+ }
131+
132+ return null ;
133+ }
134+
66135}
0 commit comments