@oddin-gg/havik-player 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/havik-player.global.js +1 -1
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/embed/index.html +1 -1
- package/package.json +1 -1
|
@@ -143,5 +143,5 @@ Schedule: ${a.map(e=>_l(e))} pos: ${this.timelinePos}`),s.length&&this.log(`Remo
|
|
|
143
143
|
.havik-menu__item:hover{background:var(--havik-surface-muted,#2a2c36)}
|
|
144
144
|
.havik-menu__item[aria-checked="true"]{color:var(--havik-accent,#E1B600);font-weight:600}
|
|
145
145
|
.havik-menu__item[aria-checked="true"]::after{content:'✓'}
|
|
146
|
-
`;function Ud(e=document){if(e.getElementById(Vd))return;let t=e.createElement(`style`);t.id=Vd,t.textContent=Hd,e.head.appendChild(t)}var Wd={play:`<path d="M8 5v14l11-7z"/>`,pause:`<path d="M6 5h4v14H6zM14 5h4v14h-4z"/>`,volumeHigh:`<path d="M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z"/>`,volumeMute:`<path d="M3 10v4h4l5 5V5L7 10H3zm16.5 2 2.5-2.5-1.4-1.4L18 10.6 15.4 8 14 9.4l2.6 2.6L14 14.6l1.4 1.4 2.6-2.6 2.6 2.6 1.4-1.4z"/>`,cc:`<path d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM10 11H8.5v-.5h-2v3h2V13H10v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H17v1a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1z"/>`,settings:`<path d="m19.4 13 .1-1-.1-1 2-1.6-2-3.4-2.4 1a7 7 0 0 0-1.7-1l-.4-2.5H9.1L8.7 6a7 7 0 0 0-1.7 1l-2.4-1-2 3.4L2.6 11l-.1 1 .1 1-2 1.6 2 3.4 2.4-1c.5.4 1 .7 1.7 1l.4 2.5h5.8l.4-2.5c.6-.3 1.2-.6 1.7-1l2.4 1 2-3.4-2-1.6zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z"/>`,pip:`<path d="M19 7h-8v6h8V7zm4 12V5a2 2 0 0 0-2-2H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2zm-2 .02H3V4.98h18v14.04z"/>`,fullscreen:`<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>`,fullscreenExit:`<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>`,liveDot:`<circle cx="12" cy="12" r="6"/>`,retry:`<path d="M17.65 6.35A8 8 0 1 0 19.73 13h-2.08A6 6 0 1 1 12 6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>`};function Gd(e){return`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Wd[e]}</svg>`}var Kd=3e3,qd=new Set([`GONE`,`NOT_FOUND`,`INVALID_URN`,`UNAUTHORIZED`]);function Jd(e){return new Yd(e)}var Yd=class{constructor(e){i(this,`root`,void 0),i(this,`video`,void 0),i(this,`player`,void 0),i(this,`doc`,void 0),i(this,`autoHideMs`,void 0),i(this,`overlay`,void 0),i(this,`center`,void 0),i(this,`spinner`,void 0),i(this,`bar`,void 0),i(this,`gradient`,void 0),i(this,`seek`,void 0),i(this,`seekBuffered`,void 0),i(this,`seekPlayed`,void 0),i(this,`seekThumb`,void 0),i(this,`playBtn`,void 0),i(this,`muteBtn`,void 0),i(this,`volSlider`,void 0),i(this,`live`,void 0),i(this,`liveGo`,void 0),i(this,`time`,void 0),i(this,`ccBtn`,void 0),i(this,`audioBtn`,void 0),i(this,`qualityBtn`,void 0),i(this,`pipBtn`,void 0),i(this,`fsBtn`,void 0),i(this,`menu`,void 0),i(this,`statusBox`,null),i(this,`statusKind`,null),i(this,`hasPlayed`,!1),i(this,`lastError`,null),i(this,`logoUrl`,void 0),i(this,`statusOverlays`,void 0),i(this,`endedMessage`,void 0),i(this,`errorMessage`,void 0),i(this,`hideTimer`,void 0),i(this,`openMenu`,null),i(this,`scrubbing`,!1),i(this,`offFns`,[]),this.root=e.root,this.video=e.video,this.player=e.player,this.doc=e.root.ownerDocument??document,this.autoHideMs=e.autoHideMs??Kd,this.logoUrl=e.logoUrl,this.statusOverlays=e.statusOverlays!==!1,this.endedMessage=e.endedMessage??`This stream has ended`,this.errorMessage=e.errorMessage,Ud(this.doc),this.root.classList.add(`havik-player`),this.root.hasAttribute(`tabindex`)||(this.root.tabIndex=0),this.root.setAttribute(`role`,`region`),this.root.setAttribute(`aria-label`,`Video player`);let t=(e,t,n)=>{let r=this.doc.createElement(e);if(r.className=t,n)for(let[e,t]of Object.entries(n))r.setAttribute(e,t);return r},n=(e,n,r)=>{let i=t(`button`,e,{type:`button`,"aria-label":r,title:r});return i.innerHTML=Gd(n),i};this.overlay=t(`div`,`havik-overlay`),this.center=t(`button`,`havik-center`,{type:`button`,"aria-label":`Play`}),this.center.innerHTML=Gd(`play`),this.spinner=t(`div`,`havik-spinner`),this.spinner.style.display=`none`,this.overlay.append(this.center,this.spinner),this.gradient=t(`div`,`havik-gradient`),this.bar=t(`div`,`havik-bar`),this.seek=t(`div`,`havik-seek`,{role:`slider`,"aria-label":`Seek`,"aria-valuemin":`0`,"aria-valuemax":`100`,tabindex:`0`});let r=t(`div`,`havik-seek__track`);this.seekBuffered=t(`div`,`havik-seek__buffered`),this.seekPlayed=t(`div`,`havik-seek__played`),this.seekThumb=t(`div`,`havik-seek__thumb`),r.append(this.seekBuffered,this.seekPlayed,this.seekThumb),this.seek.append(r);let a=t(`div`,`havik-controls`);this.playBtn=n(`havik-btn`,`play`,`Play`),this.muteBtn=n(`havik-btn`,`volumeHigh`,`Mute`),this.volSlider=t(`input`,`havik-vol__slider`,{type:`range`,min:`0`,max:`1`,step:`0.05`,"aria-label":`Volume`});let o=t(`div`,`havik-vol`);o.append(this.muteBtn,this.volSlider),this.live=t(`div`,`havik-live`),this.live.innerHTML=Gd(`liveDot`);let s=this.doc.createElement(`span`);s.textContent=`LIVE`,this.liveGo=t(`button`,`havik-live__go`,{type:`button`}),this.liveGo.textContent=`Go live`,this.live.append(s,this.liveGo),this.time=t(`div`,`havik-time`),this.time.textContent=`0:00`,this.time.style.display=`none`;let c=t(`div`,`havik-spacer`);if(this.ccBtn=n(`havik-btn`,`cc`,`Subtitles`),this.audioBtn=n(`havik-btn`,`settings`,`Audio track`),this.qualityBtn=n(`havik-btn`,`settings`,`Quality`),this.pipBtn=n(`havik-btn`,`pip`,`Picture in picture`),this.fsBtn=n(`havik-btn`,`fullscreen`,`Fullscreen`),this.ccBtn.style.display=`none`,this.audioBtn.style.display=`none`,this.qualityBtn.style.display=`none`,this.pipSupported()||(this.pipBtn.style.display=`none`),a.append(this.playBtn,o,this.live,this.time,c,this.ccBtn,this.audioBtn,this.qualityBtn,this.pipBtn,this.fsBtn),this.bar.append(this.seek,a),this.menu=t(`div`,`havik-menu`,{role:`menu`}),this.menu.hidden=!0,this.root.append(this.gradient,this.overlay,this.bar,this.menu),e.logoUrl){let n=t(`div`,`havik-watermark`);n.style.backgroundImage=`url("${e.logoUrl}")`,this.root.append(n)}this.wire(),this.syncPlayPause(),this.syncVolume(),this.scheduleHide()}on(e,t,n,r){e.addEventListener(t,n,r),this.offFns.push(()=>e.removeEventListener(t,n,r))}wire(){let e=this.video;this.on(this.playBtn,`click`,()=>this.togglePlay()),this.on(this.center,`click`,()=>this.togglePlay()),this.on(this.overlay,`click`,e=>{e.target===this.overlay&&this.togglePlay()}),this.on(this.muteBtn,`click`,()=>this.player.setMuted(!e.muted)),this.on(this.volSlider,`input`,()=>{let t=Number(this.volSlider.value);this.player.setVolume(t),t>0&&e.muted&&this.player.setMuted(!1)}),this.on(this.liveGo,`click`,()=>this.player.seekToLive()),this.on(this.pipBtn,`click`,()=>void this.togglePip()),this.on(this.fsBtn,`click`,()=>void this.toggleFullscreen()),this.on(this.ccBtn,`click`,()=>this.toggleMenu(`cc`)),this.on(this.audioBtn,`click`,()=>this.toggleMenu(`audio`)),this.on(this.qualityBtn,`click`,()=>this.toggleMenu(`quality`)),this.on(this.seek,`pointerdown`,e=>this.onSeekDown(e)),this.on(this.seek,`keydown`,e=>this.onSeekKey(e)),this.on(e,`play`,()=>this.syncPlayPause()),this.on(e,`pause`,()=>this.syncPlayPause()),this.on(e,`volumechange`,()=>this.syncVolume()),this.on(e,`timeupdate`,()=>this.syncProgress()),this.on(e,`progress`,()=>this.syncProgress()),this.on(e,`durationchange`,()=>this.syncProgress()),this.offFns.push(this.player.on(`statechange`,()=>this.syncState())),this.offFns.push(this.player.on(`ready`,()=>this.refreshTracks())),this.offFns.push(this.player.on(`qualitychange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`audiotrackchange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`texttrackchange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`pipchange`,e=>this.syncPip(e))),this.offFns.push(this.player.on(`stats`,()=>this.syncLive())),this.offFns.push(this.player.on(`error`,e=>{this.lastError=e,this.statusKind=null,this.syncState()})),this.on(this.root,`pointermove`,()=>this.poke()),this.on(this.root,`pointerleave`,()=>this.scheduleHide(0)),this.on(this.root,`focusin`,()=>this.poke()),this.on(this.root,`keydown`,e=>this.onKey(e)),this.on(this.doc,`pointerdown`,e=>this.onDocPointer(e),{capture:!0}),this.on(this.doc,`fullscreenchange`,()=>this.syncFullscreen()),this.syncState()}togglePlay(){this.video.paused||this.video.ended?this.player.play():this.player.pause()}syncPlayPause(){let e=!this.video.paused&&!this.video.ended;this.setIcon(this.playBtn,e?`pause`:`play`),this.playBtn.setAttribute(`aria-label`,e?`Pause`:`Play`),this.setIcon(this.center,e?`pause`:`play`),this.center.classList.toggle(`havik-gone`,e||!!this.statusBox),e?this.scheduleHide():this.show()}syncState(){let e=this.player.state;(e===`playing`||e===`buffering`)&&(this.hasPlayed=!0),this.syncStatus(e);let t=e===`loading`||e===`buffering`;this.spinner.style.display=t&&!this.statusBox?``:`none`,(t||this.statusBox)&&this.center.classList.add(`havik-gone`),this.syncLive()}syncStatus(e){let t=null;this.statusOverlays&&(e===`ended`?t=`ended`:e===`error`?t=`error`:e===`waiting`?t=`waiting`:!this.hasPlayed&&(e===`idle`||e===`paused`)&&(t=`preplay`)),this.renderStatus(t)}renderStatus(e){if(e===this.statusKind||(this.statusKind=e,this.statusBox?.remove(),this.statusBox=null,!e))return;let t=this.doc.createElement(`div`);if(t.className=`havik-status havik-status--${e}`,this.logoUrl){let e=this.doc.createElement(`div`);e.className=`havik-status__logo`,t.append(e)}if(e===`preplay`){let e=this.doc.createElement(`button`);e.type=`button`,e.className=`havik-status__btn havik-status__btn--play`,e.setAttribute(`aria-label`,`Play`),e.innerHTML=Gd(`play`),e.addEventListener(`click`,()=>void this.player.play()),t.append(e)}else{let n=this.doc.createElement(`div`);if(n.className=`havik-status__msg`,n.textContent=e===`ended`?this.endedMessage:e===`waiting`?`Starting soon…`:this.errorMessage??this.lastError?.message??`Playback unavailable`,t.append(n),e===`error`&&this.lastError&&!qd.has(this.lastError.code)){let e=this.doc.createElement(`button`);e.type=`button`,e.className=`havik-status__btn`,e.innerHTML=`${Gd(`retry`)}<span>Retry</span>`,e.addEventListener(`click`,()=>void this.player.retry()),t.append(e)}}this.root.append(t),this.statusBox=t,this.show()}syncVolume(){let e=this.video,t=e.muted||e.volume===0;this.setIcon(this.muteBtn,t?`volumeMute`:`volumeHigh`),this.muteBtn.setAttribute(`aria-label`,t?`Unmute`:`Mute`),this.volSlider.value=String(t?0:e.volume)}seekableRange(){let e=this.video,t,n;if(e.seekable&&e.seekable.length>0)t=e.seekable.start(0),n=e.seekable.end(e.seekable.length-1);else if(Number.isFinite(e.duration)&&e.duration>0)t=0,n=e.duration;else return null;let r=this.player.getStats();return r.isLive!==!1&&r.targetLatencySeconds&&r.targetLatencySeconds>0&&(n=Math.max(t,n-r.targetLatencySeconds)),n>t?{start:t,end:n}:null}syncProgress(){if(this.scrubbing)return;let e=this.seekableRange();if(!e){this.seekPlayed.style.width=`100%`;return}let t=e.end-e.start,n=Math.min(1,Math.max(0,(this.video.currentTime-e.start)/t));this.seekPlayed.style.width=`${(n*100).toFixed(2)}%`,this.seekThumb.style.left=`${(n*100).toFixed(2)}%`,this.seek.setAttribute(`aria-valuenow`,String(Math.round(n*100)));let r=this.video.buffered;if(r&&r.length>0){let n=r.end(r.length-1),i=Math.min(1,Math.max(0,(n-e.start)/t));this.seekBuffered.style.width=`${(i*100).toFixed(2)}%`}!this.player.getStats().isLive&&Number.isFinite(this.video.duration)&&(this.time.textContent=`${Xd(this.video.currentTime)} / ${Xd(this.video.duration)}`)}syncLive(){let e=this.player.getStats(),t=e.isLive!==!1;this.live.style.display=t?``:`none`,this.time.style.display=t?`none`:``,this.live.classList.toggle(`is-live`,e.atLiveEdge!==!1&&t)}onSeekDown(e){let t=this.seekableRange();if(!t)return;e.preventDefault(),this.scrubbing=!0;let n=e=>this.seekToPointer(e,t),r=()=>{this.scrubbing=!1,this.doc.removeEventListener(`pointermove`,n),this.doc.removeEventListener(`pointerup`,r)};this.doc.addEventListener(`pointermove`,n),this.doc.addEventListener(`pointerup`,r),this.seekToPointer(e,t)}seekToPointer(e,t){let n=this.seek.getBoundingClientRect(),r=n.width>0?Math.min(1,Math.max(0,(e.clientX-n.left)/n.width)):0;this.seekPlayed.style.width=`${(r*100).toFixed(2)}%`,this.seekThumb.style.left=`${(r*100).toFixed(2)}%`,this.video.currentTime=t.start+r*(t.end-t.start)}onSeekKey(e){e.key===`ArrowLeft`?(this.nudge(-5),e.preventDefault()):e.key===`ArrowRight`&&(this.nudge(5),e.preventDefault())}nudge(e){let t=this.seekableRange();t&&(this.video.currentTime=Math.min(t.end,Math.max(t.start,this.video.currentTime+e)))}toggleMenu(e){if(this.openMenu===e){this.closeMenu();return}this.openMenu=e,this.renderMenu(e),this.menu.hidden=!1,this.show()}closeMenu(){this.openMenu=null,this.menu.hidden=!0,this.menu.replaceChildren()}renderMenu(e){e===`quality`?this.renderQualityMenu():e===`audio`?this.renderAudioMenu():this.renderCcMenu()}menuItem(e,t,n){let r=this.doc.createElement(`button`);r.type=`button`,r.className=`havik-menu__item`,r.setAttribute(`role`,`menuitemradio`),r.setAttribute(`aria-checked`,t?`true`:`false`);let i=this.doc.createElement(`span`);return i.textContent=e,r.append(i),r.addEventListener(`click`,()=>{n(),this.closeMenu()}),r}renderQualityMenu(){let e=this.player.getQualityLevels(),t=this.player.getCurrentQuality(),n=this.doc.createElement(`div`);n.className=`havik-menu__title`,n.textContent=`Quality`,this.menu.replaceChildren(n,this.menuItem(`Auto`,t===-1,()=>this.player.setQuality(`auto`)));for(let n of e)this.menu.append(this.menuItem(Zd(n),t===n.index,()=>this.player.setQuality(n.index)))}renderAudioMenu(){let e=this.player.getAudioTracks(),t=this.doc.createElement(`div`);t.className=`havik-menu__title`,t.textContent=`Audio`,this.menu.replaceChildren(t);for(let t of e)this.menu.append(this.menuItem(Qd(t),t.default,()=>this.player.setAudioTrack(t.id)))}renderCcMenu(){let e=this.player.getTextTracks(),t=this.doc.createElement(`div`);t.className=`havik-menu__title`,t.textContent=`Subtitles`,this.menu.replaceChildren(t,this.menuItem(`Off`,!1,()=>this.player.setTextTrack(-1)));for(let t of e)this.menu.append(this.menuItem($d(t),!1,()=>this.player.setTextTrack(t.id)))}onTracksChanged(){this.openMenu&&this.renderMenu(this.openMenu)}refreshTracks(){let e=this.player.getQualityLevels(),t=this.player.getAudioTracks(),n=this.player.getTextTracks();this.qualityBtn.style.display=e.length>1?``:`none`,this.audioBtn.style.display=t.length>1?``:`none`,this.ccBtn.style.display=n.length>0?``:`none`,this.onTracksChanged()}pipSupported(){return`pictureInPictureEnabled`in this.doc&&typeof this.video.requestPictureInPicture==`function`}async togglePip(){this.doc.pictureInPictureElement===this.video?await this.player.exitPictureInPicture():await this.player.enterPictureInPicture()}syncPip(e){this.pipBtn.setAttribute(`aria-pressed`,e?`true`:`false`)}async toggleFullscreen(){let e=this.root,t=this.doc;try{t.fullscreenElement?await t.exitFullscreen?.():await e.requestFullscreen?.()}catch{}}syncFullscreen(){let e=this.doc.fullscreenElement===this.root;this.setIcon(this.fsBtn,e?`fullscreenExit`:`fullscreen`),this.fsBtn.setAttribute(`aria-label`,e?`Exit fullscreen`:`Fullscreen`)}poke(){this.show(),this.scheduleHide()}show(){this.root.classList.remove(`havik-hide`)}scheduleHide(e=this.autoHideMs){this.hideTimer&&clearTimeout(this.hideTimer),this.hideTimer=setTimeout(()=>{!this.video.paused&&!this.video.ended&&!this.openMenu&&!this.statusBox&&this.root.classList.add(`havik-hide`)},e)}onDocPointer(e){this.openMenu&&!this.menu.contains(e.target)&&([this.qualityBtn,this.audioBtn,this.ccBtn].some(t=>t.contains(e.target))||this.closeMenu())}onKey(e){let t=e.target;if(!(t&&t!==this.root&&t!==this.seek&&t.tagName===`INPUT`)){switch(e.key){case` `:case`k`:this.togglePlay();break;case`m`:this.player.setMuted(!this.video.muted);break;case`f`:this.toggleFullscreen();break;case`c`:this.ccBtn.style.display!==`none`&&this.toggleMenu(`cc`);break;case`l`:this.player.seekToLive();break;case`ArrowUp`:this.player.setVolume(Math.min(1,this.video.volume+.1));break;case`ArrowDown`:this.player.setVolume(Math.max(0,this.video.volume-.1));break;case`ArrowLeft`:this.nudge(-5);break;case`ArrowRight`:this.nudge(5);break;default:return}this.poke(),e.preventDefault()}}setIcon(e,t){e.innerHTML=Gd(t)}destroy(){this.hideTimer&&clearTimeout(this.hideTimer);for(let e of this.offFns)try{e()}catch{}this.offFns.length=0,this.closeMenu(),this.statusBox?.remove();for(let e of[this.overlay,this.gradient,this.bar,this.menu])e.remove();this.root.classList.remove(`havik-player`,`havik-hide`)}};function Xd(e){(!Number.isFinite(e)||e<0)&&(e=0);let t=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),i=r>0?String(n).padStart(2,`0`):String(n),a=String(t).padStart(2,`0`);return r>0?`${r}:${i}:${a}`:`${i}:${a}`}function Zd(e){return e.height?`${e.height}p`:`${Math.round(e.bitrate/1e3)} kbps`}function Qd(e){return e.name||e.lang||`Track ${e.id}`}function $d(e){return e.name||e.lang||`Track ${e.id}`}var ef=6e3,tf=45e3,nf=2e3,rf=3,af=2e3,of=480*1e3;async function sf(e){if(!e.video||typeof e.video.play!=`function`)throw new a(`INTERNAL`,0,`createPlayer: opts.video must be an HTMLVideoElement`);if(!e.baseUrl)throw new a(`INTERNAL`,0,`createPlayer: baseUrl is required`);if(!e.matchUrn)throw new a(`INVALID_URN`,0,`createPlayer: matchUrn is required`);if(!e.credential)throw new a(`INTERNAL`,0,`createPlayer: credential is required`);let t=new cf(e);return await t.start(),t}var cf=class{constructor(e){i(this,`opts`,void 0),i(this,`abort`,new AbortController),i(this,`listeners`,{}),i(this,`engine`,null),i(this,`controlBar`,null),i(this,`container`,null),i(this,`detachMedia`,void 0),i(this,`detachPip`,void 0),i(this,`statsTimer`,void 0),i(this,`refreshTimer`,void 0),i(this,`_state`,`idle`),i(this,`_descriptor`,null),i(this,`destroyed`,!1),i(this,`loadGen`,0),i(this,`liveStateSub`,null),i(this,`endedHandled`,!1),i(this,`armingSub`,null),i(this,`armSseTimer`,null),this.opts=e}get state(){return this._state}get descriptor(){return this._descriptor}async start(){this.opts.muted&&(this.opts.video.muted=!0),this.opts.poster&&(this.opts.video.poster=this.opts.poster),this.mountControls(),this.attachPipListeners(),this.setState(`loading`);let e=++this.loadGen,t=this.resolveOptions();try{let n=await D(t);await this.onResolved(n,e)}catch(t){if(this.opts.waitForLive&&t instanceof a&&c(t.code)){this.setState(`waiting`),this.beginArming(e);return}throw t}}resolveOptions(){return{baseUrl:this.opts.baseUrl,matchUrn:this.opts.matchUrn,credential:this.opts.credential,signal:this.abort.signal}}beginArming(e){let t=this.opts.liveStateEvents===!1?void 0:this.opts.eventsBaseUrl??oe(this.opts.baseUrl);t?this.armWithSse(e,t):this.beginArmingByPolling(e)}beginArmingByPolling(e,t){O({...this.resolveOptions(),signal:t??this.abort.signal,waitForLive:this.buildWaitConfig()}).then(t=>this.onResolved(t,e)).catch(n=>{this.destroyed||this.abort.signal.aborted||t?.aborted||e!==this.loadGen||this.fail(n)})}armWithSse(e,t){let n=!1,r=!1,i=new AbortController;this.abort.signal.addEventListener(`abort`,()=>i.abort(),{once:!0}),this.setState(`waiting`);let o=()=>this.destroyed||this.abort.signal.aborted||e!==this.loadGen,s=async t=>{n||o()||(n=!0,this.closeArming(),i.abort(),await this.onResolved(t,e))},l=()=>{n||r||o()||(r=!0,this.beginArmingByPolling(e,i.signal))},u=()=>{n||o()||D(this.resolveOptions()).then(e=>s(e)).catch(e=>{n||o()||e instanceof a&&c(e.code)||(n=!0,this.closeArming(),i.abort(),this.fail(e instanceof a?e:new a(`INTERNAL`,0,String(e))))})},d=e=>{this.armSseTimer&&clearTimeout(this.armSseTimer),this.armSseTimer=setTimeout(()=>{!n&&!o()&&l()},e)};d(ef),this.armingSub=ae({eventsBaseUrl:t,matchUrn:this.opts.matchUrn,credential:this.opts.credential,onAlive:()=>d(tf),onState:e=>{n||o()||(e.state===`live`||e.state===`gone`)&&setTimeout(u,Math.random()*nf)},onError:()=>l()})}closeArming(){this.armSseTimer&&=(clearTimeout(this.armSseTimer),null),this.armingSub?.close(),this.armingSub=null}buildWaitConfig(){let e=this.opts.waitForLive&&this.opts.waitForLive!==!0?this.opts.waitForLive:{};return{...e,onState:t=>{this.setState(`waiting`),this.emit(`waiting`,t),e.onState?.(t)}}}async onResolved(e,t){if(this.destroyed||t!==this.loadGen)return;this._descriptor=e,this.endedHandled=!1;let n=await l(this.opts.credential);if(this.destroyed||t!==this.loadGen)return;this.setState(`loading`);let r=this.createEngine(e,n),i=xd(this.opts.video,e=>this.setState(e));if(await r.load(),this.destroyed||t!==this.loadGen){i(),r.destroy();return}this.engine=r,this.detachMedia=i,this.opts.maxBitrate!=null&&r.setMaxBitrate(this.opts.maxBitrate),this.startStats(),this.scheduleLicenseRefresh(),this.startLiveState(t)}createEngine(e,t){let n={...this.opts.hlsConfig};this.opts.startLevel!=null&&(n.startLevel=this.opts.startLevel),this.opts.liveLatencyTarget!=null&&(n.liveSyncDuration=this.opts.liveLatencyTarget);let r={video:this.opts.video,descriptor:e,credential:t,deviceId:le(),userId:this.opts.userId,lowLatency:this.opts.lowLatency===void 0||this.opts.lowLatency===`auto`||this.opts.lowLatency,snapToLiveOnRefocus:this.opts.snapToLiveOnRefocus,debug:this.opts.debug,hlsConfig:n,emit:e=>this.onEngineEvent(e)},i=this.opts.engine??`auto`;if(i===`native`)return new Ld(r);if(i===`hls`||Sd())return new Fd(r);if(Id(this.opts.video))return new Ld(r);throw new a(`INTERNAL`,0,`no supported HLS playback engine in this browser`)}onEngineEvent(e){if(!this.destroyed)switch(e.type){case`ready`:this.emit(`ready`),this.opts.autoplay!==!1&&this.play();break;case`lowLatencyDetected`:this._descriptor&&(this._descriptor.isLowLatency=e.value);break;case`qualitychange`:this.emit(`qualitychange`,e.index);break;case`audiotrackchange`:this.emit(`audiotrackchange`,e.id);break;case`texttrackchange`:this.emit(`texttrackchange`,e.id);break;case`ended`:this.onStreamEnded();break;case`error`:e.fatal?this.fail(e.error):this.emit(`warning`,e.error);break}}startLiveState(e){if(this.opts.liveStateEvents===!1)return;let t=this.opts.eventsBaseUrl??oe(this.opts.baseUrl);if(!t)return;this.closeLiveState();let n=0,r=!1;this.liveStateSub=ae({eventsBaseUrl:t,matchUrn:this.opts.matchUrn,credential:this.opts.credential,onState:t=>{this.destroyed||e!==this.loadGen||(t.state===`ended`||t.state===`gone`)&&this.onStreamEnded()},onAlive:()=>{n=0,r=!1},onError:()=>{this.destroyed||e!==this.loadGen||r||(n+=1,n>=rf&&(r=!0,this.emit(`warning`,new a(`NETWORK`,0,`live-state events unreachable at ${t} after ${n} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))))}})}closeLiveState(){this.liveStateSub?.close(),this.liveStateSub=null}onStreamEnded(){this.destroyed||this.endedHandled||(this.endedHandled=!0,this.closeLiveState(),this.stopRefresh(),this.engine?.stop(),this.setState(`ended`))}mountControls(){let e=this.opts.controls??`custom`,t=this.opts.video;if(e===`native`){t.controls=!0;return}if(e===`none`){t.controls=!1;return}t.controls=!1;let n=(t.ownerDocument??document).createElement(`div`),r=t.parentNode;r&&r.insertBefore(n,t),n.appendChild(t),Bd(n,this.opts.theme),this.container=n,this.controlBar=Jd({root:n,video:t,player:this,logoUrl:this.opts.theme?.logoUrl,statusOverlays:this.opts.statusOverlays,endedMessage:this.opts.endedMessage,errorMessage:this.opts.errorMessage})}unmountControls(){this.controlBar?.destroy(),this.controlBar=null;let e=this.container;e?.parentNode&&(e.parentNode.insertBefore(this.opts.video,e),e.remove()),this.container=null}attachPipListeners(){let e=this.opts.video,t=()=>this.emit(`pipchange`,!0),n=()=>this.emit(`pipchange`,!1);e.addEventListener(`enterpictureinpicture`,t),e.addEventListener(`leavepictureinpicture`,n),this.detachPip=()=>{e.removeEventListener(`enterpictureinpicture`,t),e.removeEventListener(`leavepictureinpicture`,n)}}startStats(){this.stopStats();let e=Math.max(500,this.opts.statsIntervalMs??af);this.statsTimer=setInterval(()=>{this.engine&&this.emit(`stats`,this.engine.getStats())},e)}stopStats(){this.statsTimer&&clearInterval(this.statsTimer),this.statsTimer=void 0}scheduleLicenseRefresh(){this.stopRefresh();let e=this.opts.licenseRefreshMs??of;!e||!this._descriptor?.drmEnabled||(this.refreshTimer=setInterval(()=>void this.refreshLicense(),e))}stopRefresh(){this.refreshTimer&&clearInterval(this.refreshTimer),this.refreshTimer=void 0}async refreshLicense(){let e=this.engine;if(!(this.destroyed||!e))try{let t=await D(this.resolveOptions());if(this.destroyed||this.engine!==e)return;let n=t.drm?.widevine?.licenseUrl;n&&(e.setLicenseUrl(n),this._descriptor=t)}catch(e){e instanceof a&&!c(e.code)&&(this.stopRefresh(),this.destroyed||this.emit(`warning`,e))}}async play(){if(!this.destroyed)try{await this.opts.video.play()}catch(e){e instanceof DOMException&&e.name===`NotAllowedError`&&this.emit(`autoplayblocked`)}}pause(){this.destroyed||this.opts.video.pause()}setMuted(e){this.destroyed||(this.opts.video.muted=e)}setVolume(e){this.destroyed||(this.opts.video.volume=Math.min(1,Math.max(0,e)))}getStats(){return this.engine?.getStats()??yd}getQualityLevels(){return this.engine?.getQualityLevels()??[]}getCurrentQuality(){return this.engine?.getCurrentQuality()??-1}setQuality(e){this.destroyed||this.engine?.setQuality(e===`auto`?-1:e)}setMaxBitrate(e){this.destroyed||this.engine?.setMaxBitrate(e)}getAudioTracks(){return this.engine?.getAudioTracks()??[]}setAudioTrack(e){this.destroyed||this.engine?.setAudioTrack(e)}getTextTracks(){return this.engine?.getTextTracks()??[]}setTextTrack(e){this.destroyed||this.engine?.setTextTrack(e)}seekToLive(){this.destroyed||this.engine?.seekToLive()}async enterPictureInPicture(){if(this.destroyed)return;let e=this.opts.video;typeof e.requestPictureInPicture==`function`&&await e.requestPictureInPicture()}async exitPictureInPicture(){let e=document;e.pictureInPictureElement===this.opts.video&&typeof e.exitPictureInPicture==`function`&&await e.exitPictureInPicture()}retry(){return this.reload()}async reload(){if(this.destroyed)return;let e=++this.loadGen;this.stopStats(),this.stopRefresh(),this.closeArming(),this.closeLiveState(),this.detachMedia?.(),this.engine?.destroy(),this.engine=null;try{let t=await O({...this.resolveOptions(),waitForLive:this.opts.waitForLive?this.buildWaitConfig():void 0});await this.onResolved(t,e)}catch(t){if(this.destroyed||this.abort.signal.aborted||e!==this.loadGen)return;throw this.fail(t instanceof a?t:new a(`INTERNAL`,0,String(t))),t}}on(e,t){let n=this.listeners[e]??=new Set;return n.add(t),()=>n.delete(t)}destroy(){this.destroyed||(this.destroyed=!0,this.loadGen+=1,this.abort.abort(),this.stopStats(),this.stopRefresh(),this.unmountControls(),this.closeArming(),this.closeLiveState(),this.detachMedia?.(),this.detachPip?.(),this.engine?.destroy(),this.engine=null,this.setState(`idle`),this.clearListeners())}clearListeners(){for(let e of Object.keys(this.listeners))this.listeners[e]?.clear()}fail(e){this.setState(`error`),this.emit(`error`,e)}setState(e){if(e!==this._state)switch(this._state=e,this.emit(`statechange`,e),e){case`playing`:this.emit(`playing`);break;case`buffering`:this.emit(`buffering`);break;case`paused`:this.emit(`paused`);break;case`ended`:this.emit(`ended`);break;default:break}}emit(e,t){this.listeners[e]?.forEach(e=>{try{e(t)}catch{}})}};function lf(e){return!!e&&typeof e==`object`&&typeof e.type==`string`&&e.type.startsWith(`oddin:`)}function uf(e){if(!e.container||typeof e.container.appendChild!=`function`)throw Error(`mountEmbed: opts.container must be a DOM element`);if(!e.src)throw Error(`mountEmbed: opts.src is required`);if(!e.baseUrl||!e.matchUrn)throw Error(`mountEmbed: opts.baseUrl and opts.matchUrn are required`);let t=new URL(e.src,location.href),n=e.allowedFrameOrigin??t.origin;t.searchParams.set(`baseUrl`,e.baseUrl),t.searchParams.set(`matchUrn`,e.matchUrn),t.searchParams.set(`parentOrigin`,location.origin),e.muted!=null&&t.searchParams.set(`muted`,String(e.muted)),e.apiKey&&(t.searchParams.set(`apiKey`,e.apiKey),console.warn(`havik-player: passing apiKey to mountEmbed places it in the iframe URL — DEV/DEMO only. In production inject it server-side into window.HAVIK_EMBED_CONFIG on the embed page.`));let r=document.createElement(`iframe`);r.src=t.toString(),r.allow=`autoplay; encrypted-media; fullscreen`,r.setAttribute(`allowfullscreen`,``),r.referrerPolicy=`no-referrer`,r.setAttribute(`sandbox`,e.sandbox??`allow-scripts allow-same-origin allow-presentation`),r.style.cssText=`border:0;width:100%;height:100%;display:block`,e.container.appendChild(r);let i=new Set,a=t=>{if(t.source!==r.contentWindow||t.origin!==n||!lf(t.data))return;let a=t.data;a.type===`oddin:ready`&&a.protocol!==1&&console.warn(`havik-player: embed protocol v${a.protocol} != host v1. Pin the embed page version to the SDK version to avoid skew.`),e.onEvent?.(a),i.forEach(e=>e(a))};window.addEventListener(`message`,a);let o=e=>r.contentWindow?.postMessage(e,n);return{iframe:r,play:()=>o({type:`oddin:play`}),pause:()=>o({type:`oddin:pause`}),setMuted:e=>o({type:`oddin:setMuted`,muted:e}),setVolume:e=>o({type:`oddin:setVolume`,volume:e}),setQuality:e=>o({type:`oddin:setQuality`,index:e}),setMaxBitrate:e=>o({type:`oddin:setMaxBitrate`,bitrate:e}),setAudioTrack:e=>o({type:`oddin:setAudioTrack`,id:e}),setTextTrack:e=>o({type:`oddin:setTextTrack`,id:e}),seekToLive:()=>o({type:`oddin:seekToLive`}),enterPip:()=>o({type:`oddin:enterPip`}),exitPip:()=>o({type:`oddin:exitPip`}),retry:()=>o({type:`oddin:retry`}),load:e=>o({type:`oddin:load`,matchUrn:e}),on:e=>(i.add(e),()=>i.delete(e)),destroy:()=>{o({type:`oddin:destroy`}),window.removeEventListener(`message`,a),r.remove()}}}var df=/^[A-Za-z0-9:_.-]{1,128}$/;function ff(){let e=window.HAVIK_EMBED_CONFIG;if(e)return{baseUrl:e.baseUrl??``,matchUrn:e.matchUrn??``,apiKey:e.apiKey??``,parentOrigin:e.parentOrigin,autoplay:e.autoplay??!0,muted:e.muted??!0,waitForLive:e.waitForLive??!0};let t=new URLSearchParams(location.search);return{baseUrl:t.get(`baseUrl`)??``,matchUrn:t.get(`matchUrn`)??``,apiKey:t.get(`apiKey`)??``,parentOrigin:t.get(`parentOrigin`)??void 0,autoplay:!0,muted:t.get(`muted`)!==`false`,waitForLive:!0}}async function pf(){let e=ff();hf();let t=document.createElement(`video`);t.setAttribute(`playsinline`,``),t.muted=e.muted??!0,t.style.cssText=`width:100%;height:100%;object-fit:contain;background:#000;aspect-ratio:auto`,document.body.appendChild(t);let n=e.parentOrigin&&e.parentOrigin!==`null`?e.parentOrigin:null;n||console.warn(`havik-player: embed has no parentOrigin — the postMessage bridge is disabled (no events posted, no commands accepted). mountEmbed sets parentOrigin automatically.`);let r=e=>{if(n)try{window.parent?.postMessage(e,n)}catch{}};if(!e.baseUrl||!e.matchUrn||!e.apiKey){r({type:`oddin:error`,code:`INTERNAL`,message:`embed missing baseUrl/matchUrn/apiKey`});return}let i=null,o=e=>{e.on(`statechange`,e=>r({type:`oddin:state`,state:e})),e.on(`ready`,()=>r({type:`oddin:tracks`,quality:e.getQualityLevels(),audio:e.getAudioTracks(),text:e.getTextTracks()})),e.on(`waiting`,e=>r({type:`oddin:waiting`,retryInMs:e.retryInMs,attempt:e.attempt,phase:e.phase})),e.on(`qualitychange`,e=>r({type:`oddin:qualitychange`,index:e})),e.on(`audiotrackchange`,e=>r({type:`oddin:audiotrackchange`,id:e})),e.on(`texttrackchange`,e=>r({type:`oddin:texttrackchange`,id:e})),e.on(`stats`,e=>r({type:`oddin:stats`,droppedFrames:e.droppedFrames,latencySeconds:e.latencySeconds,bandwidthKbps:e.bandwidthKbps,levelHeight:e.levelHeight,lowLatency:e.lowLatency,isLive:e.isLive,atLiveEdge:e.atLiveEdge})),e.on(`error`,e=>r({type:`oddin:error`,code:e.code,message:e.message})),e.on(`autoplayblocked`,()=>{r({type:`oddin:autoplayblocked`}),mf(t,e)})},s=async n=>{i?.destroy(),i=null;try{let r=await sf({video:t,baseUrl:e.baseUrl,matchUrn:n,credential:{apiKey:e.apiKey},autoplay:e.autoplay,muted:e.muted,waitForLive:e.waitForLive});i=r;let a=t.parentElement;a?.classList.contains(`havik-player`)&&(a.style.cssText=`position:absolute;inset:0;width:100%;height:100%;aspect-ratio:auto`),o(r)}catch(e){let t=e instanceof a?e.code:`INTERNAL`,n=e instanceof Error?e.message:String(e);r({type:`oddin:error`,code:t,message:n})}},c=()=>{window.removeEventListener(`message`,u),window.removeEventListener(`pagehide`,c),i?.destroy(),i=null},l=e=>{switch(e.type){case`oddin:play`:i?.play();break;case`oddin:pause`:i?.pause();break;case`oddin:setMuted`:typeof e.muted==`boolean`&&i?.setMuted(e.muted);break;case`oddin:setVolume`:typeof e.volume==`number`&&Number.isFinite(e.volume)&&i?.setVolume(e.volume);break;case`oddin:setQuality`:typeof e.index==`number`&&i?.setQuality(e.index);break;case`oddin:setMaxBitrate`:(e.bitrate===null||typeof e.bitrate==`number`&&Number.isFinite(e.bitrate))&&i?.setMaxBitrate(e.bitrate);break;case`oddin:setAudioTrack`:typeof e.id==`number`&&i?.setAudioTrack(e.id);break;case`oddin:setTextTrack`:typeof e.id==`number`&&i?.setTextTrack(e.id);break;case`oddin:seekToLive`:i?.seekToLive();break;case`oddin:enterPip`:i?.enterPictureInPicture();break;case`oddin:exitPip`:i?.exitPictureInPicture();break;case`oddin:retry`:i?.retry();break;case`oddin:load`:typeof e.matchUrn==`string`&&df.test(e.matchUrn)&&s(e.matchUrn);break;case`oddin:destroy`:c();break}},u=e=>{!n||e.origin!==n||lf(e.data)&&l(e.data)};n&&window.addEventListener(`message`,u),window.addEventListener(`pagehide`,c,{once:!0}),await s(e.matchUrn),r({type:`oddin:ready`,protocol:1})}function mf(e,t){if(document.getElementById(`havik-tap`))return;let n=document.createElement(`button`);n.id=`havik-tap`,n.textContent=`▶ Tap to play`,n.style.cssText=`position:fixed;inset:0;width:100%;height:100%;border:0;background:rgba(0,0,0,.55);color:#fff;font:600 18px system-ui,sans-serif;cursor:pointer;z-index:9`,n.addEventListener(`click`,()=>{n.remove(),t.play()}),document.body.appendChild(n)}function hf(){let e=document.createElement(`style`);e.textContent=`html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}`,document.head.appendChild(e)}return e.ODDIN_THEME=Rd,e.PlaybackError=a,e.applyTheme=Bd,e.bootEmbed=pf,e.clearDeviceId=ue,e.createPlayer=sf,e.deriveEventsBaseUrl=oe,e.fetchCatalog=N,e.fetchTournament=te,e.flattenMatches=re,e.getDeviceId=le,e.isLowLatencyManifest=me,e.isOddinMessage=lf,e.licenseRequestHeaders=fe,e.mountEmbed=uf,e.pollToLive=E,e.resolveStream=O,e.subscribeLiveState=ae,e.watchStatus=ie,e})({});
|
|
146
|
+
`;function Ud(e=document){if(e.getElementById(Vd))return;let t=e.createElement(`style`);t.id=Vd,t.textContent=Hd,e.head.appendChild(t)}var Wd={play:`<path d="M8 5v14l11-7z"/>`,pause:`<path d="M6 5h4v14H6zM14 5h4v14h-4z"/>`,volumeHigh:`<path d="M3 10v4h4l5 5V5L7 10H3zm13.5 2a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4zm-2.5-9v2.06A7 7 0 0 1 14 19v2a9 9 0 0 0 0-18z"/>`,volumeMute:`<path d="M3 10v4h4l5 5V5L7 10H3zm16.5 2 2.5-2.5-1.4-1.4L18 10.6 15.4 8 14 9.4l2.6 2.6L14 14.6l1.4 1.4 2.6-2.6 2.6 2.6 1.4-1.4z"/>`,cc:`<path d="M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM10 11H8.5v-.5h-2v3h2V13H10v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H17v1a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1z"/>`,settings:`<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.11-.2.06-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>`,pip:`<path d="M19 7h-8v6h8V7zm4 12V5a2 2 0 0 0-2-2H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2zm-2 .02H3V4.98h18v14.04z"/>`,fullscreen:`<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>`,fullscreenExit:`<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>`,liveDot:`<circle cx="12" cy="12" r="6"/>`,retry:`<path d="M17.65 6.35A8 8 0 1 0 19.73 13h-2.08A6 6 0 1 1 12 6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>`};function Gd(e){return`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="currentColor">${Wd[e]}</svg>`}var Kd=3e3,qd=new Set([`GONE`,`NOT_FOUND`,`INVALID_URN`,`UNAUTHORIZED`]);function Jd(e){return new Yd(e)}var Yd=class{constructor(e){i(this,`root`,void 0),i(this,`video`,void 0),i(this,`player`,void 0),i(this,`doc`,void 0),i(this,`autoHideMs`,void 0),i(this,`overlay`,void 0),i(this,`center`,void 0),i(this,`spinner`,void 0),i(this,`bar`,void 0),i(this,`gradient`,void 0),i(this,`seek`,void 0),i(this,`seekBuffered`,void 0),i(this,`seekPlayed`,void 0),i(this,`seekThumb`,void 0),i(this,`playBtn`,void 0),i(this,`muteBtn`,void 0),i(this,`volSlider`,void 0),i(this,`live`,void 0),i(this,`liveGo`,void 0),i(this,`time`,void 0),i(this,`ccBtn`,void 0),i(this,`audioBtn`,void 0),i(this,`qualityBtn`,void 0),i(this,`pipBtn`,void 0),i(this,`fsBtn`,void 0),i(this,`menu`,void 0),i(this,`statusBox`,null),i(this,`statusKind`,null),i(this,`hasPlayed`,!1),i(this,`lastError`,null),i(this,`logoUrl`,void 0),i(this,`statusOverlays`,void 0),i(this,`endedMessage`,void 0),i(this,`errorMessage`,void 0),i(this,`hideTimer`,void 0),i(this,`openMenu`,null),i(this,`scrubbing`,!1),i(this,`offFns`,[]),this.root=e.root,this.video=e.video,this.player=e.player,this.doc=e.root.ownerDocument??document,this.autoHideMs=e.autoHideMs??Kd,this.logoUrl=e.logoUrl,this.statusOverlays=e.statusOverlays!==!1,this.endedMessage=e.endedMessage??`This stream has ended`,this.errorMessage=e.errorMessage,Ud(this.doc),this.root.classList.add(`havik-player`),this.root.hasAttribute(`tabindex`)||(this.root.tabIndex=0),this.root.setAttribute(`role`,`region`),this.root.setAttribute(`aria-label`,`Video player`);let t=(e,t,n)=>{let r=this.doc.createElement(e);if(r.className=t,n)for(let[e,t]of Object.entries(n))r.setAttribute(e,t);return r},n=(e,n,r)=>{let i=t(`button`,e,{type:`button`,"aria-label":r,title:r});return i.innerHTML=Gd(n),i};this.overlay=t(`div`,`havik-overlay`),this.center=t(`button`,`havik-center`,{type:`button`,"aria-label":`Play`}),this.center.innerHTML=Gd(`play`),this.spinner=t(`div`,`havik-spinner`),this.spinner.style.display=`none`,this.overlay.append(this.center,this.spinner),this.gradient=t(`div`,`havik-gradient`),this.bar=t(`div`,`havik-bar`),this.seek=t(`div`,`havik-seek`,{role:`slider`,"aria-label":`Seek`,"aria-valuemin":`0`,"aria-valuemax":`100`,tabindex:`0`});let r=t(`div`,`havik-seek__track`);this.seekBuffered=t(`div`,`havik-seek__buffered`),this.seekPlayed=t(`div`,`havik-seek__played`),this.seekThumb=t(`div`,`havik-seek__thumb`),r.append(this.seekBuffered,this.seekPlayed,this.seekThumb),this.seek.append(r);let a=t(`div`,`havik-controls`);this.playBtn=n(`havik-btn`,`play`,`Play`),this.muteBtn=n(`havik-btn`,`volumeHigh`,`Mute`),this.volSlider=t(`input`,`havik-vol__slider`,{type:`range`,min:`0`,max:`1`,step:`0.05`,"aria-label":`Volume`});let o=t(`div`,`havik-vol`);o.append(this.muteBtn,this.volSlider),this.live=t(`div`,`havik-live`),this.live.innerHTML=Gd(`liveDot`);let s=this.doc.createElement(`span`);s.textContent=`LIVE`,this.liveGo=t(`button`,`havik-live__go`,{type:`button`}),this.liveGo.textContent=`Go live`,this.live.append(s,this.liveGo),this.time=t(`div`,`havik-time`),this.time.textContent=`0:00`,this.time.style.display=`none`;let c=t(`div`,`havik-spacer`);if(this.ccBtn=n(`havik-btn`,`cc`,`Subtitles`),this.audioBtn=n(`havik-btn`,`settings`,`Audio track`),this.qualityBtn=n(`havik-btn`,`settings`,`Quality`),this.pipBtn=n(`havik-btn`,`pip`,`Picture in picture`),this.fsBtn=n(`havik-btn`,`fullscreen`,`Fullscreen`),this.ccBtn.style.display=`none`,this.audioBtn.style.display=`none`,this.qualityBtn.style.display=`none`,this.pipSupported()||(this.pipBtn.style.display=`none`),a.append(this.playBtn,o,this.live,this.time,c,this.ccBtn,this.audioBtn,this.qualityBtn,this.pipBtn,this.fsBtn),this.bar.append(this.seek,a),this.menu=t(`div`,`havik-menu`,{role:`menu`}),this.menu.hidden=!0,this.root.append(this.gradient,this.overlay,this.bar,this.menu),e.logoUrl){let n=t(`div`,`havik-watermark`);n.style.backgroundImage=`url("${e.logoUrl}")`,this.root.append(n)}this.wire(),this.syncPlayPause(),this.syncVolume(),this.scheduleHide()}on(e,t,n,r){e.addEventListener(t,n,r),this.offFns.push(()=>e.removeEventListener(t,n,r))}wire(){let e=this.video;this.on(this.playBtn,`click`,()=>this.togglePlay()),this.on(this.center,`click`,()=>this.togglePlay()),this.on(this.overlay,`click`,e=>{e.target===this.overlay&&this.togglePlay()}),this.on(this.muteBtn,`click`,()=>this.player.setMuted(!e.muted)),this.on(this.volSlider,`input`,()=>{let t=Number(this.volSlider.value);this.player.setVolume(t),t>0&&e.muted&&this.player.setMuted(!1)}),this.on(this.liveGo,`click`,()=>this.player.seekToLive()),this.on(this.pipBtn,`click`,()=>void this.togglePip()),this.on(this.fsBtn,`click`,()=>void this.toggleFullscreen()),this.on(this.ccBtn,`click`,()=>this.toggleMenu(`cc`)),this.on(this.audioBtn,`click`,()=>this.toggleMenu(`audio`)),this.on(this.qualityBtn,`click`,()=>this.toggleMenu(`quality`)),this.on(this.seek,`pointerdown`,e=>this.onSeekDown(e)),this.on(this.seek,`keydown`,e=>this.onSeekKey(e)),this.on(e,`play`,()=>this.syncPlayPause()),this.on(e,`pause`,()=>this.syncPlayPause()),this.on(e,`volumechange`,()=>this.syncVolume()),this.on(e,`timeupdate`,()=>this.syncProgress()),this.on(e,`progress`,()=>this.syncProgress()),this.on(e,`durationchange`,()=>this.syncProgress()),this.offFns.push(this.player.on(`statechange`,()=>this.syncState())),this.offFns.push(this.player.on(`ready`,()=>this.refreshTracks())),this.offFns.push(this.player.on(`qualitychange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`audiotrackchange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`texttrackchange`,()=>this.onTracksChanged())),this.offFns.push(this.player.on(`pipchange`,e=>this.syncPip(e))),this.offFns.push(this.player.on(`stats`,()=>this.syncLive())),this.offFns.push(this.player.on(`error`,e=>{this.lastError=e,this.statusKind=null,this.syncState()})),this.on(this.root,`pointermove`,()=>this.poke()),this.on(this.root,`pointerleave`,()=>this.scheduleHide(0)),this.on(this.root,`focusin`,()=>this.poke()),this.on(this.root,`keydown`,e=>this.onKey(e)),this.on(this.doc,`pointerdown`,e=>this.onDocPointer(e),{capture:!0}),this.on(this.doc,`fullscreenchange`,()=>this.syncFullscreen()),this.syncState()}togglePlay(){this.video.paused||this.video.ended?this.player.play():this.player.pause()}syncPlayPause(){let e=!this.video.paused&&!this.video.ended;this.setIcon(this.playBtn,e?`pause`:`play`),this.playBtn.setAttribute(`aria-label`,e?`Pause`:`Play`),this.setIcon(this.center,e?`pause`:`play`),this.center.classList.toggle(`havik-gone`,e||!!this.statusBox),e?this.scheduleHide():this.show()}syncState(){let e=this.player.state;(e===`playing`||e===`buffering`)&&(this.hasPlayed=!0),this.syncStatus(e);let t=e===`loading`||e===`buffering`;this.spinner.style.display=t&&!this.statusBox?``:`none`,(t||this.statusBox)&&this.center.classList.add(`havik-gone`),this.syncLive()}syncStatus(e){let t=null;this.statusOverlays&&(e===`ended`?t=`ended`:e===`error`?t=`error`:e===`waiting`?t=`waiting`:!this.hasPlayed&&(e===`idle`||e===`paused`)&&(t=`preplay`)),this.renderStatus(t)}renderStatus(e){if(e===this.statusKind||(this.statusKind=e,this.statusBox?.remove(),this.statusBox=null,!e))return;let t=this.doc.createElement(`div`);if(t.className=`havik-status havik-status--${e}`,this.logoUrl){let e=this.doc.createElement(`div`);e.className=`havik-status__logo`,t.append(e)}if(e===`preplay`){let e=this.doc.createElement(`button`);e.type=`button`,e.className=`havik-status__btn havik-status__btn--play`,e.setAttribute(`aria-label`,`Play`),e.innerHTML=Gd(`play`),e.addEventListener(`click`,()=>void this.player.play()),t.append(e)}else{let n=this.doc.createElement(`div`);if(n.className=`havik-status__msg`,n.textContent=e===`ended`?this.endedMessage:e===`waiting`?`Starting soon…`:this.errorMessage??this.lastError?.message??`Playback unavailable`,t.append(n),e===`error`&&this.lastError&&!qd.has(this.lastError.code)){let e=this.doc.createElement(`button`);e.type=`button`,e.className=`havik-status__btn`,e.innerHTML=`${Gd(`retry`)}<span>Retry</span>`,e.addEventListener(`click`,()=>void this.player.retry()),t.append(e)}}this.root.append(t),this.statusBox=t,this.show()}syncVolume(){let e=this.video,t=e.muted||e.volume===0;this.setIcon(this.muteBtn,t?`volumeMute`:`volumeHigh`),this.muteBtn.setAttribute(`aria-label`,t?`Unmute`:`Mute`),this.volSlider.value=String(t?0:e.volume)}seekableRange(){let e=this.video,t,n;if(e.seekable&&e.seekable.length>0)t=e.seekable.start(0),n=e.seekable.end(e.seekable.length-1);else if(Number.isFinite(e.duration)&&e.duration>0)t=0,n=e.duration;else return null;let r=this.player.getStats();return r.isLive!==!1&&r.targetLatencySeconds&&r.targetLatencySeconds>0&&(n=Math.max(t,n-r.targetLatencySeconds)),n>t?{start:t,end:n}:null}syncProgress(){if(this.scrubbing)return;let e=this.seekableRange();if(!e){this.seekPlayed.style.width=`100%`;return}let t=e.end-e.start,n=Math.min(1,Math.max(0,(this.video.currentTime-e.start)/t));this.seekPlayed.style.width=`${(n*100).toFixed(2)}%`,this.seekThumb.style.left=`${(n*100).toFixed(2)}%`,this.seek.setAttribute(`aria-valuenow`,String(Math.round(n*100)));let r=this.video.buffered;if(r&&r.length>0){let n=r.end(r.length-1),i=Math.min(1,Math.max(0,(n-e.start)/t));this.seekBuffered.style.width=`${(i*100).toFixed(2)}%`}!this.player.getStats().isLive&&Number.isFinite(this.video.duration)&&(this.time.textContent=`${Xd(this.video.currentTime)} / ${Xd(this.video.duration)}`)}syncLive(){let e=this.player.getStats(),t=e.isLive!==!1;this.live.style.display=t?``:`none`,this.time.style.display=t?`none`:``,this.live.classList.toggle(`is-live`,e.atLiveEdge!==!1&&t)}onSeekDown(e){let t=this.seekableRange();if(!t)return;e.preventDefault(),this.scrubbing=!0;let n=e=>this.seekToPointer(e,t),r=()=>{this.scrubbing=!1,this.doc.removeEventListener(`pointermove`,n),this.doc.removeEventListener(`pointerup`,r)};this.doc.addEventListener(`pointermove`,n),this.doc.addEventListener(`pointerup`,r),this.seekToPointer(e,t)}seekToPointer(e,t){let n=this.seek.getBoundingClientRect(),r=n.width>0?Math.min(1,Math.max(0,(e.clientX-n.left)/n.width)):0;this.seekPlayed.style.width=`${(r*100).toFixed(2)}%`,this.seekThumb.style.left=`${(r*100).toFixed(2)}%`,this.video.currentTime=t.start+r*(t.end-t.start)}onSeekKey(e){e.key===`ArrowLeft`?(this.nudge(-5),e.preventDefault()):e.key===`ArrowRight`&&(this.nudge(5),e.preventDefault())}nudge(e){let t=this.seekableRange();t&&(this.video.currentTime=Math.min(t.end,Math.max(t.start,this.video.currentTime+e)))}toggleMenu(e){if(this.openMenu===e){this.closeMenu();return}this.openMenu=e,this.renderMenu(e),this.menu.hidden=!1,this.show()}closeMenu(){this.openMenu=null,this.menu.hidden=!0,this.menu.replaceChildren()}renderMenu(e){e===`quality`?this.renderQualityMenu():e===`audio`?this.renderAudioMenu():this.renderCcMenu()}menuItem(e,t,n){let r=this.doc.createElement(`button`);r.type=`button`,r.className=`havik-menu__item`,r.setAttribute(`role`,`menuitemradio`),r.setAttribute(`aria-checked`,t?`true`:`false`);let i=this.doc.createElement(`span`);return i.textContent=e,r.append(i),r.addEventListener(`click`,()=>{n(),this.closeMenu()}),r}renderQualityMenu(){let e=this.player.getQualityLevels(),t=this.player.getCurrentQuality(),n=this.doc.createElement(`div`);n.className=`havik-menu__title`,n.textContent=`Quality`,this.menu.replaceChildren(n,this.menuItem(`Auto`,t===-1,()=>this.player.setQuality(`auto`)));for(let n of e)this.menu.append(this.menuItem(Zd(n),t===n.index,()=>this.player.setQuality(n.index)))}renderAudioMenu(){let e=this.player.getAudioTracks(),t=this.doc.createElement(`div`);t.className=`havik-menu__title`,t.textContent=`Audio`,this.menu.replaceChildren(t);for(let t of e)this.menu.append(this.menuItem(Qd(t),t.default,()=>this.player.setAudioTrack(t.id)))}renderCcMenu(){let e=this.player.getTextTracks(),t=this.doc.createElement(`div`);t.className=`havik-menu__title`,t.textContent=`Subtitles`,this.menu.replaceChildren(t,this.menuItem(`Off`,!1,()=>this.player.setTextTrack(-1)));for(let t of e)this.menu.append(this.menuItem($d(t),!1,()=>this.player.setTextTrack(t.id)))}onTracksChanged(){this.openMenu&&this.renderMenu(this.openMenu)}refreshTracks(){let e=this.player.getQualityLevels(),t=this.player.getAudioTracks(),n=this.player.getTextTracks();this.qualityBtn.style.display=e.length>1?``:`none`,this.audioBtn.style.display=t.length>1?``:`none`,this.ccBtn.style.display=n.length>0?``:`none`,this.onTracksChanged()}pipSupported(){return`pictureInPictureEnabled`in this.doc&&typeof this.video.requestPictureInPicture==`function`}async togglePip(){this.doc.pictureInPictureElement===this.video?await this.player.exitPictureInPicture():await this.player.enterPictureInPicture()}syncPip(e){this.pipBtn.setAttribute(`aria-pressed`,e?`true`:`false`)}async toggleFullscreen(){let e=this.root,t=this.doc;try{t.fullscreenElement?await t.exitFullscreen?.():await e.requestFullscreen?.()}catch{}}syncFullscreen(){let e=this.doc.fullscreenElement===this.root;this.setIcon(this.fsBtn,e?`fullscreenExit`:`fullscreen`),this.fsBtn.setAttribute(`aria-label`,e?`Exit fullscreen`:`Fullscreen`)}poke(){this.show(),this.scheduleHide()}show(){this.root.classList.remove(`havik-hide`)}scheduleHide(e=this.autoHideMs){this.hideTimer&&clearTimeout(this.hideTimer),this.hideTimer=setTimeout(()=>{!this.video.paused&&!this.video.ended&&!this.openMenu&&!this.statusBox&&this.root.classList.add(`havik-hide`)},e)}onDocPointer(e){this.openMenu&&!this.menu.contains(e.target)&&([this.qualityBtn,this.audioBtn,this.ccBtn].some(t=>t.contains(e.target))||this.closeMenu())}onKey(e){let t=e.target;if(!(t&&t!==this.root&&t!==this.seek&&t.tagName===`INPUT`)){switch(e.key){case` `:case`k`:this.togglePlay();break;case`m`:this.player.setMuted(!this.video.muted);break;case`f`:this.toggleFullscreen();break;case`c`:this.ccBtn.style.display!==`none`&&this.toggleMenu(`cc`);break;case`l`:this.player.seekToLive();break;case`ArrowUp`:this.player.setVolume(Math.min(1,this.video.volume+.1));break;case`ArrowDown`:this.player.setVolume(Math.max(0,this.video.volume-.1));break;case`ArrowLeft`:this.nudge(-5);break;case`ArrowRight`:this.nudge(5);break;default:return}this.poke(),e.preventDefault()}}setIcon(e,t){e.innerHTML=Gd(t)}destroy(){this.hideTimer&&clearTimeout(this.hideTimer);for(let e of this.offFns)try{e()}catch{}this.offFns.length=0,this.closeMenu(),this.statusBox?.remove();for(let e of[this.overlay,this.gradient,this.bar,this.menu])e.remove();this.root.classList.remove(`havik-player`,`havik-hide`)}};function Xd(e){(!Number.isFinite(e)||e<0)&&(e=0);let t=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),i=r>0?String(n).padStart(2,`0`):String(n),a=String(t).padStart(2,`0`);return r>0?`${r}:${i}:${a}`:`${i}:${a}`}function Zd(e){return e.height?`${e.height}p`:`${Math.round(e.bitrate/1e3)} kbps`}function Qd(e){return e.name||e.lang||`Track ${e.id}`}function $d(e){return e.name||e.lang||`Track ${e.id}`}var ef=6e3,tf=45e3,nf=2e3,rf=3,af=2e3,of=480*1e3;async function sf(e){if(!e.video||typeof e.video.play!=`function`)throw new a(`INTERNAL`,0,`createPlayer: opts.video must be an HTMLVideoElement`);if(!e.baseUrl)throw new a(`INTERNAL`,0,`createPlayer: baseUrl is required`);if(!e.matchUrn)throw new a(`INVALID_URN`,0,`createPlayer: matchUrn is required`);if(!e.credential)throw new a(`INTERNAL`,0,`createPlayer: credential is required`);let t=new cf(e);return await t.start(),t}var cf=class{constructor(e){i(this,`opts`,void 0),i(this,`abort`,new AbortController),i(this,`listeners`,{}),i(this,`engine`,null),i(this,`controlBar`,null),i(this,`container`,null),i(this,`detachMedia`,void 0),i(this,`detachPip`,void 0),i(this,`statsTimer`,void 0),i(this,`refreshTimer`,void 0),i(this,`_state`,`idle`),i(this,`_descriptor`,null),i(this,`destroyed`,!1),i(this,`loadGen`,0),i(this,`liveStateSub`,null),i(this,`endedHandled`,!1),i(this,`armingSub`,null),i(this,`armSseTimer`,null),this.opts=e}get state(){return this._state}get descriptor(){return this._descriptor}async start(){this.opts.muted&&(this.opts.video.muted=!0),this.opts.poster&&(this.opts.video.poster=this.opts.poster),this.mountControls(),this.attachPipListeners(),this.setState(`loading`);let e=++this.loadGen,t=this.resolveOptions();try{let n=await D(t);await this.onResolved(n,e)}catch(t){if(this.opts.waitForLive&&t instanceof a&&c(t.code)){this.setState(`waiting`),this.beginArming(e);return}throw t}}resolveOptions(){return{baseUrl:this.opts.baseUrl,matchUrn:this.opts.matchUrn,credential:this.opts.credential,signal:this.abort.signal}}beginArming(e){let t=this.opts.liveStateEvents===!1?void 0:this.opts.eventsBaseUrl??oe(this.opts.baseUrl);t?this.armWithSse(e,t):this.beginArmingByPolling(e)}beginArmingByPolling(e,t){O({...this.resolveOptions(),signal:t??this.abort.signal,waitForLive:this.buildWaitConfig()}).then(t=>this.onResolved(t,e)).catch(n=>{this.destroyed||this.abort.signal.aborted||t?.aborted||e!==this.loadGen||this.fail(n)})}armWithSse(e,t){let n=!1,r=!1,i=new AbortController;this.abort.signal.addEventListener(`abort`,()=>i.abort(),{once:!0}),this.setState(`waiting`);let o=()=>this.destroyed||this.abort.signal.aborted||e!==this.loadGen,s=async t=>{n||o()||(n=!0,this.closeArming(),i.abort(),await this.onResolved(t,e))},l=()=>{n||r||o()||(r=!0,this.beginArmingByPolling(e,i.signal))},u=()=>{n||o()||D(this.resolveOptions()).then(e=>s(e)).catch(e=>{n||o()||e instanceof a&&c(e.code)||(n=!0,this.closeArming(),i.abort(),this.fail(e instanceof a?e:new a(`INTERNAL`,0,String(e))))})},d=e=>{this.armSseTimer&&clearTimeout(this.armSseTimer),this.armSseTimer=setTimeout(()=>{!n&&!o()&&l()},e)};d(ef),this.armingSub=ae({eventsBaseUrl:t,matchUrn:this.opts.matchUrn,credential:this.opts.credential,onAlive:()=>d(tf),onState:e=>{n||o()||(e.state===`live`||e.state===`gone`)&&setTimeout(u,Math.random()*nf)},onError:()=>l()})}closeArming(){this.armSseTimer&&=(clearTimeout(this.armSseTimer),null),this.armingSub?.close(),this.armingSub=null}buildWaitConfig(){let e=this.opts.waitForLive&&this.opts.waitForLive!==!0?this.opts.waitForLive:{};return{...e,onState:t=>{this.setState(`waiting`),this.emit(`waiting`,t),e.onState?.(t)}}}async onResolved(e,t){if(this.destroyed||t!==this.loadGen)return;this._descriptor=e,this.endedHandled=!1;let n=await l(this.opts.credential);if(this.destroyed||t!==this.loadGen)return;this.setState(`loading`);let r=this.createEngine(e,n),i=xd(this.opts.video,e=>this.setState(e));if(await r.load(),this.destroyed||t!==this.loadGen){i(),r.destroy();return}this.engine=r,this.detachMedia=i,this.opts.maxBitrate!=null&&r.setMaxBitrate(this.opts.maxBitrate),this.startStats(),this.scheduleLicenseRefresh(),this.startLiveState(t)}createEngine(e,t){let n={...this.opts.hlsConfig};this.opts.startLevel!=null&&(n.startLevel=this.opts.startLevel),this.opts.liveLatencyTarget!=null&&(n.liveSyncDuration=this.opts.liveLatencyTarget);let r={video:this.opts.video,descriptor:e,credential:t,deviceId:le(),userId:this.opts.userId,lowLatency:this.opts.lowLatency===void 0||this.opts.lowLatency===`auto`||this.opts.lowLatency,snapToLiveOnRefocus:this.opts.snapToLiveOnRefocus,debug:this.opts.debug,hlsConfig:n,emit:e=>this.onEngineEvent(e)},i=this.opts.engine??`auto`;if(i===`native`)return new Ld(r);if(i===`hls`||Sd())return new Fd(r);if(Id(this.opts.video))return new Ld(r);throw new a(`INTERNAL`,0,`no supported HLS playback engine in this browser`)}onEngineEvent(e){if(!this.destroyed)switch(e.type){case`ready`:this.emit(`ready`),this.opts.autoplay!==!1&&this.play();break;case`lowLatencyDetected`:this._descriptor&&(this._descriptor.isLowLatency=e.value);break;case`qualitychange`:this.emit(`qualitychange`,e.index);break;case`audiotrackchange`:this.emit(`audiotrackchange`,e.id);break;case`texttrackchange`:this.emit(`texttrackchange`,e.id);break;case`ended`:this.onStreamEnded();break;case`error`:e.fatal?this.fail(e.error):this.emit(`warning`,e.error);break}}startLiveState(e){if(this.opts.liveStateEvents===!1)return;let t=this.opts.eventsBaseUrl??oe(this.opts.baseUrl);if(!t)return;this.closeLiveState();let n=0,r=!1;this.liveStateSub=ae({eventsBaseUrl:t,matchUrn:this.opts.matchUrn,credential:this.opts.credential,onState:t=>{this.destroyed||e!==this.loadGen||(t.state===`ended`||t.state===`gone`)&&this.onStreamEnded()},onAlive:()=>{n=0,r=!1},onError:()=>{this.destroyed||e!==this.loadGen||r||(n+=1,n>=rf&&(r=!0,this.emit(`warning`,new a(`NETWORK`,0,`live-state events unreachable at ${t} after ${n} attempts — end-of-stream detection degraded to the HLS staleness watchdog. Check the events host, the api-key's allowed origins, and CSP connect-src.`))))}})}closeLiveState(){this.liveStateSub?.close(),this.liveStateSub=null}onStreamEnded(){this.destroyed||this.endedHandled||(this.endedHandled=!0,this.closeLiveState(),this.stopRefresh(),this.engine?.stop(),this.setState(`ended`))}mountControls(){let e=this.opts.controls??`custom`,t=this.opts.video;if(e===`native`){t.controls=!0;return}if(e===`none`){t.controls=!1;return}t.controls=!1;let n=(t.ownerDocument??document).createElement(`div`),r=t.parentNode;r&&r.insertBefore(n,t),n.appendChild(t),Bd(n,this.opts.theme),this.container=n,this.controlBar=Jd({root:n,video:t,player:this,logoUrl:this.opts.theme?.logoUrl,statusOverlays:this.opts.statusOverlays,endedMessage:this.opts.endedMessage,errorMessage:this.opts.errorMessage})}unmountControls(){this.controlBar?.destroy(),this.controlBar=null;let e=this.container;e?.parentNode&&(e.parentNode.insertBefore(this.opts.video,e),e.remove()),this.container=null}attachPipListeners(){let e=this.opts.video,t=()=>this.emit(`pipchange`,!0),n=()=>this.emit(`pipchange`,!1);e.addEventListener(`enterpictureinpicture`,t),e.addEventListener(`leavepictureinpicture`,n),this.detachPip=()=>{e.removeEventListener(`enterpictureinpicture`,t),e.removeEventListener(`leavepictureinpicture`,n)}}startStats(){this.stopStats();let e=Math.max(500,this.opts.statsIntervalMs??af);this.statsTimer=setInterval(()=>{this.engine&&this.emit(`stats`,this.engine.getStats())},e)}stopStats(){this.statsTimer&&clearInterval(this.statsTimer),this.statsTimer=void 0}scheduleLicenseRefresh(){this.stopRefresh();let e=this.opts.licenseRefreshMs??of;!e||!this._descriptor?.drmEnabled||(this.refreshTimer=setInterval(()=>void this.refreshLicense(),e))}stopRefresh(){this.refreshTimer&&clearInterval(this.refreshTimer),this.refreshTimer=void 0}async refreshLicense(){let e=this.engine;if(!(this.destroyed||!e))try{let t=await D(this.resolveOptions());if(this.destroyed||this.engine!==e)return;let n=t.drm?.widevine?.licenseUrl;n&&(e.setLicenseUrl(n),this._descriptor=t)}catch(e){e instanceof a&&!c(e.code)&&(this.stopRefresh(),this.destroyed||this.emit(`warning`,e))}}async play(){if(!this.destroyed)try{await this.opts.video.play()}catch(e){e instanceof DOMException&&e.name===`NotAllowedError`&&this.emit(`autoplayblocked`)}}pause(){this.destroyed||this.opts.video.pause()}setMuted(e){this.destroyed||(this.opts.video.muted=e)}setVolume(e){this.destroyed||(this.opts.video.volume=Math.min(1,Math.max(0,e)))}getStats(){return this.engine?.getStats()??yd}getQualityLevels(){return this.engine?.getQualityLevels()??[]}getCurrentQuality(){return this.engine?.getCurrentQuality()??-1}setQuality(e){this.destroyed||this.engine?.setQuality(e===`auto`?-1:e)}setMaxBitrate(e){this.destroyed||this.engine?.setMaxBitrate(e)}getAudioTracks(){return this.engine?.getAudioTracks()??[]}setAudioTrack(e){this.destroyed||this.engine?.setAudioTrack(e)}getTextTracks(){return this.engine?.getTextTracks()??[]}setTextTrack(e){this.destroyed||this.engine?.setTextTrack(e)}seekToLive(){this.destroyed||this.engine?.seekToLive()}async enterPictureInPicture(){if(this.destroyed)return;let e=this.opts.video;typeof e.requestPictureInPicture==`function`&&await e.requestPictureInPicture()}async exitPictureInPicture(){let e=document;e.pictureInPictureElement===this.opts.video&&typeof e.exitPictureInPicture==`function`&&await e.exitPictureInPicture()}retry(){return this.reload()}async reload(){if(this.destroyed)return;let e=++this.loadGen;this.stopStats(),this.stopRefresh(),this.closeArming(),this.closeLiveState(),this.detachMedia?.(),this.engine?.destroy(),this.engine=null;try{let t=await O({...this.resolveOptions(),waitForLive:this.opts.waitForLive?this.buildWaitConfig():void 0});await this.onResolved(t,e)}catch(t){if(this.destroyed||this.abort.signal.aborted||e!==this.loadGen)return;throw this.fail(t instanceof a?t:new a(`INTERNAL`,0,String(t))),t}}on(e,t){let n=this.listeners[e]??=new Set;return n.add(t),()=>n.delete(t)}destroy(){this.destroyed||(this.destroyed=!0,this.loadGen+=1,this.abort.abort(),this.stopStats(),this.stopRefresh(),this.unmountControls(),this.closeArming(),this.closeLiveState(),this.detachMedia?.(),this.detachPip?.(),this.engine?.destroy(),this.engine=null,this.setState(`idle`),this.clearListeners())}clearListeners(){for(let e of Object.keys(this.listeners))this.listeners[e]?.clear()}fail(e){this.setState(`error`),this.emit(`error`,e)}setState(e){if(e!==this._state)switch(this._state=e,this.emit(`statechange`,e),e){case`playing`:this.emit(`playing`);break;case`buffering`:this.emit(`buffering`);break;case`paused`:this.emit(`paused`);break;case`ended`:this.emit(`ended`);break;default:break}}emit(e,t){this.listeners[e]?.forEach(e=>{try{e(t)}catch{}})}};function lf(e){return!!e&&typeof e==`object`&&typeof e.type==`string`&&e.type.startsWith(`oddin:`)}function uf(e){if(!e.container||typeof e.container.appendChild!=`function`)throw Error(`mountEmbed: opts.container must be a DOM element`);if(!e.src)throw Error(`mountEmbed: opts.src is required`);if(!e.baseUrl||!e.matchUrn)throw Error(`mountEmbed: opts.baseUrl and opts.matchUrn are required`);let t=new URL(e.src,location.href),n=e.allowedFrameOrigin??t.origin;t.searchParams.set(`baseUrl`,e.baseUrl),t.searchParams.set(`matchUrn`,e.matchUrn),t.searchParams.set(`parentOrigin`,location.origin),e.muted!=null&&t.searchParams.set(`muted`,String(e.muted)),e.apiKey&&(t.searchParams.set(`apiKey`,e.apiKey),console.warn(`havik-player: passing apiKey to mountEmbed places it in the iframe URL — DEV/DEMO only. In production inject it server-side into window.HAVIK_EMBED_CONFIG on the embed page.`));let r=document.createElement(`iframe`);r.src=t.toString(),r.allow=`autoplay; encrypted-media; fullscreen`,r.setAttribute(`allowfullscreen`,``),r.referrerPolicy=`no-referrer`,r.setAttribute(`sandbox`,e.sandbox??`allow-scripts allow-same-origin allow-presentation`),r.style.cssText=`border:0;width:100%;height:100%;display:block`,e.container.appendChild(r);let i=new Set,a=t=>{if(t.source!==r.contentWindow||t.origin!==n||!lf(t.data))return;let a=t.data;a.type===`oddin:ready`&&a.protocol!==1&&console.warn(`havik-player: embed protocol v${a.protocol} != host v1. Pin the embed page version to the SDK version to avoid skew.`),e.onEvent?.(a),i.forEach(e=>e(a))};window.addEventListener(`message`,a);let o=e=>r.contentWindow?.postMessage(e,n);return{iframe:r,play:()=>o({type:`oddin:play`}),pause:()=>o({type:`oddin:pause`}),setMuted:e=>o({type:`oddin:setMuted`,muted:e}),setVolume:e=>o({type:`oddin:setVolume`,volume:e}),setQuality:e=>o({type:`oddin:setQuality`,index:e}),setMaxBitrate:e=>o({type:`oddin:setMaxBitrate`,bitrate:e}),setAudioTrack:e=>o({type:`oddin:setAudioTrack`,id:e}),setTextTrack:e=>o({type:`oddin:setTextTrack`,id:e}),seekToLive:()=>o({type:`oddin:seekToLive`}),enterPip:()=>o({type:`oddin:enterPip`}),exitPip:()=>o({type:`oddin:exitPip`}),retry:()=>o({type:`oddin:retry`}),load:e=>o({type:`oddin:load`,matchUrn:e}),on:e=>(i.add(e),()=>i.delete(e)),destroy:()=>{o({type:`oddin:destroy`}),window.removeEventListener(`message`,a),r.remove()}}}var df=/^[A-Za-z0-9:_.-]{1,128}$/;function ff(){let e=window.HAVIK_EMBED_CONFIG;if(e)return{baseUrl:e.baseUrl??``,matchUrn:e.matchUrn??``,apiKey:e.apiKey??``,parentOrigin:e.parentOrigin,autoplay:e.autoplay??!0,muted:e.muted??!0,waitForLive:e.waitForLive??!0};let t=new URLSearchParams(location.search);return{baseUrl:t.get(`baseUrl`)??``,matchUrn:t.get(`matchUrn`)??``,apiKey:t.get(`apiKey`)??``,parentOrigin:t.get(`parentOrigin`)??void 0,autoplay:!0,muted:t.get(`muted`)!==`false`,waitForLive:!0}}async function pf(){let e=ff();hf();let t=document.createElement(`video`);t.setAttribute(`playsinline`,``),t.muted=e.muted??!0,t.style.cssText=`width:100%;height:100%;object-fit:contain;background:#000;aspect-ratio:auto`,document.body.appendChild(t);let n=e.parentOrigin&&e.parentOrigin!==`null`?e.parentOrigin:null;n||console.warn(`havik-player: embed has no parentOrigin — the postMessage bridge is disabled (no events posted, no commands accepted). mountEmbed sets parentOrigin automatically.`);let r=e=>{if(n)try{window.parent?.postMessage(e,n)}catch{}};if(!e.baseUrl||!e.matchUrn||!e.apiKey){r({type:`oddin:error`,code:`INTERNAL`,message:`embed missing baseUrl/matchUrn/apiKey`});return}let i=null,o=e=>{e.on(`statechange`,e=>r({type:`oddin:state`,state:e})),e.on(`ready`,()=>r({type:`oddin:tracks`,quality:e.getQualityLevels(),audio:e.getAudioTracks(),text:e.getTextTracks()})),e.on(`waiting`,e=>r({type:`oddin:waiting`,retryInMs:e.retryInMs,attempt:e.attempt,phase:e.phase})),e.on(`qualitychange`,e=>r({type:`oddin:qualitychange`,index:e})),e.on(`audiotrackchange`,e=>r({type:`oddin:audiotrackchange`,id:e})),e.on(`texttrackchange`,e=>r({type:`oddin:texttrackchange`,id:e})),e.on(`stats`,e=>r({type:`oddin:stats`,droppedFrames:e.droppedFrames,latencySeconds:e.latencySeconds,bandwidthKbps:e.bandwidthKbps,levelHeight:e.levelHeight,lowLatency:e.lowLatency,isLive:e.isLive,atLiveEdge:e.atLiveEdge})),e.on(`error`,e=>r({type:`oddin:error`,code:e.code,message:e.message})),e.on(`autoplayblocked`,()=>{r({type:`oddin:autoplayblocked`}),mf(t,e)})},s=async n=>{i?.destroy(),i=null;try{let r=await sf({video:t,baseUrl:e.baseUrl,matchUrn:n,credential:{apiKey:e.apiKey},autoplay:e.autoplay,muted:e.muted,waitForLive:e.waitForLive});i=r;let a=t.parentElement;a?.classList.contains(`havik-player`)&&(a.style.cssText=`position:absolute;inset:0;width:100%;height:100%;aspect-ratio:auto`),o(r)}catch(e){let t=e instanceof a?e.code:`INTERNAL`,n=e instanceof Error?e.message:String(e);r({type:`oddin:error`,code:t,message:n})}},c=()=>{window.removeEventListener(`message`,u),window.removeEventListener(`pagehide`,c),i?.destroy(),i=null},l=e=>{switch(e.type){case`oddin:play`:i?.play();break;case`oddin:pause`:i?.pause();break;case`oddin:setMuted`:typeof e.muted==`boolean`&&i?.setMuted(e.muted);break;case`oddin:setVolume`:typeof e.volume==`number`&&Number.isFinite(e.volume)&&i?.setVolume(e.volume);break;case`oddin:setQuality`:typeof e.index==`number`&&i?.setQuality(e.index);break;case`oddin:setMaxBitrate`:(e.bitrate===null||typeof e.bitrate==`number`&&Number.isFinite(e.bitrate))&&i?.setMaxBitrate(e.bitrate);break;case`oddin:setAudioTrack`:typeof e.id==`number`&&i?.setAudioTrack(e.id);break;case`oddin:setTextTrack`:typeof e.id==`number`&&i?.setTextTrack(e.id);break;case`oddin:seekToLive`:i?.seekToLive();break;case`oddin:enterPip`:i?.enterPictureInPicture();break;case`oddin:exitPip`:i?.exitPictureInPicture();break;case`oddin:retry`:i?.retry();break;case`oddin:load`:typeof e.matchUrn==`string`&&df.test(e.matchUrn)&&s(e.matchUrn);break;case`oddin:destroy`:c();break}},u=e=>{!n||e.origin!==n||lf(e.data)&&l(e.data)};n&&window.addEventListener(`message`,u),window.addEventListener(`pagehide`,c,{once:!0}),await s(e.matchUrn),r({type:`oddin:ready`,protocol:1})}function mf(e,t){if(document.getElementById(`havik-tap`))return;let n=document.createElement(`button`);n.id=`havik-tap`,n.textContent=`▶ Tap to play`,n.style.cssText=`position:fixed;inset:0;width:100%;height:100%;border:0;background:rgba(0,0,0,.55);color:#fff;font:600 18px system-ui,sans-serif;cursor:pointer;z-index:9`,n.addEventListener(`click`,()=>{n.remove(),t.play()}),document.body.appendChild(n)}function hf(){let e=document.createElement(`style`);e.textContent=`html,body{margin:0;height:100%;background:#000;overflow:hidden}body{display:flex}`,document.head.appendChild(e)}return e.ODDIN_THEME=Rd,e.PlaybackError=a,e.applyTheme=Bd,e.bootEmbed=pf,e.clearDeviceId=ue,e.createPlayer=sf,e.deriveEventsBaseUrl=oe,e.fetchCatalog=N,e.fetchTournament=te,e.flattenMatches=re,e.getDeviceId=le,e.isLowLatencyManifest=me,e.isOddinMessage=lf,e.licenseRequestHeaders=fe,e.mountEmbed=uf,e.pollToLive=E,e.resolveStream=O,e.subscribeLiveState=ae,e.watchStatus=ie,e})({});
|
|
147
147
|
//# sourceMappingURL=havik-player.global.js.map
|