@glitchlab/react-video-player 1.1.0 → 1.1.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/README.md CHANGED
@@ -100,7 +100,7 @@ No client-component wrapper required.
100
100
  | `muted` | `boolean` | `true` | Mute the video. Required for autoplay in most browsers. |
101
101
  | `loop` | `boolean` | `false` | Loop playback. |
102
102
  | `controls` | `boolean` | `false` | Show native browser controls. |
103
- | `autoPlay` | `boolean` | `false` | Start playback as soon as the source loads. Browsers block sound-on autoplay, so this only fires when `muted` is also `true` (the default). |
103
+ | `autoPlay` | `boolean` | `false` | Start playback as soon as the source is ready. Works for HLS (after `MANIFEST_PARSED`), native MP4/WebM (after `loadedmetadata`), and YouTube embeds. Browsers block sound-on autoplay, so this only fires when `muted` is also `true` (the default). |
104
104
  | `frameMaxWidth` | `{ desktop?: string; mobile?: string }` | `{ desktop: "960px", mobile: "420px" }` | Max width of the player in each device mode. |
105
105
  | `aspectRatio` | `{ desktop?: AspectRatio; mobile?: AspectRatio }` | `{ desktop: "16/9", mobile: "9/16" }` | Aspect ratio per device mode. `AspectRatio` is `` `${number}/${number}` ``. |
106
106
  | `hlsConfig` | `Hls.HlsConfig` | — | Optional hls.js config. Pass a stable reference (e.g. `useMemo`) to avoid HLS rebuilds. |
@@ -150,10 +150,22 @@ Recognised forms: `youtube.com/watch?v=ID`, `youtu.be/ID`, `youtube.com/embed/ID
150
150
  src="/videos/hero.m3u8"
151
151
  muted
152
152
  loop
153
+ autoPlay
153
154
  showDeviceToggle={false}
154
155
  />
155
156
  ```
156
157
 
158
+ ### Autoplay an HLS stream
159
+
160
+ ```tsx
161
+ <ReactVideoPlayer
162
+ src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
163
+ autoPlay
164
+ />
165
+ ```
166
+
167
+ > `autoPlay` waits for the manifest to parse (HLS) or for `loadedmetadata` (native), then calls `.play()` for you. Browsers reject sound-on autoplay without a prior user gesture — `muted` (the default) is the reliable path.
168
+
157
169
  ### Hover-to-play with a tooltip
158
170
 
159
171
  ```tsx
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),l=require("react"),S=require("hls.js");function H(e){var n,s,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(n=0;n<a;n++)e[n]&&(s=H(e[n]))&&(r&&(r+=" "),r+=s)}else for(s in e)e[s]&&(r&&(r+=" "),r+=s);return r}function P(){for(var e,n,s=0,r="",a=arguments.length;s<a;s++)(e=arguments[s])&&(n=H(e))&&(r&&(r+=" "),r+=n);return r}const R=l.forwardRef(({src:e,hlsConfig:n,isHls:s,children:r,...a},f)=>{const u=l.useRef(null),o=l.useRef(null);l.useImperativeHandle(f,()=>u.current);const y=globalThis.window!==void 0&&S.isSupported(),b=!!s||y&&typeof e=="string"&&e.endsWith(".m3u8");return l.useEffect(()=>{if(!e)return;const i=u.current;if(i){for(o.current&&(o.current.destroy(),o.current=null),i.pause(),i.removeAttribute("src");i.firstChild;)i.firstChild.remove();if(b){const d=new S(n);o.current=d,d.attachMedia(i),d.loadSource(e),d.on(S.Events.ERROR,(h,p)=>{p.fatal&&(d.destroy(),o.current=null)})}else i.src=e,i.load();return()=>{for(o.current&&(o.current.destroy(),o.current=null),i.pause(),i.removeAttribute("src");i.firstChild;)i.firstChild.remove();i.load()}}},[e,b,n]),t.jsx("video",{ref:u,...a,children:r})});R.displayName="HLSPlayer";const T="gvp-icon",N=e=>e?`${T} ${e}`:T,W=({className:e})=>t.jsxs("svg",{className:N(e),width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[t.jsx("path",{d:"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),t.jsx("path",{d:"M11 15H13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),t.jsx("path",{d:"M7 22H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),X=({className:e})=>t.jsxs("svg",{className:N(e),width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[t.jsx("path",{d:"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"}),t.jsx("path",{d:"M11 19H13",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})]}),G=({className:e})=>t.jsx("svg",{className:N(e),width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:t.jsx("path",{d:"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z",fill:"currentColor"})}),K=({className:e})=>t.jsx("svg",{className:N(e),width:"22",height:"22",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:t.jsx("path",{d:"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z",fill:"currentColor"})});function $(e){if(!e)return null;if(/^[A-Za-z0-9_-]{11}$/.test(e))return e;let n;try{n=new URL(e)}catch{return null}const s=n.hostname.replace(/^www\./,"");if(s==="youtu.be"){const r=n.pathname.slice(1).split("/")[0];return/^[A-Za-z0-9_-]{11}$/.test(r)?r:null}if(s==="youtube.com"||s==="m.youtube.com"||s==="music.youtube.com"||s==="youtube-nocookie.com"){const r=n.searchParams.get("v");if(r&&/^[A-Za-z0-9_-]{11}$/.test(r))return r;const a=/^\/(?:embed|shorts|v|live)\/([A-Za-z0-9_-]{11})/.exec(n.pathname);if(a)return a[1]}return null}function E(e){try{const n=new URL(e),s=n.searchParams.get("t")??n.searchParams.get("start");if(!s)return null;if(/^\d+s?$/.test(s))return Number.parseInt(s,10);const r=/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/.exec(s);if(r){const a=Number.parseInt(r[1]??"0",10),f=Number.parseInt(r[2]??"0",10),u=Number.parseInt(r[3]??"0",10),o=a*3600+f*60+u;return o>0?o:null}}catch{}return null}function Z(e,n={}){const{autoPlay:s=!1,muted:r=!0,loop:a=!1,controls:f=!0,startSeconds:u}=n,o=new URLSearchParams({rel:"0",modestbranding:"1",playsinline:"1",controls:f?"1":"0"});return s?(o.set("autoplay","1"),o.set("mute","1")):r&&o.set("mute","1"),a&&(o.set("loop","1"),o.set("playlist",e)),u&&u>0&&o.set("start",String(u)),`https://www.youtube-nocookie.com/embed/${e}?${o.toString()}`}const Q=({src:e,poster:n,showDeviceToggle:s=!0,defaultDevice:r="desktop",hoverPlay:a=!1,tooltipText:f,onClose:u,className:o="",muted:y=!0,loop:b=!1,controls:i=!1,autoPlay:d=!1,frameMaxWidth:h,aspectRatio:p,hlsConfig:U,children:Y})=>{const w=l.useRef(null),m=l.useRef(null),[v,I]=l.useState(r),[B,g]=l.useState(!1),[V,k]=l.useState(!1),j=l.useMemo(()=>$(e),[e]),C=j!==null,_=l.useMemo(()=>v==="mobile"?(p==null?void 0:p.mobile)??"9/16":(p==null?void 0:p.desktop)??"16/9",[v,p]),z=l.useMemo(()=>v==="mobile"?(h==null?void 0:h.mobile)??"420px":(h==null?void 0:h.desktop)??"960px",[v,h]),q=l.useMemo(()=>j?Z(j,{autoPlay:d,muted:y,loop:b,controls:i,startSeconds:E(e)}):null,[j,e,d,y,b,i]),x=l.useCallback(async()=>{const c=w.current;if(c){if(m.current)try{await m.current}catch{}c.pause()}},[]),L=l.useCallback(async()=>{const c=w.current;if(c)try{c.readyState<2&&c.load();const M=c.play();m.current=M,await M,g(!0)}catch{g(!1)}finally{m.current=null}},[]),D=l.useCallback(()=>{!a||C||L()},[a,C,L]),O=l.useCallback(()=>{!a||C||x().then(()=>g(!1))},[a,C,x]),J=l.useCallback(async()=>{const c=w.current;c&&(c.paused?await L():(await x(),g(!1)))},[L,x]);return t.jsxs("div",{className:P("gvp-root",o),style:{width:z,aspectRatio:_},onMouseEnter:()=>{k(!0),D()},onMouseLeave:()=>{k(!1),O()},children:[C?t.jsx("iframe",{className:"gvp-video gvp-youtube",src:q??void 0,title:"YouTube video player",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowFullScreen:!0,referrerPolicy:"strict-origin-when-cross-origin"}):t.jsx(R,{ref:w,src:e,poster:n,muted:y,loop:b,playsInline:!0,preload:"metadata",controls:i,autoPlay:d,hlsConfig:U,className:"gvp-video",onPlay:()=>g(!0),onPause:()=>g(!1),children:Y}),!C&&t.jsx("div",{className:"gvp-vignette"}),s&&t.jsx("div",{className:"gvp-toggle",children:t.jsxs("div",{className:"gvp-toggle-pill",children:[t.jsx("button",{type:"button",onClick:()=>I("desktop"),className:P("gvp-toggle-btn",v==="desktop"&&"is-active"),"aria-label":"Desktop view","aria-pressed":v==="desktop",children:t.jsx(W,{})}),t.jsx("div",{className:"gvp-toggle-divider"}),t.jsx("button",{type:"button",onClick:()=>I("mobile"),className:P("gvp-toggle-btn",v==="mobile"&&"is-active"),"aria-label":"Mobile view","aria-pressed":v==="mobile",children:t.jsx(X,{})})]})}),u&&t.jsx("button",{type:"button",onClick:u,className:"gvp-close","aria-label":"Close",children:t.jsx(G,{})}),!C&&!B&&t.jsx("div",{className:"gvp-play-wrap",children:t.jsxs("button",{type:"button",onClick:()=>void J(),onMouseEnter:()=>k(!0),onMouseLeave:()=>k(!1),className:"gvp-play","aria-label":"Play",children:[t.jsx(K,{}),f&&V&&t.jsx("span",{className:"gvp-tooltip",role:"tooltip",children:f})]})}),!C&&t.jsx("div",{className:"gvp-bottom-fade"})]})};exports.ReactVideoPlayer=Q;exports.parseYouTubeId=$;exports.parseYouTubeStart=E;exports.youTubeEmbedUrl=Z;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),l=require("react"),N=require("hls.js");function R(e){var n,s,t="";if(typeof e=="string"||typeof e=="number")t+=e;else if(typeof e=="object")if(Array.isArray(e)){var a=e.length;for(n=0;n<a;n++)e[n]&&(s=R(e[n]))&&(t&&(t+=" "),t+=s)}else for(s in e)e[s]&&(t&&(t+=" "),t+=s);return t}function I(){for(var e,n,s=0,t="",a=arguments.length;s<a;s++)(e=arguments[s])&&(n=R(e))&&(t&&(t+=" "),t+=n);return t}const $=l.forwardRef(({src:e,hlsConfig:n,isHls:s,autoPlay:t,children:a,...h},p)=>{const i=l.useRef(null),c=l.useRef(null);l.useImperativeHandle(p,()=>i.current);const y=globalThis.window!==void 0&&N.isSupported(),b=!!s||y&&typeof e=="string"&&e.endsWith(".m3u8");return l.useEffect(()=>{if(!e)return;const o=i.current;if(!o)return;const d=()=>{t&&o.play().catch(()=>{})};for(c.current&&(c.current.destroy(),c.current=null),o.pause(),o.removeAttribute("src");o.firstChild;)o.firstChild.remove();if(b){const u=new N(n);c.current=u,u.attachMedia(o),u.loadSource(e),u.on(N.Events.MANIFEST_PARSED,d),u.on(N.Events.ERROR,(M,P)=>{P.fatal&&(u.destroy(),c.current=null)})}else o.src=e,o.load(),o.addEventListener("loadedmetadata",d,{once:!0});return()=>{for(o.removeEventListener("loadedmetadata",d),c.current&&(c.current.destroy(),c.current=null),o.pause(),o.removeAttribute("src");o.firstChild;)o.firstChild.remove();o.load()}},[e,b,n,t]),r.jsx("video",{ref:i,...h,children:a})});$.displayName="HLSPlayer";const H="gvp-icon",S=e=>e?`${H} ${e}`:H,J=({className:e})=>r.jsxs("svg",{className:S(e),width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[r.jsx("path",{d:"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r.jsx("path",{d:"M11 15H13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),r.jsx("path",{d:"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r.jsx("path",{d:"M7 22H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),W=({className:e})=>r.jsxs("svg",{className:S(e),width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[r.jsx("path",{d:"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"}),r.jsx("path",{d:"M11 19H13",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),r.jsx("path",{d:"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2",stroke:"currentColor",strokeWidth:"2",strokeLinejoin:"round"})]}),X=({className:e})=>r.jsx("svg",{className:S(e),width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:r.jsx("path",{d:"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z",fill:"currentColor"})}),G=({className:e})=>r.jsx("svg",{className:S(e),width:"22",height:"22",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:r.jsx("path",{d:"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z",fill:"currentColor"})});function Z(e){if(!e)return null;if(/^[A-Za-z0-9_-]{11}$/.test(e))return e;let n;try{n=new URL(e)}catch{return null}const s=n.hostname.replace(/^www\./,"");if(s==="youtu.be"){const t=n.pathname.slice(1).split("/")[0];return/^[A-Za-z0-9_-]{11}$/.test(t)?t:null}if(s==="youtube.com"||s==="m.youtube.com"||s==="music.youtube.com"||s==="youtube-nocookie.com"){const t=n.searchParams.get("v");if(t&&/^[A-Za-z0-9_-]{11}$/.test(t))return t;const a=/^\/(?:embed|shorts|v|live)\/([A-Za-z0-9_-]{11})/.exec(n.pathname);if(a)return a[1]}return null}function U(e){try{const n=new URL(e),s=n.searchParams.get("t")??n.searchParams.get("start");if(!s)return null;if(/^\d+s?$/.test(s))return Number.parseInt(s,10);const t=/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/.exec(s);if(t){const a=Number.parseInt(t[1]??"0",10),h=Number.parseInt(t[2]??"0",10),p=Number.parseInt(t[3]??"0",10),i=a*3600+h*60+p;return i>0?i:null}}catch{}return null}function Y(e,n={}){const{autoPlay:s=!1,muted:t=!0,loop:a=!1,controls:h=!0,startSeconds:p}=n,i=new URLSearchParams({rel:"0",modestbranding:"1",playsinline:"1",controls:h?"1":"0"});return s?(i.set("autoplay","1"),i.set("mute","1")):t&&i.set("mute","1"),a&&(i.set("loop","1"),i.set("playlist",e)),p&&p>0&&i.set("start",String(p)),`https://www.youtube-nocookie.com/embed/${e}?${i.toString()}`}const K=({src:e,poster:n,showDeviceToggle:s=!0,defaultDevice:t="desktop",hoverPlay:a=!1,tooltipText:h,onClose:p,className:i="",muted:c=!0,loop:y=!1,controls:b=!1,autoPlay:o=!1,frameMaxWidth:d,aspectRatio:u,hlsConfig:M,children:P})=>{const m=l.useRef(null),w=l.useRef(null),[v,T]=l.useState(t),[_,g]=l.useState(!1),[B,k]=l.useState(!1),j=l.useMemo(()=>Z(e),[e]),C=j!==null,V=l.useMemo(()=>v==="mobile"?(u==null?void 0:u.mobile)??"9/16":(u==null?void 0:u.desktop)??"16/9",[v,u]),z=l.useMemo(()=>v==="mobile"?(d==null?void 0:d.mobile)??"420px":(d==null?void 0:d.desktop)??"960px",[v,d]),D=l.useMemo(()=>j?Y(j,{autoPlay:o,muted:c,loop:y,controls:b,startSeconds:U(e)}):null,[j,e,o,c,y,b]),x=l.useCallback(async()=>{const f=m.current;if(f){if(w.current)try{await w.current}catch{}f.pause()}},[]),L=l.useCallback(async()=>{const f=m.current;if(f)try{f.readyState<2&&f.load();const E=f.play();w.current=E,await E,g(!0)}catch{g(!1)}finally{w.current=null}},[]),q=l.useCallback(()=>{!a||C||L()},[a,C,L]),O=l.useCallback(()=>{!a||C||x().then(()=>g(!1))},[a,C,x]),A=l.useCallback(async()=>{const f=m.current;f&&(f.paused?await L():(await x(),g(!1)))},[L,x]);return r.jsxs("div",{className:I("gvp-root",i),style:{width:z,aspectRatio:V},onMouseEnter:()=>{k(!0),q()},onMouseLeave:()=>{k(!1),O()},children:[C?r.jsx("iframe",{className:"gvp-video gvp-youtube",src:D??void 0,title:"YouTube video player",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowFullScreen:!0,referrerPolicy:"strict-origin-when-cross-origin"}):r.jsx($,{ref:m,src:e,poster:n,muted:c,loop:y,playsInline:!0,preload:"metadata",controls:b,autoPlay:o,hlsConfig:M,className:"gvp-video",onPlay:()=>g(!0),onPause:()=>g(!1),children:P}),!C&&r.jsx("div",{className:"gvp-vignette"}),s&&r.jsx("div",{className:"gvp-toggle",children:r.jsxs("div",{className:"gvp-toggle-pill",children:[r.jsx("button",{type:"button",onClick:()=>T("desktop"),className:I("gvp-toggle-btn",v==="desktop"&&"is-active"),"aria-label":"Desktop view","aria-pressed":v==="desktop",children:r.jsx(J,{})}),r.jsx("div",{className:"gvp-toggle-divider"}),r.jsx("button",{type:"button",onClick:()=>T("mobile"),className:I("gvp-toggle-btn",v==="mobile"&&"is-active"),"aria-label":"Mobile view","aria-pressed":v==="mobile",children:r.jsx(W,{})})]})}),p&&r.jsx("button",{type:"button",onClick:p,className:"gvp-close","aria-label":"Close",children:r.jsx(X,{})}),!C&&!_&&r.jsx("div",{className:"gvp-play-wrap",children:r.jsxs("button",{type:"button",onClick:()=>void A(),onMouseEnter:()=>k(!0),onMouseLeave:()=>k(!1),className:"gvp-play","aria-label":"Play",children:[r.jsx(G,{}),h&&B&&r.jsx("span",{className:"gvp-tooltip",role:"tooltip",children:h})]})}),!C&&r.jsx("div",{className:"gvp-bottom-fade"})]})};exports.ReactVideoPlayer=K;exports.parseYouTubeId=Z;exports.parseYouTubeStart=U;exports.youTubeEmbedUrl=Y;
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/HLSPlayer.tsx","../src/utils/icons.tsx","../src/utils/youtube.ts","../src/VideoPlayerWrapper.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","\"use client\";\n\nimport Hls from \"hls.js\";\nimport React, { useEffect, useImperativeHandle, useRef } from \"react\";\nimport type { HLSPlayerProps } from \"./types\";\n\nexport const HLSPlayer = React.forwardRef<HTMLVideoElement, HLSPlayerProps>(\n ({ src, hlsConfig, isHls, children, ...videoProps }, forwardedRef) => {\n const internalRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLVideoElement);\n\n const canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\n const shouldUseHls =\n Boolean(isHls) || (canUseHlsJs && typeof src === \"string\" && src.endsWith(\".m3u8\"));\n\n useEffect(() => {\n if (!src) return;\n const videoEl = internalRef.current;\n if (!videoEl) return;\n\n // destroy previous\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n\n // reset video element\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n\n if (shouldUseHls) {\n const hls = new Hls(hlsConfig);\n hlsRef.current = hls;\n\n hls.attachMedia(videoEl);\n hls.loadSource(src);\n\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsRef.current = null;\n }\n });\n } else {\n // native playback\n videoEl.src = src;\n videoEl.load();\n }\n\n return () => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n videoEl.load();\n };\n }, [src, shouldUseHls, hlsConfig]);\n\n // Captions are the consumer's responsibility — pass <track> elements as children.\n // NOSONAR: typescript:S4084\n return (\n <video ref={internalRef} {...videoProps}>\n {children}\n </video>\n );\n }\n);\n\nHLSPlayer.displayName = \"HLSPlayer\";\nexport default HLSPlayer;\n","\"use client\";\n\nimport React from \"react\";\n\ntype IconProps = { className?: string };\n\nconst baseClass = \"gvp-icon\";\nconst cls = (extra?: string) => (extra ? `${baseClass} ${extra}` : baseClass);\n\nexport const IconDesktop: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path d=\"M7 22H17\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const IconMobile: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const IconX: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport const IconPlay: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n // Bare 11-char ID (YouTube IDs are [A-Za-z0-9_-]{11}).\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n // /watch?v=ID\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n // /embed/ID, /shorts/ID, /v/ID, /live/ID\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n // Supports \"90\", \"90s\", \"1m30s\", \"1h2m3s\".\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(id: string, opts: YouTubeEmbedOptions = {}): string {\n const { autoPlay = false, muted = true, loop = false, controls = true, startSeconds } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\",\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","\"use client\";\n\nimport clsx from \"clsx\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { HLSPlayer } from \"./HLSPlayer\";\nimport type { DeviceMode, VideoPlayerWrapperProps } from \"./types\";\nimport { IconDesktop, IconMobile, IconPlay, IconX } from \"./utils/icons\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nexport const VideoPlayerWrapper: React.FC<VideoPlayerWrapperProps> = ({\n src,\n poster,\n showDeviceToggle = true,\n defaultDevice = \"desktop\",\n hoverPlay = false,\n tooltipText,\n onClose,\n className = \"\",\n muted = true,\n loop = false,\n controls = false,\n autoPlay = false,\n frameMaxWidth: customFrameMaxWidth,\n aspectRatio: customAspectRatio,\n hlsConfig,\n children,\n}) => {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playPromiseRef = useRef<Promise<void> | null>(null);\n\n const [device, setDevice] = useState<DeviceMode>(defaultDevice);\n const [isPlaying, setIsPlaying] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const youTubeId = useMemo(() => parseYouTubeId(src), [src]);\n const isYouTube = youTubeId !== null;\n\n const aspectRatio = useMemo(() => {\n return device === \"mobile\"\n ? (customAspectRatio?.mobile ?? \"9/16\")\n : (customAspectRatio?.desktop ?? \"16/9\");\n }, [device, customAspectRatio]);\n\n const frameMaxWidth = useMemo(() => {\n return device === \"mobile\"\n ? (customFrameMaxWidth?.mobile ?? \"420px\")\n : (customFrameMaxWidth?.desktop ?? \"960px\");\n }, [device, customFrameMaxWidth]);\n\n const youTubeSrc = useMemo(\n () =>\n youTubeId\n ? youTubeEmbedUrl(youTubeId, {\n autoPlay,\n muted,\n loop,\n controls,\n startSeconds: parseYouTubeStart(src),\n })\n : null,\n [youTubeId, src, autoPlay, muted, loop, controls]\n );\n\n const safePause = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (playPromiseRef.current) {\n try {\n await playPromiseRef.current;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n }, []);\n\n const safePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromiseRef.current = p;\n await p;\n setIsPlaying(true);\n } catch {\n setIsPlaying(false);\n } finally {\n playPromiseRef.current = null;\n }\n }, []);\n\n const hoverStart = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePlay();\n }, [hoverPlay, isYouTube, safePlay]);\n\n const hoverStop = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePause().then(() => setIsPlaying(false));\n }, [hoverPlay, isYouTube, safePause]);\n\n const togglePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n setIsPlaying(false);\n }\n }, [safePlay, safePause]);\n\n return (\n // The mouse handlers are a progressive enhancement (hoverPlay + tooltip).\n // Keyboard/click users reach the same actions via the inner <button> elements,\n // so the outer container is intentionally non-interactive at the role level.\n // NOSONAR: typescript:S6848\n <div\n className={clsx(\"gvp-root\", className)}\n style={{ width: frameMaxWidth, aspectRatio }}\n onMouseEnter={() => {\n setShowTooltip(true);\n hoverStart();\n }}\n onMouseLeave={() => {\n setShowTooltip(false);\n hoverStop();\n }}\n >\n {isYouTube ? (\n <iframe\n className=\"gvp-video gvp-youtube\"\n src={youTubeSrc ?? undefined}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n />\n ) : (\n <HLSPlayer\n ref={videoRef}\n src={src}\n poster={poster}\n muted={muted}\n loop={loop}\n playsInline\n preload=\"metadata\"\n controls={controls}\n autoPlay={autoPlay}\n hlsConfig={hlsConfig}\n className=\"gvp-video\"\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n >\n {children}\n </HLSPlayer>\n )}\n\n {!isYouTube && <div className=\"gvp-vignette\" />}\n\n {showDeviceToggle && (\n <div className=\"gvp-toggle\">\n <div className=\"gvp-toggle-pill\">\n <button\n type=\"button\"\n onClick={() => setDevice(\"desktop\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"desktop\" && \"is-active\"\n )}\n aria-label=\"Desktop view\"\n aria-pressed={device === \"desktop\"}\n >\n <IconDesktop />\n </button>\n\n <div className=\"gvp-toggle-divider\" />\n\n <button\n type=\"button\"\n onClick={() => setDevice(\"mobile\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"mobile\" && \"is-active\"\n )}\n aria-label=\"Mobile view\"\n aria-pressed={device === \"mobile\"}\n >\n <IconMobile />\n </button>\n </div>\n </div>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"gvp-close\"\n aria-label=\"Close\"\n >\n <IconX />\n </button>\n )}\n\n {!isYouTube && !isPlaying && (\n <div className=\"gvp-play-wrap\">\n <button\n type=\"button\"\n onClick={() => void togglePlay()}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n className=\"gvp-play\"\n aria-label=\"Play\"\n >\n <IconPlay />\n {tooltipText && showTooltip && (\n <span className=\"gvp-tooltip\" role=\"tooltip\">\n {tooltipText}\n </span>\n )}\n </button>\n </div>\n )}\n\n {!isYouTube && <div className=\"gvp-bottom-fade\" />}\n </div>\n );\n};\n\nexport default VideoPlayerWrapper;\n"],"names":["r","t","f","n","o","clsx","HLSPlayer","React","src","hlsConfig","isHls","children","videoProps","forwardedRef","internalRef","useRef","hlsRef","useImperativeHandle","canUseHlsJs","Hls","shouldUseHls","useEffect","videoEl","hls","_evt","data","baseClass","cls","extra","IconDesktop","className","jsxs","jsx","IconMobile","IconX","IconPlay","parseYouTubeId","input","url","host","id","v","m","parseYouTubeStart","h","min","s","total","youTubeEmbedUrl","opts","autoPlay","muted","loop","controls","startSeconds","params","VideoPlayerWrapper","poster","showDeviceToggle","defaultDevice","hoverPlay","tooltipText","onClose","customFrameMaxWidth","customAspectRatio","videoRef","playPromiseRef","device","setDevice","useState","isPlaying","setIsPlaying","showTooltip","setShowTooltip","youTubeId","useMemo","isYouTube","aspectRatio","frameMaxWidth","youTubeSrc","safePause","useCallback","el","safePlay","p","hoverStart","hoverStop","togglePlay"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"index.cjs","sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/HLSPlayer.tsx","../src/utils/icons.tsx","../src/utils/youtube.ts","../src/VideoPlayerWrapper.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","\"use client\";\n\nimport Hls from \"hls.js\";\nimport React, { useEffect, useImperativeHandle, useRef } from \"react\";\nimport type { HLSPlayerProps } from \"./types\";\n\nexport const HLSPlayer = React.forwardRef<HTMLVideoElement, HLSPlayerProps>(\n ({ src, hlsConfig, isHls, autoPlay, children, ...videoProps }, forwardedRef) => {\n const internalRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLVideoElement);\n\n const canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\n const shouldUseHls =\n Boolean(isHls) || (canUseHlsJs && typeof src === \"string\" && src.endsWith(\".m3u8\"));\n\n useEffect(() => {\n if (!src) return;\n const videoEl = internalRef.current;\n if (!videoEl) return;\n\n // Tries to start playback once the stream is ready. Browsers only\n // honor sound-on autoplay after a user gesture, so this is best\n // effort — silently swallows the NotAllowedError when blocked.\n const tryAutoPlay = () => {\n if (!autoPlay) return;\n videoEl.play().catch(() => {\n /* autoplay blocked; user gesture required */\n });\n };\n\n // destroy previous\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n\n // reset video element\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n\n if (shouldUseHls) {\n const hls = new Hls(hlsConfig);\n hlsRef.current = hls;\n\n hls.attachMedia(videoEl);\n hls.loadSource(src);\n\n hls.on(Hls.Events.MANIFEST_PARSED, tryAutoPlay);\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsRef.current = null;\n }\n });\n } else {\n // native playback\n videoEl.src = src;\n videoEl.load();\n // For a plain <video>, we wait for metadata so play() has\n // something to start.\n videoEl.addEventListener(\"loadedmetadata\", tryAutoPlay, { once: true });\n }\n\n return () => {\n videoEl.removeEventListener(\"loadedmetadata\", tryAutoPlay);\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n videoEl.load();\n };\n }, [src, shouldUseHls, hlsConfig, autoPlay]);\n\n // Captions are the consumer's responsibility — pass <track> elements as children.\n // NOSONAR: typescript:S4084\n return (\n <video ref={internalRef} {...videoProps}>\n {children}\n </video>\n );\n }\n);\n\nHLSPlayer.displayName = \"HLSPlayer\";\nexport default HLSPlayer;\n","\"use client\";\n\nimport React from \"react\";\n\ntype IconProps = { className?: string };\n\nconst baseClass = \"gvp-icon\";\nconst cls = (extra?: string) => (extra ? `${baseClass} ${extra}` : baseClass);\n\nexport const IconDesktop: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path d=\"M7 22H17\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const IconMobile: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const IconX: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport const IconPlay: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n // Bare 11-char ID (YouTube IDs are [A-Za-z0-9_-]{11}).\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n // /watch?v=ID\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n // /embed/ID, /shorts/ID, /v/ID, /live/ID\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n // Supports \"90\", \"90s\", \"1m30s\", \"1h2m3s\".\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(id: string, opts: YouTubeEmbedOptions = {}): string {\n const { autoPlay = false, muted = true, loop = false, controls = true, startSeconds } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\",\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","\"use client\";\n\nimport clsx from \"clsx\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { HLSPlayer } from \"./HLSPlayer\";\nimport type { DeviceMode, VideoPlayerWrapperProps } from \"./types\";\nimport { IconDesktop, IconMobile, IconPlay, IconX } from \"./utils/icons\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nexport const VideoPlayerWrapper: React.FC<VideoPlayerWrapperProps> = ({\n src,\n poster,\n showDeviceToggle = true,\n defaultDevice = \"desktop\",\n hoverPlay = false,\n tooltipText,\n onClose,\n className = \"\",\n muted = true,\n loop = false,\n controls = false,\n autoPlay = false,\n frameMaxWidth: customFrameMaxWidth,\n aspectRatio: customAspectRatio,\n hlsConfig,\n children,\n}) => {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playPromiseRef = useRef<Promise<void> | null>(null);\n\n const [device, setDevice] = useState<DeviceMode>(defaultDevice);\n const [isPlaying, setIsPlaying] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const youTubeId = useMemo(() => parseYouTubeId(src), [src]);\n const isYouTube = youTubeId !== null;\n\n const aspectRatio = useMemo(() => {\n return device === \"mobile\"\n ? (customAspectRatio?.mobile ?? \"9/16\")\n : (customAspectRatio?.desktop ?? \"16/9\");\n }, [device, customAspectRatio]);\n\n const frameMaxWidth = useMemo(() => {\n return device === \"mobile\"\n ? (customFrameMaxWidth?.mobile ?? \"420px\")\n : (customFrameMaxWidth?.desktop ?? \"960px\");\n }, [device, customFrameMaxWidth]);\n\n const youTubeSrc = useMemo(\n () =>\n youTubeId\n ? youTubeEmbedUrl(youTubeId, {\n autoPlay,\n muted,\n loop,\n controls,\n startSeconds: parseYouTubeStart(src),\n })\n : null,\n [youTubeId, src, autoPlay, muted, loop, controls]\n );\n\n const safePause = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (playPromiseRef.current) {\n try {\n await playPromiseRef.current;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n }, []);\n\n const safePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromiseRef.current = p;\n await p;\n setIsPlaying(true);\n } catch {\n setIsPlaying(false);\n } finally {\n playPromiseRef.current = null;\n }\n }, []);\n\n const hoverStart = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePlay();\n }, [hoverPlay, isYouTube, safePlay]);\n\n const hoverStop = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePause().then(() => setIsPlaying(false));\n }, [hoverPlay, isYouTube, safePause]);\n\n const togglePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n setIsPlaying(false);\n }\n }, [safePlay, safePause]);\n\n return (\n // The mouse handlers are a progressive enhancement (hoverPlay + tooltip).\n // Keyboard/click users reach the same actions via the inner <button> elements,\n // so the outer container is intentionally non-interactive at the role level.\n // NOSONAR: typescript:S6848\n <div\n className={clsx(\"gvp-root\", className)}\n style={{ width: frameMaxWidth, aspectRatio }}\n onMouseEnter={() => {\n setShowTooltip(true);\n hoverStart();\n }}\n onMouseLeave={() => {\n setShowTooltip(false);\n hoverStop();\n }}\n >\n {isYouTube ? (\n <iframe\n className=\"gvp-video gvp-youtube\"\n src={youTubeSrc ?? undefined}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n />\n ) : (\n <HLSPlayer\n ref={videoRef}\n src={src}\n poster={poster}\n muted={muted}\n loop={loop}\n playsInline\n preload=\"metadata\"\n controls={controls}\n autoPlay={autoPlay}\n hlsConfig={hlsConfig}\n className=\"gvp-video\"\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n >\n {children}\n </HLSPlayer>\n )}\n\n {!isYouTube && <div className=\"gvp-vignette\" />}\n\n {showDeviceToggle && (\n <div className=\"gvp-toggle\">\n <div className=\"gvp-toggle-pill\">\n <button\n type=\"button\"\n onClick={() => setDevice(\"desktop\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"desktop\" && \"is-active\"\n )}\n aria-label=\"Desktop view\"\n aria-pressed={device === \"desktop\"}\n >\n <IconDesktop />\n </button>\n\n <div className=\"gvp-toggle-divider\" />\n\n <button\n type=\"button\"\n onClick={() => setDevice(\"mobile\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"mobile\" && \"is-active\"\n )}\n aria-label=\"Mobile view\"\n aria-pressed={device === \"mobile\"}\n >\n <IconMobile />\n </button>\n </div>\n </div>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"gvp-close\"\n aria-label=\"Close\"\n >\n <IconX />\n </button>\n )}\n\n {!isYouTube && !isPlaying && (\n <div className=\"gvp-play-wrap\">\n <button\n type=\"button\"\n onClick={() => void togglePlay()}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n className=\"gvp-play\"\n aria-label=\"Play\"\n >\n <IconPlay />\n {tooltipText && showTooltip && (\n <span className=\"gvp-tooltip\" role=\"tooltip\">\n {tooltipText}\n </span>\n )}\n </button>\n </div>\n )}\n\n {!isYouTube && <div className=\"gvp-bottom-fade\" />}\n </div>\n );\n};\n\nexport default VideoPlayerWrapper;\n"],"names":["r","t","f","n","o","clsx","HLSPlayer","React","src","hlsConfig","isHls","autoPlay","children","videoProps","forwardedRef","internalRef","useRef","hlsRef","useImperativeHandle","canUseHlsJs","Hls","shouldUseHls","useEffect","videoEl","tryAutoPlay","hls","_evt","data","baseClass","cls","extra","IconDesktop","className","jsxs","jsx","IconMobile","IconX","IconPlay","parseYouTubeId","input","url","host","id","v","m","parseYouTubeStart","h","min","s","total","youTubeEmbedUrl","opts","muted","loop","controls","startSeconds","params","VideoPlayerWrapper","poster","showDeviceToggle","defaultDevice","hoverPlay","tooltipText","onClose","customFrameMaxWidth","customAspectRatio","videoRef","playPromiseRef","device","setDevice","useState","isPlaying","setIsPlaying","showTooltip","setShowTooltip","youTubeId","useMemo","isYouTube","aspectRatio","frameMaxWidth","youTubeSrc","safePause","useCallback","el","safePlay","p","hoverStart","hoverStop","togglePlay"],"mappings":"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","x_google_ignoreList":[0]}
package/dist/index.mjs CHANGED
@@ -1,47 +1,50 @@
1
1
  "use client";
2
- import { jsx as r, jsxs as y } from "react/jsx-runtime";
3
- import q, { useRef as H, useImperativeHandle as G, useEffect as K, useState as T, useMemo as I, useCallback as w } from "react";
4
- import $ from "hls.js";
5
- function R(e) {
2
+ import { jsx as r, jsxs as m } from "react/jsx-runtime";
3
+ import X, { useRef as H, useImperativeHandle as q, useEffect as G, useState as $, useMemo as I, useCallback as b } from "react";
4
+ import E from "hls.js";
5
+ function _(e) {
6
6
  var o, n, t = "";
7
7
  if (typeof e == "string" || typeof e == "number") t += e;
8
8
  else if (typeof e == "object") if (Array.isArray(e)) {
9
9
  var l = e.length;
10
- for (o = 0; o < l; o++) e[o] && (n = R(e[o])) && (t && (t += " "), t += n);
10
+ for (o = 0; o < l; o++) e[o] && (n = _(e[o])) && (t && (t += " "), t += n);
11
11
  } else for (n in e) e[n] && (t && (t += " "), t += n);
12
12
  return t;
13
13
  }
14
14
  function Z() {
15
- for (var e, o, n = 0, t = "", l = arguments.length; n < l; n++) (e = arguments[n]) && (o = R(e)) && (t && (t += " "), t += o);
15
+ for (var e, o, n = 0, t = "", l = arguments.length; n < l; n++) (e = arguments[n]) && (o = _(e)) && (t && (t += " "), t += o);
16
16
  return t;
17
17
  }
18
- const U = q.forwardRef(
19
- ({ src: e, hlsConfig: o, isHls: n, children: t, ...l }, p) => {
20
- const i = H(null), s = H(null);
21
- G(p, () => i.current);
22
- const b = globalThis.window !== void 0 && $.isSupported(), C = !!n || b && typeof e == "string" && e.endsWith(".m3u8");
23
- return K(() => {
18
+ const B = X.forwardRef(
19
+ ({ src: e, hlsConfig: o, isHls: n, autoPlay: t, children: l, ...f }, d) => {
20
+ const a = H(null), c = H(null);
21
+ q(d, () => a.current);
22
+ const y = globalThis.window !== void 0 && E.isSupported(), C = !!n || y && typeof e == "string" && e.endsWith(".m3u8");
23
+ return G(() => {
24
24
  if (!e) return;
25
- const a = i.current;
26
- if (a) {
27
- for (s.current && (s.current.destroy(), s.current = null), a.pause(), a.removeAttribute("src"); a.firstChild; ) a.firstChild.remove();
28
- if (C) {
29
- const c = new $(o);
30
- s.current = c, c.attachMedia(a), c.loadSource(e), c.on($.Events.ERROR, (f, d) => {
31
- d.fatal && (c.destroy(), s.current = null);
32
- });
33
- } else
34
- a.src = e, a.load();
35
- return () => {
36
- for (s.current && (s.current.destroy(), s.current = null), a.pause(), a.removeAttribute("src"); a.firstChild; ) a.firstChild.remove();
37
- a.load();
38
- };
39
- }
40
- }, [e, C, o]), /* @__PURE__ */ r("video", { ref: i, ...l, children: t });
25
+ const s = a.current;
26
+ if (!s) return;
27
+ const u = () => {
28
+ t && s.play().catch(() => {
29
+ });
30
+ };
31
+ for (c.current && (c.current.destroy(), c.current = null), s.pause(), s.removeAttribute("src"); s.firstChild; ) s.firstChild.remove();
32
+ if (C) {
33
+ const i = new E(o);
34
+ c.current = i, i.attachMedia(s), i.loadSource(e), i.on(E.Events.MANIFEST_PARSED, u), i.on(E.Events.ERROR, (R, T) => {
35
+ T.fatal && (i.destroy(), c.current = null);
36
+ });
37
+ } else
38
+ s.src = e, s.load(), s.addEventListener("loadedmetadata", u, { once: !0 });
39
+ return () => {
40
+ for (s.removeEventListener("loadedmetadata", u), c.current && (c.current.destroy(), c.current = null), s.pause(), s.removeAttribute("src"); s.firstChild; ) s.firstChild.remove();
41
+ s.load();
42
+ };
43
+ }, [e, C, o, t]), /* @__PURE__ */ r("video", { ref: a, ...f, children: l });
41
44
  }
42
45
  );
43
- U.displayName = "HLSPlayer";
44
- const x = "gvp-icon", M = (e) => e ? `${x} ${e}` : x, Q = ({ className: e }) => /* @__PURE__ */ y(
46
+ B.displayName = "HLSPlayer";
47
+ const U = "gvp-icon", M = (e) => e ? `${U} ${e}` : U, K = ({ className: e }) => /* @__PURE__ */ m(
45
48
  "svg",
46
49
  {
47
50
  className: M(e),
@@ -83,7 +86,7 @@ const x = "gvp-icon", M = (e) => e ? `${x} ${e}` : x, Q = ({ className: e }) =>
83
86
  /* @__PURE__ */ r("path", { d: "M7 22H17", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
84
87
  ]
85
88
  }
86
- ), A = ({ className: e }) => /* @__PURE__ */ y(
89
+ ), Q = ({ className: e }) => /* @__PURE__ */ m(
87
90
  "svg",
88
91
  {
89
92
  className: M(e),
@@ -192,21 +195,21 @@ function re(e) {
192
195
  if (/^\d+s?$/.test(n)) return Number.parseInt(n, 10);
193
196
  const t = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/.exec(n);
194
197
  if (t) {
195
- const l = Number.parseInt(t[1] ?? "0", 10), p = Number.parseInt(t[2] ?? "0", 10), i = Number.parseInt(t[3] ?? "0", 10), s = l * 3600 + p * 60 + i;
196
- return s > 0 ? s : null;
198
+ const l = Number.parseInt(t[1] ?? "0", 10), f = Number.parseInt(t[2] ?? "0", 10), d = Number.parseInt(t[3] ?? "0", 10), a = l * 3600 + f * 60 + d;
199
+ return a > 0 ? a : null;
197
200
  }
198
201
  } catch {
199
202
  }
200
203
  return null;
201
204
  }
202
205
  function ne(e, o = {}) {
203
- const { autoPlay: n = !1, muted: t = !0, loop: l = !1, controls: p = !0, startSeconds: i } = o, s = new URLSearchParams({
206
+ const { autoPlay: n = !1, muted: t = !0, loop: l = !1, controls: f = !0, startSeconds: d } = o, a = new URLSearchParams({
204
207
  rel: "0",
205
208
  modestbranding: "1",
206
209
  playsinline: "1",
207
- controls: p ? "1" : "0"
210
+ controls: f ? "1" : "0"
208
211
  });
209
- return n ? (s.set("autoplay", "1"), s.set("mute", "1")) : t && s.set("mute", "1"), l && (s.set("loop", "1"), s.set("playlist", e)), i && i > 0 && s.set("start", String(i)), `https://www.youtube-nocookie.com/embed/${e}?${s.toString()}`;
212
+ return n ? (a.set("autoplay", "1"), a.set("mute", "1")) : t && a.set("mute", "1"), l && (a.set("loop", "1"), a.set("playlist", e)), d && d > 0 && a.set("start", String(d)), `https://www.youtube-nocookie.com/embed/${e}?${a.toString()}`;
210
213
  }
211
214
  const ae = ({
212
215
  src: e,
@@ -214,117 +217,117 @@ const ae = ({
214
217
  showDeviceToggle: n = !0,
215
218
  defaultDevice: t = "desktop",
216
219
  hoverPlay: l = !1,
217
- tooltipText: p,
218
- onClose: i,
219
- className: s = "",
220
- muted: b = !0,
221
- loop: C = !1,
222
- controls: a = !1,
223
- autoPlay: c = !1,
224
- frameMaxWidth: f,
225
- aspectRatio: d,
226
- hlsConfig: B,
227
- children: V
220
+ tooltipText: f,
221
+ onClose: d,
222
+ className: a = "",
223
+ muted: c = !0,
224
+ loop: y = !1,
225
+ controls: C = !1,
226
+ autoPlay: s = !1,
227
+ frameMaxWidth: u,
228
+ aspectRatio: i,
229
+ hlsConfig: R,
230
+ children: T
228
231
  }) => {
229
- const m = H(null), k = H(null), [h, E] = T(t), [_, g] = T(!1), [z, L] = T(!1), N = I(() => te(e), [e]), v = N !== null, Y = I(() => h === "mobile" ? (d == null ? void 0 : d.mobile) ?? "9/16" : (d == null ? void 0 : d.desktop) ?? "16/9", [h, d]), D = I(() => h === "mobile" ? (f == null ? void 0 : f.mobile) ?? "420px" : (f == null ? void 0 : f.desktop) ?? "960px", [h, f]), J = I(
232
+ const w = H(null), k = H(null), [h, j] = $(t), [V, g] = $(!1), [z, L] = $(!1), N = I(() => te(e), [e]), v = N !== null, D = I(() => h === "mobile" ? (i == null ? void 0 : i.mobile) ?? "9/16" : (i == null ? void 0 : i.desktop) ?? "16/9", [h, i]), Y = I(() => h === "mobile" ? (u == null ? void 0 : u.mobile) ?? "420px" : (u == null ? void 0 : u.desktop) ?? "960px", [h, u]), A = I(
230
233
  () => N ? ne(N, {
231
- autoPlay: c,
232
- muted: b,
233
- loop: C,
234
- controls: a,
234
+ autoPlay: s,
235
+ muted: c,
236
+ loop: y,
237
+ controls: C,
235
238
  startSeconds: re(e)
236
239
  }) : null,
237
- [N, e, c, b, C, a]
238
- ), S = w(async () => {
239
- const u = m.current;
240
- if (u) {
240
+ [N, e, s, c, y, C]
241
+ ), S = b(async () => {
242
+ const p = w.current;
243
+ if (p) {
241
244
  if (k.current)
242
245
  try {
243
246
  await k.current;
244
247
  } catch {
245
248
  }
246
- u.pause();
249
+ p.pause();
247
250
  }
248
- }, []), P = w(async () => {
249
- const u = m.current;
250
- if (u)
251
+ }, []), P = b(async () => {
252
+ const p = w.current;
253
+ if (p)
251
254
  try {
252
- u.readyState < 2 && u.load();
253
- const j = u.play();
254
- k.current = j, await j, g(!0);
255
+ p.readyState < 2 && p.load();
256
+ const x = p.play();
257
+ k.current = x, await x, g(!0);
255
258
  } catch {
256
259
  g(!1);
257
260
  } finally {
258
261
  k.current = null;
259
262
  }
260
- }, []), O = w(() => {
263
+ }, []), J = b(() => {
261
264
  !l || v || P();
262
- }, [l, v, P]), W = w(() => {
265
+ }, [l, v, P]), O = b(() => {
263
266
  !l || v || S().then(() => g(!1));
264
- }, [l, v, S]), X = w(async () => {
265
- const u = m.current;
266
- u && (u.paused ? await P() : (await S(), g(!1)));
267
+ }, [l, v, S]), W = b(async () => {
268
+ const p = w.current;
269
+ p && (p.paused ? await P() : (await S(), g(!1)));
267
270
  }, [P, S]);
268
271
  return (
269
272
  // The mouse handlers are a progressive enhancement (hoverPlay + tooltip).
270
273
  // Keyboard/click users reach the same actions via the inner <button> elements,
271
274
  // so the outer container is intentionally non-interactive at the role level.
272
275
  // NOSONAR: typescript:S6848
273
- /* @__PURE__ */ y(
276
+ /* @__PURE__ */ m(
274
277
  "div",
275
278
  {
276
- className: Z("gvp-root", s),
277
- style: { width: D, aspectRatio: Y },
279
+ className: Z("gvp-root", a),
280
+ style: { width: Y, aspectRatio: D },
278
281
  onMouseEnter: () => {
279
- L(!0), O();
282
+ L(!0), J();
280
283
  },
281
284
  onMouseLeave: () => {
282
- L(!1), W();
285
+ L(!1), O();
283
286
  },
284
287
  children: [
285
288
  v ? /* @__PURE__ */ r(
286
289
  "iframe",
287
290
  {
288
291
  className: "gvp-video gvp-youtube",
289
- src: J ?? void 0,
292
+ src: A ?? void 0,
290
293
  title: "YouTube video player",
291
294
  allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
292
295
  allowFullScreen: !0,
293
296
  referrerPolicy: "strict-origin-when-cross-origin"
294
297
  }
295
298
  ) : /* @__PURE__ */ r(
296
- U,
299
+ B,
297
300
  {
298
- ref: m,
301
+ ref: w,
299
302
  src: e,
300
303
  poster: o,
301
- muted: b,
302
- loop: C,
304
+ muted: c,
305
+ loop: y,
303
306
  playsInline: !0,
304
307
  preload: "metadata",
305
- controls: a,
306
- autoPlay: c,
307
- hlsConfig: B,
308
+ controls: C,
309
+ autoPlay: s,
310
+ hlsConfig: R,
308
311
  className: "gvp-video",
309
312
  onPlay: () => g(!0),
310
313
  onPause: () => g(!1),
311
- children: V
314
+ children: T
312
315
  }
313
316
  ),
314
317
  !v && /* @__PURE__ */ r("div", { className: "gvp-vignette" }),
315
- n && /* @__PURE__ */ r("div", { className: "gvp-toggle", children: /* @__PURE__ */ y("div", { className: "gvp-toggle-pill", children: [
318
+ n && /* @__PURE__ */ r("div", { className: "gvp-toggle", children: /* @__PURE__ */ m("div", { className: "gvp-toggle-pill", children: [
316
319
  /* @__PURE__ */ r(
317
320
  "button",
318
321
  {
319
322
  type: "button",
320
- onClick: () => E("desktop"),
323
+ onClick: () => j("desktop"),
321
324
  className: Z(
322
325
  "gvp-toggle-btn",
323
326
  h === "desktop" && "is-active"
324
327
  ),
325
328
  "aria-label": "Desktop view",
326
329
  "aria-pressed": h === "desktop",
327
- children: /* @__PURE__ */ r(Q, {})
330
+ children: /* @__PURE__ */ r(K, {})
328
331
  }
329
332
  ),
330
333
  /* @__PURE__ */ r("div", { className: "gvp-toggle-divider" }),
@@ -332,39 +335,39 @@ const ae = ({
332
335
  "button",
333
336
  {
334
337
  type: "button",
335
- onClick: () => E("mobile"),
338
+ onClick: () => j("mobile"),
336
339
  className: Z(
337
340
  "gvp-toggle-btn",
338
341
  h === "mobile" && "is-active"
339
342
  ),
340
343
  "aria-label": "Mobile view",
341
344
  "aria-pressed": h === "mobile",
342
- children: /* @__PURE__ */ r(A, {})
345
+ children: /* @__PURE__ */ r(Q, {})
343
346
  }
344
347
  )
345
348
  ] }) }),
346
- i && /* @__PURE__ */ r(
349
+ d && /* @__PURE__ */ r(
347
350
  "button",
348
351
  {
349
352
  type: "button",
350
- onClick: i,
353
+ onClick: d,
351
354
  className: "gvp-close",
352
355
  "aria-label": "Close",
353
356
  children: /* @__PURE__ */ r(F, {})
354
357
  }
355
358
  ),
356
- !v && !_ && /* @__PURE__ */ r("div", { className: "gvp-play-wrap", children: /* @__PURE__ */ y(
359
+ !v && !V && /* @__PURE__ */ r("div", { className: "gvp-play-wrap", children: /* @__PURE__ */ m(
357
360
  "button",
358
361
  {
359
362
  type: "button",
360
- onClick: () => void X(),
363
+ onClick: () => void W(),
361
364
  onMouseEnter: () => L(!0),
362
365
  onMouseLeave: () => L(!1),
363
366
  className: "gvp-play",
364
367
  "aria-label": "Play",
365
368
  children: [
366
369
  /* @__PURE__ */ r(ee, {}),
367
- p && z && /* @__PURE__ */ r("span", { className: "gvp-tooltip", role: "tooltip", children: p })
370
+ f && z && /* @__PURE__ */ r("span", { className: "gvp-tooltip", role: "tooltip", children: f })
368
371
  ]
369
372
  }
370
373
  ) }),
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/HLSPlayer.tsx","../src/utils/icons.tsx","../src/utils/youtube.ts","../src/VideoPlayerWrapper.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","\"use client\";\n\nimport Hls from \"hls.js\";\nimport React, { useEffect, useImperativeHandle, useRef } from \"react\";\nimport type { HLSPlayerProps } from \"./types\";\n\nexport const HLSPlayer = React.forwardRef<HTMLVideoElement, HLSPlayerProps>(\n ({ src, hlsConfig, isHls, children, ...videoProps }, forwardedRef) => {\n const internalRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLVideoElement);\n\n const canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\n const shouldUseHls =\n Boolean(isHls) || (canUseHlsJs && typeof src === \"string\" && src.endsWith(\".m3u8\"));\n\n useEffect(() => {\n if (!src) return;\n const videoEl = internalRef.current;\n if (!videoEl) return;\n\n // destroy previous\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n\n // reset video element\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n\n if (shouldUseHls) {\n const hls = new Hls(hlsConfig);\n hlsRef.current = hls;\n\n hls.attachMedia(videoEl);\n hls.loadSource(src);\n\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsRef.current = null;\n }\n });\n } else {\n // native playback\n videoEl.src = src;\n videoEl.load();\n }\n\n return () => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n videoEl.load();\n };\n }, [src, shouldUseHls, hlsConfig]);\n\n // Captions are the consumer's responsibility — pass <track> elements as children.\n // NOSONAR: typescript:S4084\n return (\n <video ref={internalRef} {...videoProps}>\n {children}\n </video>\n );\n }\n);\n\nHLSPlayer.displayName = \"HLSPlayer\";\nexport default HLSPlayer;\n","\"use client\";\n\nimport React from \"react\";\n\ntype IconProps = { className?: string };\n\nconst baseClass = \"gvp-icon\";\nconst cls = (extra?: string) => (extra ? `${baseClass} ${extra}` : baseClass);\n\nexport const IconDesktop: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path d=\"M7 22H17\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const IconMobile: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const IconX: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport const IconPlay: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n // Bare 11-char ID (YouTube IDs are [A-Za-z0-9_-]{11}).\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n // /watch?v=ID\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n // /embed/ID, /shorts/ID, /v/ID, /live/ID\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n // Supports \"90\", \"90s\", \"1m30s\", \"1h2m3s\".\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(id: string, opts: YouTubeEmbedOptions = {}): string {\n const { autoPlay = false, muted = true, loop = false, controls = true, startSeconds } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\",\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","\"use client\";\n\nimport clsx from \"clsx\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { HLSPlayer } from \"./HLSPlayer\";\nimport type { DeviceMode, VideoPlayerWrapperProps } from \"./types\";\nimport { IconDesktop, IconMobile, IconPlay, IconX } from \"./utils/icons\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nexport const VideoPlayerWrapper: React.FC<VideoPlayerWrapperProps> = ({\n src,\n poster,\n showDeviceToggle = true,\n defaultDevice = \"desktop\",\n hoverPlay = false,\n tooltipText,\n onClose,\n className = \"\",\n muted = true,\n loop = false,\n controls = false,\n autoPlay = false,\n frameMaxWidth: customFrameMaxWidth,\n aspectRatio: customAspectRatio,\n hlsConfig,\n children,\n}) => {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playPromiseRef = useRef<Promise<void> | null>(null);\n\n const [device, setDevice] = useState<DeviceMode>(defaultDevice);\n const [isPlaying, setIsPlaying] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const youTubeId = useMemo(() => parseYouTubeId(src), [src]);\n const isYouTube = youTubeId !== null;\n\n const aspectRatio = useMemo(() => {\n return device === \"mobile\"\n ? (customAspectRatio?.mobile ?? \"9/16\")\n : (customAspectRatio?.desktop ?? \"16/9\");\n }, [device, customAspectRatio]);\n\n const frameMaxWidth = useMemo(() => {\n return device === \"mobile\"\n ? (customFrameMaxWidth?.mobile ?? \"420px\")\n : (customFrameMaxWidth?.desktop ?? \"960px\");\n }, [device, customFrameMaxWidth]);\n\n const youTubeSrc = useMemo(\n () =>\n youTubeId\n ? youTubeEmbedUrl(youTubeId, {\n autoPlay,\n muted,\n loop,\n controls,\n startSeconds: parseYouTubeStart(src),\n })\n : null,\n [youTubeId, src, autoPlay, muted, loop, controls]\n );\n\n const safePause = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (playPromiseRef.current) {\n try {\n await playPromiseRef.current;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n }, []);\n\n const safePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromiseRef.current = p;\n await p;\n setIsPlaying(true);\n } catch {\n setIsPlaying(false);\n } finally {\n playPromiseRef.current = null;\n }\n }, []);\n\n const hoverStart = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePlay();\n }, [hoverPlay, isYouTube, safePlay]);\n\n const hoverStop = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePause().then(() => setIsPlaying(false));\n }, [hoverPlay, isYouTube, safePause]);\n\n const togglePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n setIsPlaying(false);\n }\n }, [safePlay, safePause]);\n\n return (\n // The mouse handlers are a progressive enhancement (hoverPlay + tooltip).\n // Keyboard/click users reach the same actions via the inner <button> elements,\n // so the outer container is intentionally non-interactive at the role level.\n // NOSONAR: typescript:S6848\n <div\n className={clsx(\"gvp-root\", className)}\n style={{ width: frameMaxWidth, aspectRatio }}\n onMouseEnter={() => {\n setShowTooltip(true);\n hoverStart();\n }}\n onMouseLeave={() => {\n setShowTooltip(false);\n hoverStop();\n }}\n >\n {isYouTube ? (\n <iframe\n className=\"gvp-video gvp-youtube\"\n src={youTubeSrc ?? undefined}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n />\n ) : (\n <HLSPlayer\n ref={videoRef}\n src={src}\n poster={poster}\n muted={muted}\n loop={loop}\n playsInline\n preload=\"metadata\"\n controls={controls}\n autoPlay={autoPlay}\n hlsConfig={hlsConfig}\n className=\"gvp-video\"\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n >\n {children}\n </HLSPlayer>\n )}\n\n {!isYouTube && <div className=\"gvp-vignette\" />}\n\n {showDeviceToggle && (\n <div className=\"gvp-toggle\">\n <div className=\"gvp-toggle-pill\">\n <button\n type=\"button\"\n onClick={() => setDevice(\"desktop\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"desktop\" && \"is-active\"\n )}\n aria-label=\"Desktop view\"\n aria-pressed={device === \"desktop\"}\n >\n <IconDesktop />\n </button>\n\n <div className=\"gvp-toggle-divider\" />\n\n <button\n type=\"button\"\n onClick={() => setDevice(\"mobile\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"mobile\" && \"is-active\"\n )}\n aria-label=\"Mobile view\"\n aria-pressed={device === \"mobile\"}\n >\n <IconMobile />\n </button>\n </div>\n </div>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"gvp-close\"\n aria-label=\"Close\"\n >\n <IconX />\n </button>\n )}\n\n {!isYouTube && !isPlaying && (\n <div className=\"gvp-play-wrap\">\n <button\n type=\"button\"\n onClick={() => void togglePlay()}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n className=\"gvp-play\"\n aria-label=\"Play\"\n >\n <IconPlay />\n {tooltipText && showTooltip && (\n <span className=\"gvp-tooltip\" role=\"tooltip\">\n {tooltipText}\n </span>\n )}\n </button>\n </div>\n )}\n\n {!isYouTube && <div className=\"gvp-bottom-fade\" />}\n </div>\n );\n};\n\nexport default VideoPlayerWrapper;\n"],"names":["r","t","f","n","o","clsx","HLSPlayer","React","src","hlsConfig","isHls","children","videoProps","forwardedRef","internalRef","useRef","hlsRef","useImperativeHandle","canUseHlsJs","Hls","shouldUseHls","useEffect","videoEl","hls","_evt","data","baseClass","cls","extra","IconDesktop","className","jsxs","jsx","IconMobile","IconX","IconPlay","parseYouTubeId","input","url","host","id","v","m","parseYouTubeStart","h","min","s","total","youTubeEmbedUrl","opts","autoPlay","muted","loop","controls","startSeconds","params","VideoPlayerWrapper","poster","showDeviceToggle","defaultDevice","hoverPlay","tooltipText","onClose","customFrameMaxWidth","customAspectRatio","videoRef","playPromiseRef","device","setDevice","useState","isPlaying","setIsPlaying","showTooltip","setShowTooltip","youTubeId","useMemo","isYouTube","aspectRatio","frameMaxWidth","youTubeSrc","safePause","useCallback","el","safePlay","p","hoverStart","hoverStop","togglePlay"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"index.mjs","sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/HLSPlayer.tsx","../src/utils/icons.tsx","../src/utils/youtube.ts","../src/VideoPlayerWrapper.tsx"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","\"use client\";\n\nimport Hls from \"hls.js\";\nimport React, { useEffect, useImperativeHandle, useRef } from \"react\";\nimport type { HLSPlayerProps } from \"./types\";\n\nexport const HLSPlayer = React.forwardRef<HTMLVideoElement, HLSPlayerProps>(\n ({ src, hlsConfig, isHls, autoPlay, children, ...videoProps }, forwardedRef) => {\n const internalRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLVideoElement);\n\n const canUseHlsJs = globalThis.window !== undefined && Hls.isSupported();\n const shouldUseHls =\n Boolean(isHls) || (canUseHlsJs && typeof src === \"string\" && src.endsWith(\".m3u8\"));\n\n useEffect(() => {\n if (!src) return;\n const videoEl = internalRef.current;\n if (!videoEl) return;\n\n // Tries to start playback once the stream is ready. Browsers only\n // honor sound-on autoplay after a user gesture, so this is best\n // effort — silently swallows the NotAllowedError when blocked.\n const tryAutoPlay = () => {\n if (!autoPlay) return;\n videoEl.play().catch(() => {\n /* autoplay blocked; user gesture required */\n });\n };\n\n // destroy previous\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n\n // reset video element\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n\n if (shouldUseHls) {\n const hls = new Hls(hlsConfig);\n hlsRef.current = hls;\n\n hls.attachMedia(videoEl);\n hls.loadSource(src);\n\n hls.on(Hls.Events.MANIFEST_PARSED, tryAutoPlay);\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (data.fatal) {\n hls.destroy();\n hlsRef.current = null;\n }\n });\n } else {\n // native playback\n videoEl.src = src;\n videoEl.load();\n // For a plain <video>, we wait for metadata so play() has\n // something to start.\n videoEl.addEventListener(\"loadedmetadata\", tryAutoPlay, { once: true });\n }\n\n return () => {\n videoEl.removeEventListener(\"loadedmetadata\", tryAutoPlay);\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n videoEl.pause();\n videoEl.removeAttribute(\"src\");\n while (videoEl.firstChild) videoEl.firstChild.remove();\n videoEl.load();\n };\n }, [src, shouldUseHls, hlsConfig, autoPlay]);\n\n // Captions are the consumer's responsibility — pass <track> elements as children.\n // NOSONAR: typescript:S4084\n return (\n <video ref={internalRef} {...videoProps}>\n {children}\n </video>\n );\n }\n);\n\nHLSPlayer.displayName = \"HLSPlayer\";\nexport default HLSPlayer;\n","\"use client\";\n\nimport React from \"react\";\n\ntype IconProps = { className?: string };\n\nconst baseClass = \"gvp-icon\";\nconst cls = (extra?: string) => (extra ? `${baseClass} ${extra}` : baseClass);\n\nexport const IconDesktop: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M14 2H10C6.72077 2 5.08116 2 3.91891 2.81382C3.48891 3.1149 3.1149 3.48891 2.81382 3.91891C2 5.08116 2 6.72077 2 10C2 13.2792 2 14.9188 2.81382 16.0811C3.1149 16.5111 3.48891 16.8851 3.91891 17.1862C5.08116 18 6.72077 18 10 18H14C17.2792 18 18.9188 18 20.0811 17.1862C20.5111 16.8851 20.8851 16.5111 21.1862 16.0811C22 14.9188 22 13.2792 22 10C22 6.72077 22 5.08116 21.1862 3.91891C20.8851 3.48891 20.5111 3.1149 20.0811 2.81382C18.9188 2 17.2792 2 14 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 15H13\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14.5 22L14.1845 21.5811C13.4733 20.6369 13.2969 19.1944 13.7468 18M9.5 22L9.8155 21.5811C10.5267 20.6369 10.7031 19.1944 10.2532 18\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <path d=\"M7 22H17\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const IconMobile: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5 9C5 5.70017 5 4.05025 6.02513 3.02513C7.05025 2 8.70017 2 12 2C15.2998 2 16.9497 2 17.9749 3.02513C19 4.05025 19 5.70017 19 9V15C19 18.2998 19 19.9497 17.9749 20.9749C16.9497 22 15.2998 22 12 22C8.70017 22 7.05025 22 6.02513 20.9749C5 19.9497 5 18.2998 5 15V9Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M11 19H13\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M9 2L9.089 2.53402C9.28188 3.69129 9.37832 4.26993 9.77519 4.62204C10.1892 4.98934 10.7761 5 12 5C13.2239 5 13.8108 4.98934 14.2248 4.62204C14.6217 4.26993 14.7181 3.69129 14.911 2.53402L15 2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const IconX: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.94994 5.53594L12.1929 0.292938C12.5834 -0.0975275 13.2165 -0.0975279 13.6069 0.292938C13.9974 0.683403 13.9974 1.31647 13.6069 1.70694L8.36394 6.94994L13.6069 12.1929C13.9974 12.5834 13.9974 13.2165 13.6069 13.6069C13.2165 13.9974 12.5834 13.9974 12.1929 13.6069L6.94994 8.36394L1.70694 13.6069C1.31647 13.9974 0.683403 13.9974 0.292938 13.6069C-0.0975279 13.2165 -0.0975277 12.5834 0.292938 12.1929L5.53594 6.94994L0.292938 1.70694C-0.0975279 1.31647 -0.0975279 0.683403 0.292938 0.292938C0.683403 -0.0975279 1.31647 -0.0975277 1.70694 0.292938L6.94994 5.53594Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport const IconPlay: React.FC<IconProps> = ({ className }) => (\n <svg\n className={cls(className)}\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.3335 11.45V4.54997C5.3335 4.36108 5.40016 4.20275 5.5335 4.07497C5.66683 3.94719 5.82238 3.8833 6.00016 3.8833C6.05572 3.8833 6.11405 3.89163 6.17516 3.9083C6.23627 3.92497 6.29461 3.94997 6.35016 3.9833L11.7835 7.4333C11.8835 7.49997 11.9585 7.5833 12.0085 7.6833C12.0585 7.7833 12.0835 7.88886 12.0835 7.99997C12.0835 8.11108 12.0585 8.21663 12.0085 8.31663C11.9585 8.41663 11.8835 8.49997 11.7835 8.56663L6.35016 12.0166C6.29461 12.05 6.23627 12.075 6.17516 12.0916C6.11405 12.1083 6.05572 12.1166 6.00016 12.1166C5.82238 12.1166 5.66683 12.0527 5.5335 11.925C5.40016 11.7972 5.3335 11.6389 5.3335 11.45Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n","/**\n * Extract a YouTube video ID from any common URL form, or `null` if the URL\n * isn't a YouTube link.\n *\n * Recognised:\n * - https://www.youtube.com/watch?v=ID\n * - https://youtube.com/watch?v=ID&t=42\n * - https://youtu.be/ID\n * - https://youtu.be/ID?t=42\n * - https://www.youtube.com/embed/ID\n * - https://www.youtube.com/shorts/ID\n * - https://music.youtube.com/watch?v=ID\n * - bare 11-character video IDs\n */\nexport function parseYouTubeId(input: string): string | null {\n if (!input) return null;\n\n // Bare 11-char ID (YouTube IDs are [A-Za-z0-9_-]{11}).\n if (/^[A-Za-z0-9_-]{11}$/.test(input)) return input;\n\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n return null;\n }\n\n const host = url.hostname.replace(/^www\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.slice(1).split(\"/\")[0];\n return /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null;\n }\n\n if (\n host === \"youtube.com\" ||\n host === \"m.youtube.com\" ||\n host === \"music.youtube.com\" ||\n host === \"youtube-nocookie.com\"\n ) {\n // /watch?v=ID\n const v = url.searchParams.get(\"v\");\n if (v && /^[A-Za-z0-9_-]{11}$/.test(v)) return v;\n\n // /embed/ID, /shorts/ID, /v/ID, /live/ID\n const m = /^\\/(?:embed|shorts|v|live)\\/([A-Za-z0-9_-]{11})/.exec(\n url.pathname\n );\n if (m) return m[1];\n }\n\n return null;\n}\n\n/** Extract a `t`/`start` timestamp (in seconds) from a YouTube URL, if present. */\nexport function parseYouTubeStart(input: string): number | null {\n try {\n const url = new URL(input);\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n if (!t) return null;\n // Supports \"90\", \"90s\", \"1m30s\", \"1h2m3s\".\n if (/^\\d+s?$/.test(t)) return Number.parseInt(t, 10);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(t);\n if (m) {\n const h = Number.parseInt(m[1] ?? \"0\", 10);\n const min = Number.parseInt(m[2] ?? \"0\", 10);\n const s = Number.parseInt(m[3] ?? \"0\", 10);\n const total = h * 3600 + min * 60 + s;\n return total > 0 ? total : null;\n }\n } catch {\n /* not a URL */\n }\n return null;\n}\n\nexport interface YouTubeEmbedOptions {\n /** Start playback immediately. Forces `mute` on, since browsers block sound-on autoplay. */\n autoPlay?: boolean;\n /** Mute the player. */\n muted?: boolean;\n /** Loop the video. */\n loop?: boolean;\n /** Show YouTube's player controls. Defaults to `true`. */\n controls?: boolean;\n /** Start offset in seconds. */\n startSeconds?: number | null;\n}\n\n/**\n * Build a privacy-enhanced YouTube embed URL from a video ID and player options.\n *\n * Notes on YouTube's quirks:\n * - `autoplay=1` only takes effect if `mute=1` is also set (browser policy).\n * - single-video loop requires `loop=1` **and** `playlist=<id>`.\n */\nexport function youTubeEmbedUrl(id: string, opts: YouTubeEmbedOptions = {}): string {\n const { autoPlay = false, muted = true, loop = false, controls = true, startSeconds } = opts;\n\n const params = new URLSearchParams({\n rel: \"0\",\n modestbranding: \"1\",\n playsinline: \"1\",\n controls: controls ? \"1\" : \"0\",\n });\n\n if (autoPlay) {\n params.set(\"autoplay\", \"1\");\n params.set(\"mute\", \"1\"); // required for autoplay to actually fire\n } else if (muted) {\n params.set(\"mute\", \"1\");\n }\n\n if (loop) {\n params.set(\"loop\", \"1\");\n params.set(\"playlist\", id); // YouTube needs this for single-video loop\n }\n\n if (startSeconds && startSeconds > 0) {\n params.set(\"start\", String(startSeconds));\n }\n\n return `https://www.youtube-nocookie.com/embed/${id}?${params.toString()}`;\n}\n","\"use client\";\n\nimport clsx from \"clsx\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { HLSPlayer } from \"./HLSPlayer\";\nimport type { DeviceMode, VideoPlayerWrapperProps } from \"./types\";\nimport { IconDesktop, IconMobile, IconPlay, IconX } from \"./utils/icons\";\nimport { parseYouTubeId, parseYouTubeStart, youTubeEmbedUrl } from \"./utils/youtube\";\n\nexport const VideoPlayerWrapper: React.FC<VideoPlayerWrapperProps> = ({\n src,\n poster,\n showDeviceToggle = true,\n defaultDevice = \"desktop\",\n hoverPlay = false,\n tooltipText,\n onClose,\n className = \"\",\n muted = true,\n loop = false,\n controls = false,\n autoPlay = false,\n frameMaxWidth: customFrameMaxWidth,\n aspectRatio: customAspectRatio,\n hlsConfig,\n children,\n}) => {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const playPromiseRef = useRef<Promise<void> | null>(null);\n\n const [device, setDevice] = useState<DeviceMode>(defaultDevice);\n const [isPlaying, setIsPlaying] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const youTubeId = useMemo(() => parseYouTubeId(src), [src]);\n const isYouTube = youTubeId !== null;\n\n const aspectRatio = useMemo(() => {\n return device === \"mobile\"\n ? (customAspectRatio?.mobile ?? \"9/16\")\n : (customAspectRatio?.desktop ?? \"16/9\");\n }, [device, customAspectRatio]);\n\n const frameMaxWidth = useMemo(() => {\n return device === \"mobile\"\n ? (customFrameMaxWidth?.mobile ?? \"420px\")\n : (customFrameMaxWidth?.desktop ?? \"960px\");\n }, [device, customFrameMaxWidth]);\n\n const youTubeSrc = useMemo(\n () =>\n youTubeId\n ? youTubeEmbedUrl(youTubeId, {\n autoPlay,\n muted,\n loop,\n controls,\n startSeconds: parseYouTubeStart(src),\n })\n : null,\n [youTubeId, src, autoPlay, muted, loop, controls]\n );\n\n const safePause = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (playPromiseRef.current) {\n try {\n await playPromiseRef.current;\n } catch {\n /* play was interrupted; nothing to await */\n }\n }\n el.pause();\n }, []);\n\n const safePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n try {\n if (el.readyState < 2) el.load();\n const p = el.play();\n playPromiseRef.current = p;\n await p;\n setIsPlaying(true);\n } catch {\n setIsPlaying(false);\n } finally {\n playPromiseRef.current = null;\n }\n }, []);\n\n const hoverStart = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePlay();\n }, [hoverPlay, isYouTube, safePlay]);\n\n const hoverStop = useCallback(() => {\n if (!hoverPlay || isYouTube) return;\n void safePause().then(() => setIsPlaying(false));\n }, [hoverPlay, isYouTube, safePause]);\n\n const togglePlay = useCallback(async () => {\n const el = videoRef.current;\n if (!el) return;\n if (el.paused) {\n await safePlay();\n } else {\n await safePause();\n setIsPlaying(false);\n }\n }, [safePlay, safePause]);\n\n return (\n // The mouse handlers are a progressive enhancement (hoverPlay + tooltip).\n // Keyboard/click users reach the same actions via the inner <button> elements,\n // so the outer container is intentionally non-interactive at the role level.\n // NOSONAR: typescript:S6848\n <div\n className={clsx(\"gvp-root\", className)}\n style={{ width: frameMaxWidth, aspectRatio }}\n onMouseEnter={() => {\n setShowTooltip(true);\n hoverStart();\n }}\n onMouseLeave={() => {\n setShowTooltip(false);\n hoverStop();\n }}\n >\n {isYouTube ? (\n <iframe\n className=\"gvp-video gvp-youtube\"\n src={youTubeSrc ?? undefined}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n />\n ) : (\n <HLSPlayer\n ref={videoRef}\n src={src}\n poster={poster}\n muted={muted}\n loop={loop}\n playsInline\n preload=\"metadata\"\n controls={controls}\n autoPlay={autoPlay}\n hlsConfig={hlsConfig}\n className=\"gvp-video\"\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n >\n {children}\n </HLSPlayer>\n )}\n\n {!isYouTube && <div className=\"gvp-vignette\" />}\n\n {showDeviceToggle && (\n <div className=\"gvp-toggle\">\n <div className=\"gvp-toggle-pill\">\n <button\n type=\"button\"\n onClick={() => setDevice(\"desktop\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"desktop\" && \"is-active\"\n )}\n aria-label=\"Desktop view\"\n aria-pressed={device === \"desktop\"}\n >\n <IconDesktop />\n </button>\n\n <div className=\"gvp-toggle-divider\" />\n\n <button\n type=\"button\"\n onClick={() => setDevice(\"mobile\")}\n className={clsx(\n \"gvp-toggle-btn\",\n device === \"mobile\" && \"is-active\"\n )}\n aria-label=\"Mobile view\"\n aria-pressed={device === \"mobile\"}\n >\n <IconMobile />\n </button>\n </div>\n </div>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"gvp-close\"\n aria-label=\"Close\"\n >\n <IconX />\n </button>\n )}\n\n {!isYouTube && !isPlaying && (\n <div className=\"gvp-play-wrap\">\n <button\n type=\"button\"\n onClick={() => void togglePlay()}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n className=\"gvp-play\"\n aria-label=\"Play\"\n >\n <IconPlay />\n {tooltipText && showTooltip && (\n <span className=\"gvp-tooltip\" role=\"tooltip\">\n {tooltipText}\n </span>\n )}\n </button>\n </div>\n )}\n\n {!isYouTube && <div className=\"gvp-bottom-fade\" />}\n </div>\n );\n};\n\nexport default VideoPlayerWrapper;\n"],"names":["r","t","f","n","o","clsx","HLSPlayer","React","src","hlsConfig","isHls","autoPlay","children","videoProps","forwardedRef","internalRef","useRef","hlsRef","useImperativeHandle","canUseHlsJs","Hls","shouldUseHls","useEffect","videoEl","tryAutoPlay","hls","_evt","data","baseClass","cls","extra","IconDesktop","className","jsxs","jsx","IconMobile","IconX","IconPlay","parseYouTubeId","input","url","host","id","v","m","parseYouTubeStart","h","min","s","total","youTubeEmbedUrl","opts","muted","loop","controls","startSeconds","params","VideoPlayerWrapper","poster","showDeviceToggle","defaultDevice","hoverPlay","tooltipText","onClose","customFrameMaxWidth","customAspectRatio","videoRef","playPromiseRef","device","setDevice","useState","isPlaying","setIsPlaying","showTooltip","setShowTooltip","youTubeId","useMemo","isYouTube","aspectRatio","frameMaxWidth","youTubeSrc","safePause","useCallback","el","safePlay","p","hoverStart","hoverStop","togglePlay"],"mappings":"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","x_google_ignoreList":[0]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glitchlab/react-video-player",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "React video player with HLS support (hls.js), device-mode toggle, hover-to-play, and zero global CSS side-effects. Works with Next.js App Router and TypeScript.",
5
5
  "license": "MIT",
6
6
  "author": "im-fahad",