react-helios 2.0.0 → 2.1.0
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/README.md +74 -10
- package/dist/index.d.mts +59 -48
- package/dist/index.d.ts +59 -48
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +15 -9
- package/dist/styles.d.ts +1 -0
- package/package.json +11 -5
- package/dist/index.css +0 -2
- package/dist/index.css.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import it,{memo,useState,useMemo,useRef,useEffect,useCallback,forwardRef}from'react';import de,{Events}from'hls.js';import {jsx,jsxs}from'react/jsx-runtime';var _e=Object.defineProperty;var $e=(e,a)=>{for(var l in a)_e(e,l,{get:a[l],enumerable:true});};function K(e){if(!Number.isFinite(e)||e<0)return "0:00";let a=Math.floor(e),l=Math.floor(a/3600),f=Math.floor(a%3600/60),d=a%60;return l>0?`${l}:${String(f).padStart(2,"0")}:${String(d).padStart(2,"0")}`:`${f}:${String(d).padStart(2,"0")}`}function ce(e){try{return new URL(e,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(e)||/\/stream\.m3u8/i.test(e)}catch{return e.toLowerCase().includes(".m3u8")}}function Ue(e){if(ce(e))return "application/x-mpegURL";let a=e.toLowerCase().split("?")[0];return a.endsWith(".mp4")?"video/mp4":a.endsWith(".webm")?"video/webm":a.endsWith(".ogv")||a.endsWith(".ogg")?"video/ogg":a.endsWith(".mov")?"video/quicktime":"video/mp4"}function we(e){return e.map((a,l)=>({id:l,height:a.height??0,width:a.width??0,bitrate:a.bitrate??0,name:a.height?`${a.height}p`:`Level ${l+1}`}))}var Ke={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function Te(e,a,l={}){let f=useRef(null),d=useRef(null),h=useRef(1),v=useRef(0),u=useRef(l);u.current=l;let[g,s]=useState({...Ke,isMuted:l.muted??false,volume:l.muted?0:1}),B=useRef(g);B.current=g,useEffect(()=>{let t=e.current;if(!t||(f.current&&(f.current.destroy(),f.current=null),v.current=0,s(c=>({...c,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1})),!a))return;let n=u.current;if(n.enableHLS!==false&&ce(a)){if(t.canPlayType("application/vnd.apple.mpegurl"))t.src=a,t.load(),n.autoplay&&t.play().catch(()=>{});else if(de.isSupported()){let c=new de({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...n.hlsConfig});c.attachMedia(t),c.loadSource(a),c.on(Events.MANIFEST_PARSED,(z,E)=>{let i=we(E.levels);s(m=>({...m,qualityLevels:i,currentQualityLevel:-1})),u.current.autoplay&&t.play().catch(()=>{});}),c.on(Events.LEVEL_SWITCHED,(z,E)=>{s(i=>({...i,currentQualityLevel:E.level}));});let F=3;c.on(Events.ERROR,(z,E)=>{if(!E.fatal){console.warn("[hls] non-fatal:",E.details);return}switch(E.type){case de.ErrorTypes.NETWORK_ERROR:if(v.current<F){v.current+=1;let i=1e3*v.current;console.warn(`[hls] network error \u2013 retry ${v.current}/${F} in ${i}ms`),setTimeout(()=>{f.current===c&&c.startLoad();},i);}else {let i={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};s(m=>({...m,error:i})),u.current.onError?.(i);}break;case de.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),c.recoverMediaError();break;default:{c.destroy(),f.current=null;let i={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};s(m=>({...m,error:i})),u.current.onError?.(i);break}}}),f.current=c;}}else t.src=a,t.load(),n.autoplay&&t.play().catch(()=>{});return ()=>{f.current&&(f.current.destroy(),f.current=null);}},[a,e]),useEffect(()=>{let t=e.current;if(!t)return;u.current.muted&&(t.muted=true),u.current.loop&&(t.loop=true);let n=()=>{s(r=>({...r,isPlaying:true})),u.current.onPlay?.();},c=()=>{s(r=>({...r,isPlaying:false})),u.current.onPause?.();},F=()=>{s(r=>({...r,isPlaying:false})),u.current.onEnded?.();},z=()=>{s(r=>({...r,currentTime:t.currentTime})),u.current.onTimeUpdate?.(t.currentTime);},E=()=>{let r=t.duration,o=!Number.isFinite(r);s(b=>({...b,duration:o?0:r,isLive:o})),o||u.current.onDurationChange?.(r);},i=()=>{let r=t.volume;r>0&&!t.muted&&(h.current=r),s(o=>({...o,volume:r,isMuted:t.muted||r===0}));},m=()=>{s(r=>({...r,playbackRate:t.playbackRate}));},W=()=>{let r=t.error;if(!r)return;let b={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[r.code]??"UNKNOWN",message:r.message||"Unknown media error"};s(O=>({...O,error:b})),u.current.onError?.(b);},ee=()=>{s(r=>({...r,isBuffering:true})),u.current.onBuffering?.(true);},G=()=>{s(r=>({...r,isBuffering:false})),u.current.onBuffering?.(false);},Y=()=>s(r=>({...r,isBuffering:false})),j=()=>{let r=[];for(let o=0;o<t.buffered.length;o++)r.push({start:t.buffered.start(o),end:t.buffered.end(o)});s(o=>({...o,bufferedRanges:r}));},$=()=>{let r=!!(document.fullscreenElement||document.webkitFullscreenElement);s(o=>({...o,isFullscreen:r}));},Q=()=>{s(r=>({...r,isPictureInPicture:document.pictureInPictureElement===t}));};return t.addEventListener("play",n),t.addEventListener("pause",c),t.addEventListener("ended",F),t.addEventListener("timeupdate",z),t.addEventListener("durationchange",E),t.addEventListener("volumechange",i),t.addEventListener("ratechange",m),t.addEventListener("error",W),t.addEventListener("waiting",ee),t.addEventListener("canplay",G),t.addEventListener("playing",Y),t.addEventListener("progress",j),document.addEventListener("fullscreenchange",$),document.addEventListener("webkitfullscreenchange",$),t.addEventListener("enterpictureinpicture",Q),t.addEventListener("leavepictureinpicture",Q),()=>{t.removeEventListener("play",n),t.removeEventListener("pause",c),t.removeEventListener("ended",F),t.removeEventListener("timeupdate",z),t.removeEventListener("durationchange",E),t.removeEventListener("volumechange",i),t.removeEventListener("ratechange",m),t.removeEventListener("error",W),t.removeEventListener("waiting",ee),t.removeEventListener("canplay",G),t.removeEventListener("playing",Y),t.removeEventListener("progress",j),document.removeEventListener("fullscreenchange",$),document.removeEventListener("webkitfullscreenchange",$),t.removeEventListener("enterpictureinpicture",Q),t.removeEventListener("leavepictureinpicture",Q);}},[e]);let k=useCallback(async()=>{let t=e.current;if(t)try{await t.play();}catch(n){n instanceof Error&&n.name!=="AbortError"&&console.error("[player] play() failed:",n);}},[e]),x=useCallback(()=>{e.current?.pause();},[e]),H=useCallback(t=>{let n=e.current;n&&(n.currentTime=Math.max(0,Math.min(t,n.duration||t)));},[e]),p=useCallback(t=>{let n=e.current;if(!n)return;let c=Math.max(0,Math.min(t,1));c>0&&(h.current=c),n.volume=c,n.muted=c===0;},[e]),T=useCallback(()=>{let t=e.current;if(t)if(t.muted||t.volume===0){let n=h.current>0?h.current:1;t.volume=n,t.muted=false;}else h.current=t.volume,t.muted=true;},[e]),S=useCallback(t=>{let n=e.current;n&&(n.playbackRate=t);},[e]),y=useCallback(t=>{let n=f.current;n&&(n.currentLevel=t,s(c=>({...c,currentQualityLevel:t})));},[]),C=useCallback(()=>{let t=f.current,n=e.current;if(!t||!n)return;let c=t.liveSyncPosition;c!=null&&Number.isFinite(c)&&(n.currentTime=c);},[e]),N=useCallback(async()=>{let t=e.current;if(!t)return;let n=d.current??t.parentElement;if(n)try{!document.fullscreenElement&&!document.webkitFullscreenElement?n.requestFullscreen?await n.requestFullscreen():n.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(c){console.error("[player] fullscreen toggle failed:",c);}},[e]),P=useCallback(async()=>{let t=e.current;if(t)try{document.pictureInPictureElement?await document.exitPictureInPicture():await t.requestPictureInPicture();}catch(n){console.error("[player] PiP toggle failed:",n);}},[e]),_=useCallback(()=>({...B.current}),[]),L=useCallback(()=>e.current??null,[e]),M=useMemo(()=>({play:k,pause:x,seek:H,setVolume:p,toggleMute:T,setPlaybackRate:S,setQualityLevel:y,seekToLive:C,toggleFullscreen:N,togglePictureInPicture:P,getState:_,getVideoElement:L}),[k,x,H,p,T,S,y,C,N,P,_,L]);return {state:g,ref:M,hlsRef:f,fullscreenContainerRef:d}}var He={};$e(He,{ControlElements:()=>I,FullscreenButton:()=>ie,PauseButton:()=>ae,PiPButton:()=>se,PlayButton:()=>oe,ProgressBar:()=>fe,SettingsMenu:()=>ve,TimeDisplay:()=>ge,VolumeControl:()=>me});var oe=memo(({onClick:e})=>jsx("button",{onClick:e,className:"controlButton","aria-label":"Play",title:"Play (Space)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M8 5v14l11-7z"})})}));oe.displayName="PlayButton";var ae=memo(({onClick:e})=>jsx("button",{onClick:e,className:"controlButton","aria-label":"Pause",title:"Pause (Space)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}));ae.displayName="PauseButton";var ie=memo(({onClick:e,isFullscreen:a=false})=>jsx("button",{onClick:e,className:"controlButton","aria-label":a?"Exit Fullscreen":"Fullscreen",title:a?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:a?jsx("path",{d:"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"}):jsx("path",{d:"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"})})}));ie.displayName="FullscreenButton";var se=memo(({onClick:e,isPiP:a=false})=>jsx("button",{onClick:e,className:"controlButton","aria-label":a?"Exit Picture-in-Picture":"Picture-in-Picture",title:a?"Exit Picture-in-Picture (P)":"Picture-in-Picture (P)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V5h18v14.02z"})})}));se.displayName="PiPButton";var Se=memo(({volume:e,isMuted:a,onVolumeChange:l,onToggleMute:f})=>{let[d,h]=useState(false),v=a?0:e,u=v*100,g=useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${u}%, rgba(255,255,255,0.3) ${u}%, rgba(255,255,255,0.3) 100%)`,[u]);return jsxs("div",{className:"volumeContainer",onMouseEnter:()=>h(true),onMouseLeave:()=>h(false),children:[jsx("button",{onClick:f,className:"controlButton","aria-label":a?"Unmute":"Mute",title:a?"Unmute (M)":"Mute (M)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:v===0?jsx("path",{d:"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C23.16 14.42 24 13.3 24 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"}):v<.5?jsx("path",{d:"M7 9v6h4l5 5V4l-5 5H7z"}):jsx("path",{d:"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"})})}),d&&jsx("input",{type:"range",min:"0",max:"100",value:u,onChange:s=>l(Number(s.target.value)/100),className:"volumeSlider",style:{background:g},"aria-label":"Volume","aria-valuenow":Math.round(u)})]})});Se.displayName="VolumeControl";var me=Se;var Ce=memo(({playerRef:e,currentTime:a,duration:l,bufferedRanges:f,enablePreview:d=true})=>{let h=useRef(null),v=useRef(null),u=useRef(null),[g,s]=useState(false),[B,k]=useState(0),[x,H]=useState(0),[p,T]=useState(false),[S,y]=useState(false),C=useRef(null),N=useRef(0),P=useRef(null),_=useRef(false);_.current=g;let L=useRef(null);useEffect(()=>{let r=()=>{L.current=null;};return window.addEventListener("resize",r,{passive:true}),()=>window.removeEventListener("resize",r)},[]);let M=useCallback(()=>(!L.current&&h.current&&(L.current=h.current.getBoundingClientRect()),L.current),[]);useEffect(()=>{if(!d)return;let r=e.getVideoElement(),o=v.current;if(!r||!o)return;let b=r.currentSrc||r.src;if(!b)return;o.src=b,o.muted=true,o.preload="auto",o.crossOrigin=r.crossOrigin;let O=()=>y(true),te=()=>{console.warn("[preview] failed to load"),y(false);};return o.addEventListener("loadedmetadata",O),o.addEventListener("loadeddata",O),o.addEventListener("error",te),()=>{o.removeEventListener("loadedmetadata",O),o.removeEventListener("loadeddata",O),o.removeEventListener("error",te),o.removeAttribute("src"),o.load(),y(false);}},[e,d]),useEffect(()=>{let r=h.current;if(!r)return;let o=b=>{_.current&&b.preventDefault();};return r.addEventListener("touchmove",o,{passive:false}),()=>r.removeEventListener("touchmove",o)},[]);let t=useCallback(r=>{if(!d||!S)return;let o=v.current,b=u.current;if(!o||!b)return;let O=Date.now();if(O-N.current<100)return;N.current=O,C.current&&clearTimeout(C.current),P.current&&cancelAnimationFrame(P.current);let te=false,xe=()=>{te||o.readyState>=2&&(te=true,P.current&&cancelAnimationFrame(P.current),P.current=requestAnimationFrame(()=>{let Le=b.getContext("2d",{alpha:false,willReadFrequently:false});Le&&(b.width=160,b.height=90,Le.drawImage(o,0,0,160,90));}));};o.currentTime=r,o.addEventListener("seeked",xe,{once:true}),C.current=setTimeout(()=>{te||xe();},200);},[d,S]),n=useCallback(r=>{let o=M();return !o||o.width===0?0:Math.max(0,Math.min(r-o.left,o.width))/o.width*l},[M,l]),c=useCallback(r=>{let o=M();return o?Math.max(0,Math.min(r-o.left,o.width)):0},[M]),F=useCallback(r=>{switch(r.key){case "ArrowLeft":case "ArrowRight":{r.preventDefault(),r.nativeEvent.stopImmediatePropagation();let o=r.shiftKey?10:5,b=r.key==="ArrowLeft"?Math.max(0,a-o):Math.min(l||0,a+o);e.seek(b);break}case "Home":r.preventDefault(),r.nativeEvent.stopImmediatePropagation(),e.seek(0);break;case "End":l>0&&(r.preventDefault(),r.nativeEvent.stopImmediatePropagation(),e.seek(l));break}},[a,l,e]),z=useCallback(r=>{let o=n(r.clientX),b=c(r.clientX);k(o),H(b),g?e.seek(o):d&&S&&t(o);},[g,d,S,e,t,n,c]),E=useCallback(()=>{L.current=null,T(true);},[]),i=useCallback(()=>{T(false),s(false);},[]),m=useCallback(r=>{r.preventDefault(),s(true),e.seek(n(r.clientX));},[n,e]),W=useCallback(()=>s(false),[]),ee=useCallback(r=>{g||e.seek(n(r.clientX));},[g,n,e]),G=useCallback(r=>{L.current=null,s(true),e.seek(n(r.touches[0].clientX));},[n,e]),Y=useCallback(r=>{g&&e.seek(n(r.touches[0].clientX));},[g,n,e]),j=useCallback(()=>s(false),[]);useEffect(()=>{let r=()=>s(false);return window.addEventListener("mouseup",r),()=>window.removeEventListener("mouseup",r)},[]),useEffect(()=>()=>{C.current&&clearTimeout(C.current),P.current&&cancelAnimationFrame(P.current);},[]);let $=l>0?a/l*100:0,Q=useMemo(()=>l<=0?null:f.map((r,o)=>{let b=r.start/l*100,O=(r.end-r.start)/l*100;return jsx("div",{className:"bufferedSegment",style:{left:`${b}%`,width:`${O}%`}},o)}),[f,l]);return jsxs("div",{ref:h,className:"progressContainer",onMouseMove:z,onMouseEnter:E,onMouseLeave:i,onMouseDown:m,onMouseUp:W,onClick:ee,onTouchStart:G,onTouchMove:Y,onTouchEnd:j,onKeyDown:F,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":Math.round(l),"aria-valuenow":Math.round(a),"aria-valuetext":K(a),tabIndex:0,children:[d&&jsx("video",{ref:v,className:"previewVideo",playsInline:true,muted:true,preload:"auto","aria-hidden":"true"}),d&&p&&S&&jsxs("div",{className:"previewTooltip",style:{left:x},"aria-hidden":"true",children:[jsx("canvas",{ref:u,className:"previewCanvas"}),jsx("div",{className:"previewTime",children:K(B)})]}),jsxs("div",{className:"progressBackground",children:[Q,jsx("div",{className:"progressFilled",style:{width:`${$}%`}}),p&&jsx("div",{className:"hoverIndicator",style:{left:x},"aria-hidden":"true"})]}),jsx("div",{className:`scrubHandle${g?" dragging":""}`,style:{left:`${$}%`},"aria-hidden":"true"})]})});Ce.displayName="ProgressBar";var fe=Ce;var Be=memo(({currentRate:e,playbackRates:a,onRateChange:l,qualityLevels:f=[],currentQualityLevel:d=-1,onQualityChange:h})=>{let[v,u]=useState(false),[g,s]=useState("speed"),B=useRef(null),k=f.length>0&&!!h;useEffect(()=>{let p=T=>{B.current&&!B.current.contains(T.target)&&u(false);};return v&&document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[v]);let x=useMemo(()=>[...f].sort((p,T)=>T.bitrate-p.bitrate),[f]),H=useMemo(()=>d===-1?"Auto":f.find(p=>p.id===d)?.name??"Auto",[f,d]);return jsxs("div",{ref:B,className:"settingsContainer",children:[jsx("button",{onClick:()=>u(p=>!p),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":v,children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19.14 12.94c.04-.3.06-.61.06-.94s-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96a7.02 7.02 0 0 0-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54a6.88 6.88 0 0 0-1.61.94l-2.39-.96a.488.488 0 0 0-.59.22L2.74 8.87a.48.48 0 0 0 .12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.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.54a6.88 6.88 0 0 0 1.61-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32a.47.47 0 0 0-.12-.61l-2.01-1.58zM12 15.6A3.6 3.6 0 0 1 8.4 12 3.6 3.6 0 0 1 12 8.4a3.6 3.6 0 0 1 3.6 3.6 3.6 3.6 0 0 1-3.6 3.6z"})})}),v&&jsxs("div",{className:"settingsDropdown",role:"menu",children:[k&&jsxs("div",{className:"settingsTabs",children:[jsx("button",{className:`settingsTab${g==="speed"?" active":""}`,onClick:()=>s("speed"),children:"Speed"}),jsx("button",{className:`settingsTab${g==="quality"?" active":""}`,onClick:()=>s("quality"),children:"Quality"})]}),(!k||g==="speed")&&jsxs("div",{children:[!k&&jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),a.map(p=>jsx("button",{onClick:()=>{l(p),u(false);},className:`settingsOption${e===p?" active":""}`,role:"menuitemradio","aria-checked":e===p,children:p===1?"Normal":`${p}\xD7`},p))]}),k&&g==="quality"&&jsxs("div",{children:[jsxs("button",{onClick:()=>{h(-1),u(false);},className:`settingsOption${d===-1?" active":""}`,role:"menuitemradio","aria-checked":d===-1,children:["Auto ",d===-1&&H!=="Auto"?`(${H})`:""]}),x.map(p=>jsxs("button",{onClick:()=>{h(p.id),u(false);},className:`settingsOption${d===p.id?" active":""}`,role:"menuitemradio","aria-checked":d===p.id,children:[p.name,p.bitrate>0&&jsxs("span",{className:"settingsOptionBadge",children:[Math.round(p.bitrate/1e3)," kbps"]})]},p.id))]})]})]})});Be.displayName="SettingsMenu";var ve=Be;var Ve=memo(({currentTime:e,duration:a,isLive:l=false})=>l?jsx("span",{className:"timeDisplay",style:{opacity:.7},children:K(e)}):jsxs("span",{className:"timeDisplay",children:[K(e),jsxs("span",{style:{opacity:.6},children:[" / ",K(a)]})]}));Ve.displayName="TimeDisplay";var ge=Ve;var I={PlayButton:oe,PauseButton:ae,FullscreenButton:ie,PiPButton:se,VolumeControl:me,ProgressBar:fe,SettingsMenu:ve,TimeDisplay:ge};var Ee=({playerRef:e,playerContainerRef:a,playbackRates:l,enablePreview:f,isPlaying:d,currentTime:h,duration:v,volume:u,isMuted:g,playbackRate:s,isFullscreen:B,isPictureInPicture:k,isLive:x,qualityLevels:H,currentQualityLevel:p,bufferedRanges:T})=>{let S=useRef(null),y=useRef(null),[C,N]=useState(true),P=useRef({isPlaying:d,currentTime:h,duration:v,volume:u,isMuted:g,isLive:x});P.current={isPlaying:d,currentTime:h,duration:v,volume:u,isMuted:g,isLive:x},useEffect(()=>{if(!d){N(true),y.current&&clearTimeout(y.current);return}let i=()=>{N(true),y.current&&clearTimeout(y.current),y.current=setTimeout(()=>N(false),3e3);},m=S.current;return m&&(m.addEventListener("mousemove",i),m.addEventListener("mouseenter",i),m.addEventListener("touchstart",i,{passive:true})),i(),()=>{m&&(m.removeEventListener("mousemove",i),m.removeEventListener("mouseenter",i),m.removeEventListener("touchstart",i)),y.current&&clearTimeout(y.current);}},[d]),useEffect(()=>{let i=m=>{if(!a.current?.contains(document.activeElement))return;let W=m.target;if(W.tagName==="INPUT"||W.tagName==="TEXTAREA"||W.isContentEditable)return;let{isPlaying:ee,currentTime:G,duration:Y,volume:j,isLive:$}=P.current;switch(m.code){case "Space":case "KeyK":m.preventDefault(),ee?e.pause():e.play();break;case "ArrowLeft":m.preventDefault(),e.seek(Math.max(0,G-5));break;case "ArrowRight":m.preventDefault(),e.seek(Math.min(Y||1/0,G+5));break;case "ArrowUp":m.preventDefault(),e.setVolume(Math.min(1,j+.1));break;case "ArrowDown":m.preventDefault(),e.setVolume(Math.max(0,j-.1));break;case "KeyM":m.preventDefault(),e.toggleMute();break;case "KeyF":m.preventDefault(),e.toggleFullscreen();break;case "KeyP":m.preventDefault(),e.togglePictureInPicture();break;case "KeyL":m.preventDefault(),$&&e.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{m.preventDefault();let Q=Number(m.code.replace("Digit",""))*10;e.seek(Y/100*Q);break}}};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[e,a]);let _=useCallback(()=>e.play(),[e]),L=useCallback(()=>e.pause(),[e]),M=useCallback(i=>e.setVolume(i),[e]),t=useCallback(()=>e.toggleMute(),[e]),n=useCallback(i=>e.setPlaybackRate(i),[e]),c=useCallback(i=>e.setQualityLevel(i),[e]),F=useCallback(()=>e.togglePictureInPicture(),[e]),z=useCallback(()=>e.toggleFullscreen(),[e]),E=useCallback(()=>e.seekToLive(),[e]);return jsx("div",{ref:S,style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:C?1:0,transition:"opacity 0.3s",pointerEvents:C?"auto":"none"},children:jsxs("div",{style:{background:"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)",padding:"48px 12px 12px"},role:"region","aria-label":"Video player controls",children:[jsx(I.ProgressBar,{playerRef:e,currentTime:h,duration:v,bufferedRanges:T,enablePreview:f}),jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[d?jsx(I.PauseButton,{onClick:L}):jsx(I.PlayButton,{onClick:_}),jsx(I.VolumeControl,{volume:u,isMuted:g,onVolumeChange:M,onToggleMute:t}),jsx(I.TimeDisplay,{currentTime:h,duration:v,isLive:x}),jsx("div",{style:{flex:1}}),x&&jsx(ze,{onClick:E}),jsx(I.SettingsMenu,{currentRate:s,playbackRates:l,onRateChange:n,qualityLevels:H,currentQualityLevel:p,onQualityChange:c}),jsx(I.PiPButton,{onClick:F,isPiP:k}),jsx(I.FullscreenButton,{onClick:z,isFullscreen:B})]})]})})},ze=memo(({onClick:e})=>jsx("button",{onClick:e,style:{background:"none",border:"1px solid rgba(255,255,255,0.6)",color:"#fff",borderRadius:3,padding:"2px 8px",fontSize:11,fontWeight:700,cursor:"pointer",letterSpacing:"0.06em"},title:"Go to live (L)",children:"GO LIVE"}));ze.displayName="GoLiveButton";var Ae=forwardRef(({src:e,poster:a,autoplay:l=false,muted:f=false,loop:d=false,controls:h=true,preload:v="metadata",playbackRates:u=[.25,.5,.75,1,1.25,1.5,1.75,2],className:g,enableHLS:s=true,enablePreview:B=true,hlsConfig:k,subtitles:x,crossOrigin:H,onPlay:p,onPause:T,onEnded:S,onError:y,onTimeUpdate:C,onDurationChange:N,onBuffering:P},_)=>{let L=useRef(null),M=useRef(null),{state:t,ref:n,fullscreenContainerRef:c}=Te(L,e,{autoplay:l,muted:f,loop:d,playbackRates:u,enableHLS:s,hlsConfig:k,onPlay:p,onPause:T,onEnded:S,onError:y,onTimeUpdate:C,onDurationChange:N,onBuffering:P});useEffect(()=>{c.current=M.current;},[c]),it.useImperativeHandle(_,()=>n,[n]);let F=useCallback(()=>{M.current?.focus(),t.isPlaying?n.pause():n.play();},[t.isPlaying,n]),z=useCallback(()=>{n.toggleFullscreen();},[n]),E=useMemo(()=>s&&!!e&&e.toLowerCase().includes(".m3u8"),[s,e]);return jsxs("div",{ref:M,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:g,"data-test":"video-player-container",children:[jsx("video",{ref:L,poster:a,preload:v,crossOrigin:H,onClick:F,onDoubleClick:z,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer"},"data-test":"video-element",children:x?.map(i=>jsx("track",{kind:"subtitles",src:i.src,label:i.label,srcLang:i.srclang,default:i.default},i.id))}),h&&jsx(Ee,{playerRef:n,playerContainerRef:M,playbackRates:u,enablePreview:B&&!E,isPlaying:t.isPlaying,currentTime:t.currentTime,duration:t.duration,volume:t.volume,isMuted:t.isMuted,playbackRate:t.playbackRate,isFullscreen:t.isFullscreen,isPictureInPicture:t.isPictureInPicture,isLive:t.isLive,qualityLevels:t.qualityLevels,currentQualityLevel:t.currentQualityLevel,bufferedRanges:t.bufferedRanges}),t.isLive&&jsx("div",{style:{position:"absolute",top:12,left:12,backgroundColor:"#e53935",color:"#fff",fontSize:11,fontWeight:700,letterSpacing:"0.08em",padding:"2px 8px",borderRadius:3,pointerEvents:"none"},children:"LIVE"}),t.isBuffering&&!t.error&&jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:12,color:"#fff",pointerEvents:"none"},"data-test":"buffering-indicator",children:[jsx("div",{style:{width:48,height:48,border:"4px solid rgba(255,255,255,0.25)",borderTop:"4px solid #fff",borderRadius:"50%",animation:"rvp-spin 0.8s linear infinite"}}),jsx("style",{children:"@keyframes rvp-spin { to { transform: rotate(360deg); } }"})]}),t.error&&jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0,0,0,0.85)",color:"#fff",padding:24},"data-test":"error-overlay",children:jsxs("div",{style:{textAlign:"center",maxWidth:400},children:[jsx("div",{style:{fontSize:36,marginBottom:12},children:"\u26A0"}),jsx("h3",{style:{margin:"0 0 8px",fontSize:18},children:t.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":t.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:t.error.message})]})})]})});Ae.displayName="VideoPlayer";var ct=Ae;
|
|
2
|
-
|
|
1
|
+
import ct,{memo,useState,useMemo,useRef,useEffect,useCallback,forwardRef}from'react';import ue,{Events}from'hls.js';import {jsx,jsxs}from'react/jsx-runtime';var $e=Object.defineProperty;var Ue=(r,e)=>{for(var m in e)$e(r,m,{get:e[m],enumerable:true});};function j(r){if(!Number.isFinite(r)||r<0)return "0:00";let e=Math.floor(r),m=Math.floor(e/3600),s=Math.floor(e%3600/60),a=e%60;return m>0?`${m}:${String(s).padStart(2,"0")}:${String(a).padStart(2,"0")}`:`${s}:${String(a).padStart(2,"0")}`}function le(r){try{return new URL(r,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(r)||/\/stream\.m3u8/i.test(r)}catch{return r.toLowerCase().includes(".m3u8")}}function We(r){if(le(r))return "application/x-mpegURL";let e=r.toLowerCase().split("?")[0];return e.endsWith(".mp4")?"video/mp4":e.endsWith(".webm")?"video/webm":e.endsWith(".ogv")||e.endsWith(".ogg")?"video/ogg":e.endsWith(".mov")?"video/quicktime":"video/mp4"}function Te(r){return r.map((e,m)=>({id:m,height:e.height??0,width:e.width??0,bitrate:e.bitrate??0,name:e.height?`${e.height}p`:`Level ${m+1}`}))}var qe={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function Me(r,e,m={}){let s=useRef(null),a=useRef(null),h=useRef(1),f=useRef(0),l=useRef(m);l.current=m;let[b,d]=useState({...qe,isMuted:m.muted??false,volume:m.muted?0:1}),P=useRef(b);P.current=b,useEffect(()=>{let t=r.current;if(!t||(s.current&&(s.current.destroy(),s.current=null),f.current=0,d(c=>({...c,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1})),!e))return;let o=l.current;if(o.enableHLS!==false&&le(e)){if(t.canPlayType("application/vnd.apple.mpegurl"))t.src=e,t.load(),o.autoplay&&t.play().catch(()=>{});else if(ue.isSupported()){let c=new ue({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...o.hlsConfig});c.attachMedia(t),c.loadSource(e),c.on(Events.MANIFEST_PARSED,(I,g)=>{let u=Te(g.levels);d(R=>({...R,qualityLevels:u,currentQualityLevel:-1})),l.current.autoplay&&t.play().catch(()=>{});}),c.on(Events.LEVEL_SWITCHED,(I,g)=>{d(u=>({...u,currentQualityLevel:g.level}));});let M=3;c.on(Events.ERROR,(I,g)=>{if(!g.fatal){console.warn("[hls] non-fatal:",g.details);return}switch(g.type){case ue.ErrorTypes.NETWORK_ERROR:if(f.current<M){f.current+=1;let u=1e3*f.current;console.warn(`[hls] network error \u2013 retry ${f.current}/${M} in ${u}ms`),setTimeout(()=>{s.current===c&&c.startLoad();},u);}else {let u={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};d(R=>({...R,error:u})),l.current.onError?.(u);}break;case ue.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),c.recoverMediaError();break;default:{c.destroy(),s.current=null;let u={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};d(R=>({...R,error:u})),l.current.onError?.(u);break}}}),s.current=c;}}else t.src=e,t.load(),o.autoplay&&t.play().catch(()=>{});return ()=>{s.current&&(s.current.destroy(),s.current=null);}},[e,r]),useEffect(()=>{let t=r.current;if(!t)return;l.current.muted&&(t.muted=true),l.current.loop&&(t.loop=true);let o=()=>{d(n=>({...n,isPlaying:true})),l.current.onPlay?.();},c=()=>{d(n=>({...n,isPlaying:false})),l.current.onPause?.();},M=()=>{d(n=>({...n,isPlaying:false})),l.current.onEnded?.();},I=()=>{l.current.onTimeUpdate?.(t.currentTime);},g=()=>{let n=t.duration,p=!Number.isFinite(n);d(y=>({...y,duration:p?0:n,isLive:p})),p||l.current.onDurationChange?.(n);},u=()=>{let n=t.volume;n>0&&!t.muted&&(h.current=n),d(p=>({...p,volume:n,isMuted:t.muted||n===0}));},R=()=>{d(n=>({...n,playbackRate:t.playbackRate}));},Y=()=>{let n=t.error;if(!n)return;let y={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[n.code]??"UNKNOWN",message:n.message||"Unknown media error"};d(U=>({...U,error:y})),l.current.onError?.(y);},q=()=>{d(n=>({...n,isBuffering:true})),l.current.onBuffering?.(true);},Z=()=>{d(n=>({...n,isBuffering:false})),l.current.onBuffering?.(false);},X=()=>d(n=>({...n,isBuffering:false})),G=()=>{},Q=()=>{let n=!!(document.fullscreenElement||document.webkitFullscreenElement);d(p=>({...p,isFullscreen:n}));},i=()=>{d(n=>({...n,isPictureInPicture:document.pictureInPictureElement===t}));};return t.addEventListener("play",o),t.addEventListener("pause",c),t.addEventListener("ended",M),t.addEventListener("timeupdate",I),t.addEventListener("durationchange",g),t.addEventListener("volumechange",u),t.addEventListener("ratechange",R),t.addEventListener("error",Y),t.addEventListener("waiting",q),t.addEventListener("canplay",Z),t.addEventListener("playing",X),t.addEventListener("progress",G),document.addEventListener("fullscreenchange",Q),document.addEventListener("webkitfullscreenchange",Q),t.addEventListener("enterpictureinpicture",i),t.addEventListener("leavepictureinpicture",i),()=>{t.removeEventListener("play",o),t.removeEventListener("pause",c),t.removeEventListener("ended",M),t.removeEventListener("timeupdate",I),t.removeEventListener("durationchange",g),t.removeEventListener("volumechange",u),t.removeEventListener("ratechange",R),t.removeEventListener("error",Y),t.removeEventListener("waiting",q),t.removeEventListener("canplay",Z),t.removeEventListener("playing",X),t.removeEventListener("progress",G),document.removeEventListener("fullscreenchange",Q),document.removeEventListener("webkitfullscreenchange",Q),t.removeEventListener("enterpictureinpicture",i),t.removeEventListener("leavepictureinpicture",i);}},[r]);let T=useCallback(async()=>{let t=r.current;if(t)try{await t.play();}catch(o){o instanceof Error&&o.name!=="AbortError"&&console.error("[player] play() failed:",o);}},[r]),C=useCallback(()=>{r.current?.pause();},[r]),E=useCallback(t=>{let o=r.current;o&&(o.currentTime=Math.max(0,Math.min(t,o.duration||t)));},[r]),v=useCallback(t=>{let o=r.current;if(!o)return;let c=Math.max(0,Math.min(t,1));c>0&&(h.current=c),o.volume=c,o.muted=c===0;},[r]),w=useCallback(()=>{let t=r.current;if(t)if(t.muted||t.volume===0){let o=h.current>0?h.current:1;t.volume=o,t.muted=false;}else h.current=t.volume,t.muted=true;},[r]),L=useCallback(t=>{let o=r.current;o&&(o.playbackRate=t);},[r]),D=useCallback(t=>{let o=s.current;o&&(o.currentLevel=t,d(c=>({...c,currentQualityLevel:t})));},[]),x=useCallback(()=>{let t=s.current,o=r.current;if(!t||!o)return;let c=t.liveSyncPosition;c!=null&&Number.isFinite(c)&&(o.currentTime=c);},[r]),V=useCallback(async()=>{let t=r.current;if(!t)return;let o=a.current??t.parentElement;if(o)try{!document.fullscreenElement&&!document.webkitFullscreenElement?o.requestFullscreen?await o.requestFullscreen():o.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(c){console.error("[player] fullscreen toggle failed:",c);}},[r]),O=useCallback(async()=>{let t=r.current;if(t)try{document.pictureInPictureElement?await document.exitPictureInPicture():await t.requestPictureInPicture();}catch(o){console.error("[player] PiP toggle failed:",o);}},[r]),S=useCallback(()=>{let t=r.current,o=t?.currentTime??0,c=[];if(t)for(let M=0;M<t.buffered.length;M++)c.push({start:t.buffered.start(M),end:t.buffered.end(M)});return {...P.current,currentTime:o,bufferedRanges:c}},[r]),$=useCallback(()=>r.current??null,[r]),A=useMemo(()=>({play:T,pause:C,seek:E,setVolume:v,toggleMute:w,setPlaybackRate:L,setQualityLevel:D,seekToLive:x,toggleFullscreen:V,togglePictureInPicture:O,getState:S,getVideoElement:$}),[T,C,E,v,w,L,D,x,V,O,S,$]);return {state:b,ref:A,hlsRef:s,fullscreenContainerRef:a}}var Ve={};Ue(Ve,{ControlElements:()=>z,FullscreenButton:()=>ae,PauseButton:()=>ie,PiPButton:()=>se,PlayButton:()=>oe,ProgressBar:()=>me,SettingsMenu:()=>pe,TimeDisplay:()=>ve,VolumeControl:()=>de});var oe=memo(({onClick:r})=>jsx("button",{onClick:r,className:"controlButton","aria-label":"Play",title:"Play (Space)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M8 5v14l11-7z"})})}));oe.displayName="PlayButton";var ie=memo(({onClick:r})=>jsx("button",{onClick:r,className:"controlButton","aria-label":"Pause",title:"Pause (Space)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}));ie.displayName="PauseButton";var ae=memo(({onClick:r,isFullscreen:e=false})=>jsx("button",{onClick:r,className:"controlButton","aria-label":e?"Exit Fullscreen":"Fullscreen",title:e?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:e?jsx("path",{d:"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"}):jsx("path",{d:"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"})})}));ae.displayName="FullscreenButton";var se=memo(({onClick:r,isPiP:e=false})=>jsx("button",{onClick:r,className:"controlButton","aria-label":e?"Exit Picture-in-Picture":"Picture-in-Picture",title:e?"Exit Picture-in-Picture (P)":"Picture-in-Picture (P)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V5h18v14.02z"})})}));se.displayName="PiPButton";var Ce=memo(({volume:r,isMuted:e,onVolumeChange:m,onToggleMute:s})=>{let[a,h]=useState(false),f=e?0:r,l=f*100,b=useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${l}%, rgba(255,255,255,0.3) ${l}%, rgba(255,255,255,0.3) 100%)`,[l]);return jsxs("div",{className:"volumeContainer",onMouseEnter:()=>h(true),onMouseLeave:()=>h(false),children:[jsx("button",{onClick:s,className:"controlButton","aria-label":e?"Unmute":"Mute",title:e?"Unmute (M)":"Mute (M)",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:f===0?jsx("path",{d:"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C23.16 14.42 24 13.3 24 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"}):f<.5?jsx("path",{d:"M7 9v6h4l5 5V4l-5 5H7z"}):jsx("path",{d:"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"})})}),a&&jsx("input",{type:"range",min:"0",max:"100",value:l,onChange:d=>m(Number(d.target.value)/100),className:"volumeSlider",style:{background:b},"aria-label":"Volume","aria-valuenow":Math.round(l)})]})});Ce.displayName="VolumeControl";var de=Ce;function we(r){let e=r.trim().split(":");return e.length===3?+e[0]*3600+ +e[1]*60+parseFloat(e[2]):+e[0]*60+parseFloat(e[1])}function Ye(r,e){if(/^https?:\/\//i.test(e))return e;try{return new URL(e,r).href}catch{return e}}function ge(r,e=""){let m=[],s=r.replace(/\r\n/g,`
|
|
2
|
+
`).split(`
|
|
3
|
+
`),a=0;for(;a<s.length;){let h=s[a].trim();if(h.includes("-->")){let f=h.indexOf("-->"),l=we(h.slice(0,f)),b=we(h.slice(f+3));for(a++;a<s.length&&!s[a].trim();)a++;if(a<s.length){let d=s[a].trim(),P=d.lastIndexOf("#xywh="),T=d,C=0,E=0,v=160,w=90;if(P!==-1){T=d.slice(0,P);let L=d.slice(P+6).split(",").map(Number);C=L[0]??0,E=L[1]??0,v=L[2]??160,w=L[3]??90;}m.push({start:l,end:b,url:Ye(e,T),x:C,y:E,w:v,h:w});}}a++;}return m}function be(r,e){if(!r.length)return null;let m=0,s=r.length-1;for(;m<=s;){let a=m+s>>1;if(r[a].end<=e)m=a+1;else if(r[a].start>e)s=a-1;else return r[a]}return null}var xe=memo(({videoRef:r,playerRef:e,enablePreview:m=true,thumbnailVtt:s})=>{let a=useRef(null),h=useRef(null),f=useRef(null),l=useRef(null),b=useRef(null),d=useRef(null),P=useRef(null),[T,C]=useState([]),E=useRef(false),v=useRef(0),w=useRef(0),L=useRef(null),D=useRef([]),x=useRef(null);useEffect(()=>{let i=()=>{x.current=null;};return window.addEventListener("resize",i,{passive:true}),()=>window.removeEventListener("resize",i)},[]);let V=useCallback(()=>(!x.current&&a.current&&(x.current=a.current.getBoundingClientRect()),x.current),[]);useEffect(()=>{if(!s){D.current=[];return}let i=false;return fetch(s).then(n=>n.text()).then(n=>{i||(D.current=ge(n,s));}).catch(()=>{i||(D.current=[]);}),()=>{i=true;}},[s]),useEffect(()=>{let i=r.current;if(!i)return;let n=()=>{let p=isFinite(i.duration)?i.duration:0,y=i.currentTime,U=p>0?y/p*100:0;h.current&&(h.current.style.width=`${U}%`),f.current&&(f.current.style.left=`${U}%`),a.current&&(a.current.setAttribute("aria-valuenow",String(Math.round(y))),a.current.setAttribute("aria-valuemax",String(Math.round(p))),a.current.setAttribute("aria-valuetext",j(y)));};return i.addEventListener("timeupdate",n),i.addEventListener("durationchange",n),i.addEventListener("seeked",n),n(),()=>{i.removeEventListener("timeupdate",n),i.removeEventListener("durationchange",n),i.removeEventListener("seeked",n);}},[r]),useEffect(()=>{let i=r.current;if(!i)return;let n=()=>{let p=[];for(let y=0;y<i.buffered.length;y++)p.push({start:i.buffered.start(y),end:i.buffered.end(y)});C(p);};return i.addEventListener("progress",n),()=>i.removeEventListener("progress",n)},[r]);let O=useCallback(()=>{E.current=true,f.current?.classList.add("dragging");},[]),S=useCallback(()=>{E.current=false,f.current?.classList.remove("dragging");},[]),$=useCallback(()=>{m&&(x.current=null,l.current&&(l.current.style.display=""),d.current&&(d.current.style.display=""));},[m]),A=useCallback(()=>{l.current&&(l.current.style.display="none"),d.current&&(d.current.style.display="none");},[]),t=useCallback(i=>{if(!P.current||!D.current.length)return;let n=be(D.current,i);if(L.current=n,!n)return;let p=P.current;p.style.backgroundImage=`url(${n.url})`,p.style.backgroundPosition=`-${n.x}px -${n.y}px`,p.style.width=`${n.w}px`,p.style.height=`${n.h}px`;},[]),o=useCallback(i=>{let n=V(),p=r.current?.duration;return !n||n.width===0||!p||!isFinite(p)?0:Math.max(0,Math.min(i-n.left,n.width))/n.width*p},[V,r]),c=useCallback(i=>{let n=V();return n?Math.max(0,Math.min(i-n.left,n.width)):0},[V]),M=useCallback(i=>{let n=r.current;if(!n)return;let p=n.currentTime,y=isFinite(n.duration)?n.duration:0;switch(i.key){case "ArrowLeft":case "ArrowRight":{i.preventDefault(),i.nativeEvent.stopImmediatePropagation();let U=i.shiftKey?10:5;e.seek(i.key==="ArrowLeft"?Math.max(0,p-U):Math.min(y,p+U));break}case "Home":i.preventDefault(),i.nativeEvent.stopImmediatePropagation(),e.seek(0);break;case "End":y>0&&(i.preventDefault(),i.nativeEvent.stopImmediatePropagation(),e.seek(y));break}},[r,e]),I=useCallback(i=>{let n=o(i.clientX),p=c(i.clientX);v.current=p,w.current=n,l.current&&(l.current.style.left=`${p}px`),d.current&&(d.current.style.left=`${p}px`),b.current&&(b.current.textContent=j(n)),t(n),E.current&&e.seek(n);},[e,t,o,c]),g=useCallback(()=>{$();},[$]),u=useCallback(()=>{A(),S();},[A,S]),R=useCallback(i=>{i.preventDefault(),O(),e.seek(o(i.clientX));},[O,o,e]),Y=useCallback(()=>S(),[S]),q=useCallback(i=>{E.current||e.seek(o(i.clientX));},[o,e]);useEffect(()=>{let i=a.current;if(!i)return;let n=p=>{E.current&&p.preventDefault();};return i.addEventListener("touchmove",n,{passive:false}),()=>i.removeEventListener("touchmove",n)},[]);let Z=useCallback(i=>{x.current=null,O(),e.seek(o(i.touches[0].clientX));},[O,o,e]),X=useCallback(i=>{E.current&&e.seek(o(i.touches[0].clientX));},[o,e]),G=useCallback(()=>S(),[S]);useEffect(()=>{let i=()=>S();return window.addEventListener("mouseup",i),()=>window.removeEventListener("mouseup",i)},[S]);let Q=useMemo(()=>{let i=r.current,n=i&&isFinite(i.duration)?i.duration:0;return n<=0||!T.length?null:T.map((p,y)=>{let U=p.start/n*100,_e=(p.end-p.start)/n*100;return jsx("div",{className:"bufferedSegment",style:{left:`${U}%`,width:`${_e}%`}},y)})},[T,r]);return jsxs("div",{ref:a,className:"progressContainer",onMouseMove:I,onMouseEnter:g,onMouseLeave:u,onMouseDown:R,onMouseUp:Y,onClick:q,onTouchStart:Z,onTouchMove:X,onTouchEnd:G,onKeyDown:M,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[m&&jsxs("div",{ref:l,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[s&&jsx("div",{ref:P,className:"previewThumbnail"}),jsx("div",{ref:b,className:"previewTime"})]}),jsxs("div",{className:"progressBackground",children:[Q,jsx("div",{ref:h,className:"progressFilled",style:{width:"0%"}}),m&&jsx("div",{ref:d,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsx("div",{ref:f,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})});xe.displayName="ProgressBar";var me=xe;var De=memo(({currentRate:r,playbackRates:e,onRateChange:m,qualityLevels:s=[],currentQualityLevel:a=-1,onQualityChange:h})=>{let[f,l]=useState(false),[b,d]=useState("speed"),P=useRef(null),T=s.length>0&&!!h;useEffect(()=>{let v=w=>{P.current&&!P.current.contains(w.target)&&l(false);};return f&&document.addEventListener("mousedown",v),()=>document.removeEventListener("mousedown",v)},[f]);let C=useMemo(()=>[...s].sort((v,w)=>w.bitrate-v.bitrate),[s]),E=useMemo(()=>a===-1?"Auto":s.find(v=>v.id===a)?.name??"Auto",[s,a]);return jsxs("div",{ref:P,className:"settingsContainer",children:[jsx("button",{onClick:()=>l(v=>!v),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":f,children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19.14 12.94c.04-.3.06-.61.06-.94s-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96a7.02 7.02 0 0 0-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54a6.88 6.88 0 0 0-1.61.94l-2.39-.96a.488.488 0 0 0-.59.22L2.74 8.87a.48.48 0 0 0 .12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.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.54a6.88 6.88 0 0 0 1.61-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32a.47.47 0 0 0-.12-.61l-2.01-1.58zM12 15.6A3.6 3.6 0 0 1 8.4 12 3.6 3.6 0 0 1 12 8.4a3.6 3.6 0 0 1 3.6 3.6 3.6 3.6 0 0 1-3.6 3.6z"})})}),f&&jsxs("div",{className:"settingsDropdown",role:"menu",children:[T&&jsxs("div",{className:"settingsTabs",children:[jsx("button",{className:`settingsTab${b==="speed"?" active":""}`,onClick:()=>d("speed"),children:"Speed"}),jsx("button",{className:`settingsTab${b==="quality"?" active":""}`,onClick:()=>d("quality"),children:"Quality"})]}),(!T||b==="speed")&&jsxs("div",{children:[!T&&jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),e.map(v=>jsx("button",{onClick:()=>{m(v),l(false);},className:`settingsOption${r===v?" active":""}`,role:"menuitemradio","aria-checked":r===v,children:v===1?"Normal":`${v}\xD7`},v))]}),T&&b==="quality"&&jsxs("div",{children:[jsxs("button",{onClick:()=>{h(-1),l(false);},className:`settingsOption${a===-1?" active":""}`,role:"menuitemradio","aria-checked":a===-1,children:["Auto ",a===-1&&E!=="Auto"?`(${E})`:""]}),C.map(v=>jsxs("button",{onClick:()=>{h(v.id),l(false);},className:`settingsOption${a===v.id?" active":""}`,role:"menuitemradio","aria-checked":a===v.id,children:[v.name,v.bitrate>0&&jsxs("span",{className:"settingsOptionBadge",children:[Math.round(v.bitrate/1e3)," kbps"]})]},v.id))]})]})]})});De.displayName="SettingsMenu";var pe=De;var He=memo(({videoRef:r,isLive:e=false})=>{let m=useRef(null),s=useRef(null);return useEffect(()=>{let a=r.current;if(!a)return;let h=()=>{m.current&&(m.current.textContent=j(a.currentTime));},f=()=>{if(s.current){let l=isFinite(a.duration)?a.duration:0;s.current.textContent=` / ${j(l)}`;}};return a.addEventListener("timeupdate",h),a.addEventListener("durationchange",f),a.addEventListener("seeked",h),h(),f(),()=>{a.removeEventListener("timeupdate",h),a.removeEventListener("durationchange",f),a.removeEventListener("seeked",h);}},[r,e]),e?jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsx("span",{ref:m,children:"0:00"})}):jsxs("span",{className:"timeDisplay",children:[jsx("span",{ref:m,children:"0:00"}),jsx("span",{ref:s,style:{opacity:.6},children:" / 0:00"})]})});He.displayName="TimeDisplay";var ve=He;var z={PlayButton:oe,PauseButton:ie,FullscreenButton:ae,PiPButton:se,VolumeControl:de,ProgressBar:me,SettingsMenu:pe,TimeDisplay:ve};var Le=({videoRef:r,playerRef:e,playerContainerRef:m,playbackRates:s,enablePreview:a,thumbnailVtt:h,isPlaying:f,volume:l,isMuted:b,playbackRate:d,isFullscreen:P,isPictureInPicture:T,isLive:C,qualityLevels:E,currentQualityLevel:v})=>{let w=useRef(null),L=useRef(null),[D,x]=useState(true),V=useRef({isPlaying:f,volume:l,isMuted:b,isLive:C});V.current={isPlaying:f,volume:l,isMuted:b,isLive:C},useEffect(()=>{if(!f){x(true),L.current&&clearTimeout(L.current);return}let g=()=>{x(true),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>x(false),3e3);},u=w.current;return u&&(u.addEventListener("mousemove",g),u.addEventListener("mouseenter",g),u.addEventListener("touchstart",g,{passive:true})),g(),()=>{u&&(u.removeEventListener("mousemove",g),u.removeEventListener("mouseenter",g),u.removeEventListener("touchstart",g)),L.current&&clearTimeout(L.current);}},[f]),useEffect(()=>{let g=u=>{if(!m.current?.contains(document.activeElement))return;let R=u.target;if(R.tagName==="INPUT"||R.tagName==="TEXTAREA"||R.isContentEditable)return;let{isPlaying:Y,volume:q,isLive:Z}=V.current,X=r.current?.currentTime??0,G=r.current?.duration??0;switch(u.code){case "Space":case "KeyK":u.preventDefault(),Y?e.pause():e.play();break;case "ArrowLeft":u.preventDefault(),e.seek(Math.max(0,X-5));break;case "ArrowRight":u.preventDefault(),e.seek(Math.min(G||1/0,X+5));break;case "ArrowUp":u.preventDefault(),e.setVolume(Math.min(1,q+.1));break;case "ArrowDown":u.preventDefault(),e.setVolume(Math.max(0,q-.1));break;case "KeyM":u.preventDefault(),e.toggleMute();break;case "KeyF":u.preventDefault(),e.toggleFullscreen();break;case "KeyP":u.preventDefault(),e.togglePictureInPicture();break;case "KeyL":u.preventDefault(),Z&&e.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{u.preventDefault();let Q=Number(u.code.replace("Digit",""))*10;e.seek(G/100*Q);break}}};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[e,m,r]);let O=useCallback(()=>e.play(),[e]),S=useCallback(()=>e.pause(),[e]),$=useCallback(g=>e.setVolume(g),[e]),A=useCallback(()=>e.toggleMute(),[e]),t=useCallback(g=>e.setPlaybackRate(g),[e]),o=useCallback(g=>e.setQualityLevel(g),[e]),c=useCallback(()=>e.togglePictureInPicture(),[e]),M=useCallback(()=>e.toggleFullscreen(),[e]),I=useCallback(()=>e.seekToLive(),[e]);return jsx("div",{ref:w,style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:D?1:0,transition:"opacity 0.3s",pointerEvents:D?"auto":"none"},children:jsxs("div",{style:{background:"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)",padding:"48px 12px 12px"},role:"region","aria-label":"Video player controls",children:[jsx(z.ProgressBar,{videoRef:r,playerRef:e,enablePreview:a,thumbnailVtt:h}),jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[f?jsx(z.PauseButton,{onClick:S}):jsx(z.PlayButton,{onClick:O}),jsx(z.VolumeControl,{volume:l,isMuted:b,onVolumeChange:$,onToggleMute:A}),jsx(z.TimeDisplay,{videoRef:r,isLive:C}),jsx("div",{style:{flex:1}}),C&&jsx(Oe,{onClick:I}),jsx(z.SettingsMenu,{currentRate:d,playbackRates:s,onRateChange:t,qualityLevels:E,currentQualityLevel:v,onQualityChange:o}),jsx(z.PiPButton,{onClick:c,isPiP:T}),jsx(z.FullscreenButton,{onClick:M,isFullscreen:P})]})]})})},Oe=memo(({onClick:r})=>jsx("button",{onClick:r,style:{background:"none",border:"1px solid rgba(255,255,255,0.6)",color:"#fff",borderRadius:3,padding:"2px 8px",fontSize:11,fontWeight:700,cursor:"pointer",letterSpacing:"0.06em"},title:"Go to live (L)",children:"GO LIVE"}));Oe.displayName="GoLiveButton";var ze=forwardRef(({src:r,poster:e,autoplay:m=false,muted:s=false,loop:a=false,controls:h=true,preload:f="metadata",playbackRates:l=[.25,.5,.75,1,1.25,1.5,1.75,2],className:b,enableHLS:d=true,enablePreview:P=true,thumbnailVtt:T,hlsConfig:C,subtitles:E,crossOrigin:v,onPlay:w,onPause:L,onEnded:D,onError:x,onTimeUpdate:V,onDurationChange:O,onBuffering:S},$)=>{let A=useRef(null),t=useRef(null),{state:o,ref:c,fullscreenContainerRef:M}=Me(A,r,{autoplay:m,muted:s,loop:a,playbackRates:l,enableHLS:d,hlsConfig:C,onPlay:w,onPause:L,onEnded:D,onError:x,onTimeUpdate:V,onDurationChange:O,onBuffering:S});useEffect(()=>{M.current=t.current;},[M]),ct.useImperativeHandle($,()=>c,[c]);let I=useCallback(()=>{t.current?.focus(),o.isPlaying?c.pause():c.play();},[o.isPlaying,c]),g=useCallback(()=>{c.toggleFullscreen();},[c]);return jsxs("div",{ref:t,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:b,"data-test":"video-player-container",children:[jsx("video",{ref:A,poster:e,preload:f,crossOrigin:v,onClick:I,onDoubleClick:g,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer"},"data-test":"video-element",children:E?.map(u=>jsx("track",{kind:"subtitles",src:u.src,label:u.label,srcLang:u.srclang,default:u.default},u.id))}),h&&jsx(Le,{videoRef:A,playerRef:c,playerContainerRef:t,playbackRates:l,enablePreview:P,thumbnailVtt:T,isPlaying:o.isPlaying,volume:o.volume,isMuted:o.isMuted,playbackRate:o.playbackRate,isFullscreen:o.isFullscreen,isPictureInPicture:o.isPictureInPicture,isLive:o.isLive,qualityLevels:o.qualityLevels,currentQualityLevel:o.currentQualityLevel}),o.isLive&&jsx("div",{style:{position:"absolute",top:12,left:12,backgroundColor:"#e53935",color:"#fff",fontSize:11,fontWeight:700,letterSpacing:"0.08em",padding:"2px 8px",borderRadius:3,pointerEvents:"none"},children:"LIVE"}),o.isBuffering&&!o.error&&jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:12,color:"#fff",pointerEvents:"none"},"data-test":"buffering-indicator",children:[jsx("div",{style:{width:48,height:48,border:"4px solid rgba(255,255,255,0.25)",borderTop:"4px solid #fff",borderRadius:"50%",animation:"rvp-spin 0.8s linear infinite"}}),jsx("style",{children:"@keyframes rvp-spin { to { transform: rotate(360deg); } }"})]}),o.error&&jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0,0,0,0.85)",color:"#fff",padding:24},"data-test":"error-overlay",children:jsxs("div",{style:{textAlign:"center",maxWidth:400},children:[jsx("div",{style:{fontSize:36,marginBottom:12},children:"\u26A0"}),jsx("h3",{style:{margin:"0 0 8px",fontSize:18},children:o.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":o.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:o.error.message})]})})]})});ze.displayName="VideoPlayer";var pt=ze;export{Ve as ControlElements,Le as Controls,pt as VideoPlayer,be as findThumbnailCue,j as formatTime,We as getMimeType,le as isHLSUrl,ge as parseThumbnailVtt};//# sourceMappingURL=index.mjs.map
|
|
3
4
|
//# sourceMappingURL=index.mjs.map
|