seg-cam 0.4.8 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Q=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var De=(e,n)=>{for(var u in n)Q(e,u,{get:n[u],enumerable:!0})},be=(e,n,u,T)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of Te(n))!Ee.call(e,s)&&s!==u&&Q(e,s,{get:()=>n[s],enumerable:!(T=he(n,s))||T.enumerable});return e};var ke=e=>be(Q({},"__esModule",{value:!0}),e);var O=(e,n,u)=>new Promise((T,s)=>{var x=l=>{try{I(u.next(l))}catch(w){s(w)}},b=l=>{try{I(u.throw(l))}catch(w){s(w)}},I=l=>l.done?T(l.value):Promise.resolve(l.value).then(x,b);I((u=u.apply(e,n)).next())});var Re={};De(Re,{DEFAULT_CONFIG:()=>c,JerseyDetector:()=>re,useJerseyWorker:()=>z});module.exports=ke(Re);var t=require("react");var g=require("react");var f=null,S=!1,G=null,Z=0,ee=null,D=new Map,Ie=0,$=new Map;function z(e,n){let u=(0,g.useRef)(!1),[T,s]=(0,g.useState)(!1),[x,b]=(0,g.useState)(null),I=(0,g.useRef)(!0),l=(0,g.useRef)(!1),w=(0,g.useRef)(`instance_${Math.random().toString(36).substr(2,9)}`),A=(0,g.useRef)(0);(0,g.useEffect)(()=>{var _;if(!e)return;I.current=!0,A.current++;let v=A.current,C=w.current,H=(_=$.get(C))!=null?_:0;return v>H&&(Z++,$.set(C,v)),O(null,null,function*(){var p;if(!f||!we(ee,e)){f&&(f.terminate(),f=null,S=!1);try{l.current=(p=e.verbose)!=null?p:l.current;let a=n||"/jersey-detector-worker.js";f=new Worker(a),ee=e,S=!1,G=null,s(!1),b(null),f.onmessage=y=>{let i=y.data;switch(i.type){case"ready":S=!0,s(!0);break;case"loading_progress":l.current&&console.log(`[v0 useJerseyWorker] Loaded ${i.progress}% of ${i.file}`);break;case"debug":l.current&&console.log(i.debug_message);break;case"error":let M=i.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",M),S=!1,G=M,s(!1),b(M);break;case"detect_response":if(i.requestId&&D.has(i.requestId)){let E=D.get(i.requestId);E&&(E.resolve(i),D.delete(i.requestId))}else if(D.size>0){let E=D.entries().next();if(!E.done){let[J,N]=E.value;N.resolve(i),D.delete(J)}}break}},f.onerror=y=>{let i=y.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",i),S=!1,G=i,s(!1),b(i)},f.postMessage({type:"init",config:e})}catch(a){let y=(a==null?void 0:a.message)||String(a);console.error("[useJerseyWorker] Failed to create worker:",y),s(!1),b(y)}}else s(S),b(G)}),()=>{I.current=!1;let p=w.current,a=$.get(p),y=A.current;a===y&&(Z--,$.delete(p),Z<=0&&f&&(f.terminate(),f=null,S=!1,G=null,ee=null,D.clear()))}},[]);let V=(0,g.useCallback)((v,C,H=.5)=>O(null,null,function*(){if(!f||!S)throw new Error("Worker not ready");if(u.current)return null;let R=`req_${++Ie}_${Date.now()}`;return new Promise((_,p)=>{D.set(R,{resolve:_,reject:p});try{u.current=!0,f.postMessage({type:"detect",requestId:R,dimensions:C,bitmap:v,threshold:H},[v])}catch(a){D.delete(R);let y=`Failed to send detect: ${a==null?void 0:a.message}`;p(new Error(y))}finally{u.current=!1}setTimeout(()=>{D.has(R)&&(D.delete(R),p(new Error("Detection timeout")))},1e4)})}),[T]);return{isReady:T,workerReady:T,lastError:x,detect:V}}function we(e,n){return e?JSON.stringify(e)===JSON.stringify(n):!1}var c={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1};var ue=require("react/jsx-runtime"),re=(0,t.forwardRef)(({videoRef:e,onWorkerReady:n,onWorkerError:u,onStatsUpdate:T,onSegmentedImage:s,task:x=c.TASK,model:b=c.MODEL,verbose:I=c.VERBOSE,bodyPixArchitecture:l=c.BODYPIX_ARCHITECTURE,bodyPixMultiplier:w=c.BODYPIX_MULTIPLIER,bodyPixQuantBytes:A=c.BODYPIX_QUANT_BYTES,bodyPixStride:V=c.BODYPIX_STRIDE,multiSegmentation:v=c.MULTI_SEGMENTATION,segmentBodyParts:C=c.SEGMENT_BODY_PARTS,backgroundShade:H=c.BACKGROUND_SHADE,shirtShade:R=c.SHIRT_SHADE,threshold:_=c.DETECTION_THRESHOLD,targetPartId:p=c.TARGET_PART_ID,imagesToReturn:a=c.IMAGES_TO_RETURN,workerUrl:y},i)=>{var ne,se;let M=(0,t.useRef)(null),E=(0,t.useRef)(null),J=(0,t.useRef)(!1),N=(0,t.useRef)([]),le=(0,t.useRef)(null),L=(0,t.useRef)(!1),Y=(0,t.useRef)(void 0);Y.current=u;let K=(0,t.useRef)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),te=(0,t.useRef)(0),me=500,de=(0,t.useMemo)(()=>({task:x,model:b,verbose:I,bodyPixArchitecture:l,bodyPixMultiplier:w,bodyPixQuantBytes:A,bodyPixStride:V,multiSegmentation:v,segmentBodyParts:C,backgroundShade:H,shirtShade:R,threshold:_,targetPartId:p,imagesToReturn:a}),[x,b,I,l,w,A,V,v,C,H,R,_,p,a]),fe=(0,t.useMemo)(()=>{var r,o;return{width:((r=e.current)==null?void 0:r.videoWidth)||0,height:((o=e.current)==null?void 0:o.videoHeight)||0}},[(ne=e.current)==null?void 0:ne.videoWidth,(se=e.current)==null?void 0:se.videoHeight]),{isReady:P,workerReady:W,lastError:U,detect:ge}=z(de,y);(0,t.useEffect)(()=>{n==null||n(W)},[W,n]),(0,t.useEffect)(()=>{var r;U&&(L.current=!0,(r=Y.current)==null||r.call(Y,U))},[U]);let pe=()=>O(null,null,function*(){var B,oe,ie;let r=e.current,o=M.current;if(L.current||!P||!W||!r||!o||J.current||r.readyState<2||r.paused||r.ended||r.videoWidth===0||r.videoHeight===0)return;let d=o.getContext("2d");if(!d||o.width<=0||o.height<=0)return;let h=null,m=null;try{J.current=!0;let F=r.videoWidth,j=r.videoHeight;le.current={width:F,height:j},h=yield createImageBitmap(r);let k=yield ge(h,fe,_);if((k==null?void 0:k.type)==="detect_response"&&k.bitmap){m=k.bitmap,(o.width!==F||o.height!==j)&&(o.width=F,o.height=j),a==="mask"&&d.clearRect(0,0,F,j),m&&d.drawImage(m,0,0),N.current.push(Date.now()),N.current=N.current.filter(X=>Date.now()-X<1e3);let q={jerseyCount:((B=k.stats)==null?void 0:B.detectionCount)||0,confidence:((oe=k.stats)==null?void 0:oe.averageConfidence)||0,fps:N.current.length,processingTime:((ie=k.stats)==null?void 0:ie.processingTime)||0},ae=K.current;K.current=q;let ce=Date.now();if((ce-te.current>me||q.jerseyCount!==ae.jerseyCount||q.confidence!==ae.confidence)&&T&&(T(q),te.current=ce),k.segmentedImages){let X=k.segmentedImages;O(null,null,function*(){try{yield s==null?void 0:s(X)}finally{X.forEach(ye=>ye.close())}})}}}catch(F){L.current=!0}finally{h==null||h.close(),m==null||m.close(),J.current=!1}});return(0,t.useImperativeHandle)(i,()=>({get isReady(){return P},get lastError(){return U},get stats(){return K.current},capture:(r="image/jpeg",o=.92)=>{let d=e.current,h=M.current;if(!d||d.videoWidth<=0||d.videoHeight<=0)throw new Error("Video not ready for capture");let m=document.createElement("canvas");m.width=d.videoWidth,m.height=d.videoHeight;let B=m.getContext("2d");if(!B)throw new Error("Failed to get context for capture canvas");return B.drawImage(d,0,0,m.width,m.height),h&&h.width>0&&h.height>0?B.drawImage(h,0,0,m.width,m.height):console.warn("[capture] Mask canvas not available \u2014 returning raw video frame"),m.toDataURL(r,o)}}),[P,U,W]),(0,t.useEffect)(()=>{if(!W||!P||L.current)return;let r=e.current,o=M.current;if(!r||!o||r.videoWidth===0||r.videoHeight===0){let h=setTimeout(()=>{E.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(h)}(o.width!==r.videoWidth||o.height!==r.videoHeight)&&(o.width=r.videoWidth,o.height=r.videoHeight);let d=()=>O(null,null,function*(){!W||!P||L.current||(yield pe(),E.current=requestAnimationFrame(d))});return E.current=requestAnimationFrame(d),()=>{E.current&&cancelAnimationFrame(E.current)}},[W,P]),(0,ue.jsx)("canvas",{ref:M,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});re.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
1
+ "use strict";var De=Object.create;var X=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var we=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var ve=(r,s)=>{for(var i in s)X(r,i,{get:s[i],enumerable:!0})},ce=(r,s,i,T)=>{if(s&&typeof s=="object"||typeof s=="function")for(let o of ke(s))!be.call(r,o)&&o!==i&&X(r,o,{get:()=>s[o],enumerable:!(T=Ie(s,o))||T.enumerable});return r};var Re=(r,s,i)=>(i=r!=null?De(we(r)):{},ce(s||!r||!r.__esModule?X(i,"default",{value:r,enumerable:!0}):i,r)),_e=r=>ce(X({},"__esModule",{value:!0}),r);var W=(r,s,i)=>new Promise((T,o)=>{var x=f=>{try{w(i.next(f))}catch(b){o(b)}},I=f=>{try{w(i.throw(f))}catch(b){o(b)}},w=f=>f.done?T(f.value):Promise.resolve(f.value).then(x,I);w((i=i.apply(r,s)).next())});var Se={};ve(Se,{DEFAULT_CONFIG:()=>l,JerseyDetector:()=>ee,useJerseyWorker:()=>z});module.exports=_e(Se);var n=require("react");var p=require("react");var g=null,C=!1,F=null,Q=0,Z=null,D=new Map,Me=0,$=new Map;function z(r,s){let i=(0,p.useRef)(!1),[T,o]=(0,p.useState)(!1),[x,I]=(0,p.useState)(null),w=(0,p.useRef)(!0),f=(0,p.useRef)(!1),b=(0,p.useRef)(`instance_${Math.random().toString(36).substr(2,9)}`),N=(0,p.useRef)(0);(0,p.useEffect)(()=>{var _;if(!r)return;w.current=!0,N.current++;let R=N.current,S=b.current,A=(_=$.get(S))!=null?_:0;return R>A&&(Q++,$.set(S,R)),W(null,null,function*(){var y;if(!g||!Ce(Z,r)){g&&(g.terminate(),g=null,C=!1);try{f.current=(y=r.verbose)!=null?y:f.current;let c=s||"/jersey-detector-worker.js";g=new Worker(c),Z=r,C=!1,F=null,o(!1),I(null),g.onmessage=h=>{let u=h.data;switch(u.type){case"ready":C=!0,o(!0);break;case"loading_progress":f.current&&console.log(`[v0 useJerseyWorker] Loaded ${u.progress}% of ${u.file}`);break;case"debug":f.current&&console.log(u.debug_message);break;case"error":let M=u.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",M),C=!1,F=M,o(!1),I(M);break;case"detect_response":if(u.requestId&&D.has(u.requestId)){let E=D.get(u.requestId);E&&(E.resolve(u),D.delete(u.requestId))}else if(D.size>0){let E=D.entries().next();if(!E.done){let[J,H]=E.value;H.resolve(u),D.delete(J)}}break}},g.onerror=h=>{let u=h.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",u),C=!1,F=u,o(!1),I(u)},g.postMessage({type:"init",config:r})}catch(c){let h=(c==null?void 0:c.message)||String(c);console.error("[useJerseyWorker] Failed to create worker:",h),o(!1),I(h)}}else o(C),I(F)}),()=>{w.current=!1;let y=b.current,c=$.get(y),h=N.current;c===h&&(Q--,$.delete(y),Q<=0&&g&&(g.terminate(),g=null,C=!1,F=null,Z=null,D.clear()))}},[]);let V=(0,p.useCallback)((R,S,A=.5)=>W(null,null,function*(){if(!g||!C)throw new Error("Worker not ready");if(i.current)return null;let v=`req_${++Me}_${Date.now()}`;return new Promise((_,y)=>{D.set(v,{resolve:_,reject:y});try{i.current=!0,g.postMessage({type:"detect",requestId:v,dimensions:S,bitmap:R,threshold:A},[R])}catch(c){D.delete(v);let h=`Failed to send detect: ${c==null?void 0:c.message}`;y(new Error(h))}finally{i.current=!1}setTimeout(()=>{D.has(v)&&(D.delete(v),y(new Error("Detection timeout")))},1e4)})}),[T]);return{isReady:T,workerReady:T,lastError:x,detect:V}}function Ce(r,s){return r?JSON.stringify(r)===JSON.stringify(s):!1}var l={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1};var ue=Re(require("p-limit"));var le=require("react/jsx-runtime"),ee=(0,n.forwardRef)(({videoRef:r,onWorkerReady:s,onWorkerError:i,onStatsUpdate:T,onSegmentedImage:o,task:x=l.TASK,model:I=l.MODEL,verbose:w=l.VERBOSE,bodyPixArchitecture:f=l.BODYPIX_ARCHITECTURE,bodyPixMultiplier:b=l.BODYPIX_MULTIPLIER,bodyPixQuantBytes:N=l.BODYPIX_QUANT_BYTES,bodyPixStride:V=l.BODYPIX_STRIDE,multiSegmentation:R=l.MULTI_SEGMENTATION,segmentBodyParts:S=l.SEGMENT_BODY_PARTS,backgroundShade:A=l.BACKGROUND_SHADE,shirtShade:v=l.SHIRT_SHADE,threshold:_=l.DETECTION_THRESHOLD,targetPartId:y=l.TARGET_PART_ID,imagesToReturn:c=l.IMAGES_TO_RETURN,workerUrl:h},u)=>{let M=(0,n.useRef)(null),E=(0,n.useRef)(null),J=(0,n.useRef)(!1),H=(0,n.useRef)([]),fe=(0,n.useRef)(null),L=(0,n.useRef)(!1),Y=(0,n.useRef)(void 0);Y.current=i;let K=(0,n.useRef)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),re=(0,n.useRef)(0),de=500,te=5,ne=(0,n.useMemo)(()=>(0,ue.default)(te),[]),me=(0,n.useMemo)(()=>({task:x,model:I,verbose:w,bodyPixArchitecture:f,bodyPixMultiplier:b,bodyPixQuantBytes:N,bodyPixStride:V,multiSegmentation:R,segmentBodyParts:S,backgroundShade:A,shirtShade:v,threshold:_,targetPartId:y,imagesToReturn:c}),[x,I,w,f,b,N,V,R,S,A,v,_,y,c]),ge=()=>{var t,e;return{width:((t=r.current)==null?void 0:t.videoWidth)||0,height:((e=r.current)==null?void 0:e.videoHeight)||0}},{isReady:B,workerReady:O,lastError:U,detect:pe}=z(me,h);(0,n.useEffect)(()=>{s==null||s(O)},[O,s]),(0,n.useEffect)(()=>{var t;U&&(L.current=!0,(t=Y.current)==null||t.call(Y,U))},[U]);let ye=(0,n.useCallback)(t=>{if(ne.activeCount>=te){t.forEach(e=>{var a;return(a=e==null?void 0:e.close)==null?void 0:a.call(e)}),console.warn("[JerseyDetector] Dropped new segmented images \u2014 max 5 classifications running");return}ne(()=>W(null,null,function*(){try{yield o==null?void 0:o(t)}catch(e){console.error("[JerseyDetector] Classification error:",e)}finally{t.forEach(e=>{var a;return(a=e==null?void 0:e.close)==null?void 0:a.call(e)})}}))},[o]),he=()=>W(null,null,function*(){var P,se,oe;let t=r.current,e=M.current;if(L.current||!B||!O||!t||!e||J.current||t.readyState<2||t.paused||t.ended||t.videoWidth===0||t.videoHeight===0)return;let a=e.getContext("2d");if(!a||e.width<=0||e.height<=0)return;let m=null,d=null;try{J.current=!0;let G=t.videoWidth,j=t.videoHeight;fe.current={width:G,height:j},m=yield createImageBitmap(t);let Te=ge(),k=yield pe(m,Te,_);if((k==null?void 0:k.type)==="detect_response"){k.bitmap&&c!=="none"&&(d=k.bitmap,(e.width!==G||e.height!==j)&&(e.width=G,e.height=j),a.clearRect(0,0,G,j),c==="mask_with_image"&&a.drawImage(m,0,0),(c==="mask"||c==="mask_with_image")&&a.drawImage(d,0,0)),H.current.push(Date.now()),H.current=H.current.filter(Ee=>Date.now()-Ee<1e3);let q={jerseyCount:((P=k.stats)==null?void 0:P.detectionCount)||0,confidence:((se=k.stats)==null?void 0:se.averageConfidence)||0,fps:H.current.length,processingTime:((oe=k.stats)==null?void 0:oe.processingTime)||0},ae=K.current;K.current=q;let ie=Date.now();(ie-re.current>de||q.jerseyCount!==ae.jerseyCount||q.confidence!==ae.confidence)&&T&&(T(q),re.current=ie),k.segmentedImages&&o&&ye(k.segmentedImages)}}catch(G){L.current=!0}finally{m==null||m.close(),d==null||d.close(),J.current=!1}});return(0,n.useImperativeHandle)(u,()=>({get isReady(){return B},get lastError(){return U},get stats(){return K.current},capture:(t="image/jpeg",e=.92)=>{let a=r.current,m=M.current;if(!a||a.videoWidth<=0||a.videoHeight<=0)throw new Error("Video not ready for capture");let d=document.createElement("canvas");d.width=a.videoWidth,d.height=a.videoHeight;let P=d.getContext("2d");if(!P)throw new Error("Failed to get context for capture canvas");return P.drawImage(a,0,0,d.width,d.height),m&&m.width>0&&m.height>0?P.drawImage(m,0,0,d.width,d.height):console.warn("[capture] Mask canvas not available \u2014 returning raw video frame"),d.toDataURL(t,e)}}),[B,U,O]),(0,n.useEffect)(()=>{if(!O||!B||L.current)return;let t=r.current,e=M.current;if(!t||!e||t.videoWidth===0||t.videoHeight===0){let m=setTimeout(()=>{E.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(m)}(e.width!==t.videoWidth||e.height!==t.videoHeight)&&(e.width=t.videoWidth,e.height=t.videoHeight);let a=()=>W(null,null,function*(){!O||!B||L.current||(yield he(),E.current=requestAnimationFrame(a))});return E.current=requestAnimationFrame(a),()=>{E.current&&cancelAnimationFrame(E.current)}},[O,B]),(0,le.jsx)("canvas",{ref:M,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});ee.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var W=(t,y,h)=>new Promise((w,c)=>{var O=o=>{try{D(h.next(o))}catch(b){c(b)}},T=o=>{try{D(h.throw(o))}catch(b){c(b)}},D=o=>o.done?w(o.value):Promise.resolve(o.value).then(O,T);D((h=h.apply(t,y)).next())});import{forwardRef as ke,useImperativeHandle as Ie,useRef as I,useEffect as ee,useMemo as ue}from"react";import{useEffect as Te,useState as ce,useCallback as Ee,useRef as F}from"react";var l=null,M=!1,G=null,K=0,Q=null,p=new Map,De=0,$=new Map;function Z(t,y){let h=F(!1),[w,c]=ce(!1),[O,T]=ce(null),D=F(!0),o=F(!1),b=F(`instance_${Math.random().toString(36).substr(2,9)}`),x=F(0);Te(()=>{var v;if(!t)return;D.current=!0,x.current++;let R=x.current,S=b.current,A=(v=$.get(S))!=null?v:0;return R>A&&(K++,$.set(S,R)),W(null,null,function*(){var m;if(!l||!be(Q,t)){l&&(l.terminate(),l=null,M=!1);try{o.current=(m=t.verbose)!=null?m:o.current;let s=y||"/jersey-detector-worker.js";l=new Worker(s),Q=t,M=!1,G=null,c(!1),T(null),l.onmessage=d=>{let n=d.data;switch(n.type){case"ready":M=!0,c(!0);break;case"loading_progress":o.current&&console.log(`[v0 useJerseyWorker] Loaded ${n.progress}% of ${n.file}`);break;case"debug":o.current&&console.log(n.debug_message);break;case"error":let _=n.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",_),M=!1,G=_,c(!1),T(_);break;case"detect_response":if(n.requestId&&p.has(n.requestId)){let g=p.get(n.requestId);g&&(g.resolve(n),p.delete(n.requestId))}else if(p.size>0){let g=p.entries().next();if(!g.done){let[B,H]=g.value;H.resolve(n),p.delete(B)}}break}},l.onerror=d=>{let n=d.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",n),M=!1,G=n,c(!1),T(n)},l.postMessage({type:"init",config:t})}catch(s){let d=(s==null?void 0:s.message)||String(s);console.error("[useJerseyWorker] Failed to create worker:",d),c(!1),T(d)}}else c(M),T(G)}),()=>{D.current=!1;let m=b.current,s=$.get(m),d=x.current;s===d&&(K--,$.delete(m),K<=0&&l&&(l.terminate(),l=null,M=!1,G=null,Q=null,p.clear()))}},[]);let V=Ee((R,S,A=.5)=>W(null,null,function*(){if(!l||!M)throw new Error("Worker not ready");if(h.current)return null;let k=`req_${++De}_${Date.now()}`;return new Promise((v,m)=>{p.set(k,{resolve:v,reject:m});try{h.current=!0,l.postMessage({type:"detect",requestId:k,dimensions:S,bitmap:R,threshold:A},[R])}catch(s){p.delete(k);let d=`Failed to send detect: ${s==null?void 0:s.message}`;m(new Error(d))}finally{h.current=!1}setTimeout(()=>{p.has(k)&&(p.delete(k),m(new Error("Detection timeout")))},1e4)})}),[w]);return{isReady:w,workerReady:w,lastError:O,detect:V}}function be(t,y){return t?JSON.stringify(t)===JSON.stringify(y):!1}var a={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1};import{jsx as we}from"react/jsx-runtime";var le=ke(({videoRef:t,onWorkerReady:y,onWorkerError:h,onStatsUpdate:w,onSegmentedImage:c,task:O=a.TASK,model:T=a.MODEL,verbose:D=a.VERBOSE,bodyPixArchitecture:o=a.BODYPIX_ARCHITECTURE,bodyPixMultiplier:b=a.BODYPIX_MULTIPLIER,bodyPixQuantBytes:x=a.BODYPIX_QUANT_BYTES,bodyPixStride:V=a.BODYPIX_STRIDE,multiSegmentation:R=a.MULTI_SEGMENTATION,segmentBodyParts:S=a.SEGMENT_BODY_PARTS,backgroundShade:A=a.BACKGROUND_SHADE,shirtShade:k=a.SHIRT_SHADE,threshold:v=a.DETECTION_THRESHOLD,targetPartId:m=a.TARGET_PART_ID,imagesToReturn:s=a.IMAGES_TO_RETURN,workerUrl:d},n)=>{var te,ne;let _=I(null),g=I(null),B=I(!1),H=I([]),me=I(null),J=I(!1),Y=I(void 0);Y.current=h;let z=I({jerseyCount:0,confidence:0,fps:0,processingTime:0}),re=I(0),de=500,fe=ue(()=>({task:O,model:T,verbose:D,bodyPixArchitecture:o,bodyPixMultiplier:b,bodyPixQuantBytes:x,bodyPixStride:V,multiSegmentation:R,segmentBodyParts:S,backgroundShade:A,shirtShade:k,threshold:v,targetPartId:m,imagesToReturn:s}),[O,T,D,o,b,x,V,R,S,A,k,v,m,s]),ge=ue(()=>{var e,r;return{width:((e=t.current)==null?void 0:e.videoWidth)||0,height:((r=t.current)==null?void 0:r.videoHeight)||0}},[(te=t.current)==null?void 0:te.videoWidth,(ne=t.current)==null?void 0:ne.videoHeight]),{isReady:N,workerReady:C,lastError:L,detect:pe}=Z(fe,d);ee(()=>{y==null||y(C)},[C,y]),ee(()=>{var e;L&&(J.current=!0,(e=Y.current)==null||e.call(Y,L))},[L]);let ye=()=>W(null,null,function*(){var P,se,oe;let e=t.current,r=_.current;if(J.current||!N||!C||!e||!r||B.current||e.readyState<2||e.paused||e.ended||e.videoWidth===0||e.videoHeight===0)return;let u=r.getContext("2d");if(!u||r.width<=0||r.height<=0)return;let f=null,i=null;try{B.current=!0;let U=e.videoWidth,j=e.videoHeight;me.current={width:U,height:j},f=yield createImageBitmap(e);let E=yield pe(f,ge,v);if((E==null?void 0:E.type)==="detect_response"&&E.bitmap){i=E.bitmap,(r.width!==U||r.height!==j)&&(r.width=U,r.height=j),s==="mask"&&u.clearRect(0,0,U,j),i&&u.drawImage(i,0,0),H.current.push(Date.now()),H.current=H.current.filter(X=>Date.now()-X<1e3);let q={jerseyCount:((P=E.stats)==null?void 0:P.detectionCount)||0,confidence:((se=E.stats)==null?void 0:se.averageConfidence)||0,fps:H.current.length,processingTime:((oe=E.stats)==null?void 0:oe.processingTime)||0},ie=z.current;z.current=q;let ae=Date.now();if((ae-re.current>de||q.jerseyCount!==ie.jerseyCount||q.confidence!==ie.confidence)&&w&&(w(q),re.current=ae),E.segmentedImages){let X=E.segmentedImages;W(null,null,function*(){try{yield c==null?void 0:c(X)}finally{X.forEach(he=>he.close())}})}}}catch(U){J.current=!0}finally{f==null||f.close(),i==null||i.close(),B.current=!1}});return Ie(n,()=>({get isReady(){return N},get lastError(){return L},get stats(){return z.current},capture:(e="image/jpeg",r=.92)=>{let u=t.current,f=_.current;if(!u||u.videoWidth<=0||u.videoHeight<=0)throw new Error("Video not ready for capture");let i=document.createElement("canvas");i.width=u.videoWidth,i.height=u.videoHeight;let P=i.getContext("2d");if(!P)throw new Error("Failed to get context for capture canvas");return P.drawImage(u,0,0,i.width,i.height),f&&f.width>0&&f.height>0?P.drawImage(f,0,0,i.width,i.height):console.warn("[capture] Mask canvas not available \u2014 returning raw video frame"),i.toDataURL(e,r)}}),[N,L,C]),ee(()=>{if(!C||!N||J.current)return;let e=t.current,r=_.current;if(!e||!r||e.videoWidth===0||e.videoHeight===0){let f=setTimeout(()=>{g.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(f)}(r.width!==e.videoWidth||r.height!==e.videoHeight)&&(r.width=e.videoWidth,r.height=e.videoHeight);let u=()=>W(null,null,function*(){!C||!N||J.current||(yield ye(),g.current=requestAnimationFrame(u))});return g.current=requestAnimationFrame(u),()=>{g.current&&cancelAnimationFrame(g.current)}},[C,N]),we("canvas",{ref:_,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});le.displayName="JerseyDetector";export{a as DEFAULT_CONFIG,le as JerseyDetector,Z as useJerseyWorker};
1
+ var O=(o,y,h)=>new Promise((b,a)=>{var W=i=>{try{D(h.next(i))}catch(I){a(I)}},T=i=>{try{D(h.throw(i))}catch(I){a(I)}},D=i=>i.done?b(i.value):Promise.resolve(i.value).then(W,T);D((h=h.apply(o,y)).next())});import{forwardRef as we,useImperativeHandle as be,useRef as w,useEffect as Z,useMemo as ce,useCallback as ve}from"react";import{useEffect as Ee,useState as ie,useCallback as De,useRef as G}from"react";var f=null,M=!1,F=null,z=0,K=null,p=new Map,Ie=0,X=new Map;function Q(o,y){let h=G(!1),[b,a]=ie(!1),[W,T]=ie(null),D=G(!0),i=G(!1),I=G(`instance_${Math.random().toString(36).substr(2,9)}`),x=G(0);Ee(()=>{var R;if(!o)return;D.current=!0,x.current++;let v=x.current,C=I.current,N=(R=X.get(C))!=null?R:0;return v>N&&(z++,X.set(C,v)),O(null,null,function*(){var d;if(!f||!ke(K,o)){f&&(f.terminate(),f=null,M=!1);try{i.current=(d=o.verbose)!=null?d:i.current;let n=y||"/jersey-detector-worker.js";f=new Worker(n),K=o,M=!1,F=null,a(!1),T(null),f.onmessage=m=>{let s=m.data;switch(s.type){case"ready":M=!0,a(!0);break;case"loading_progress":i.current&&console.log(`[v0 useJerseyWorker] Loaded ${s.progress}% of ${s.file}`);break;case"debug":i.current&&console.log(s.debug_message);break;case"error":let _=s.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",_),M=!1,F=_,a(!1),T(_);break;case"detect_response":if(s.requestId&&p.has(s.requestId)){let g=p.get(s.requestId);g&&(g.resolve(s),p.delete(s.requestId))}else if(p.size>0){let g=p.entries().next();if(!g.done){let[P,A]=g.value;A.resolve(s),p.delete(P)}}break}},f.onerror=m=>{let s=m.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",s),M=!1,F=s,a(!1),T(s)},f.postMessage({type:"init",config:o})}catch(n){let m=(n==null?void 0:n.message)||String(n);console.error("[useJerseyWorker] Failed to create worker:",m),a(!1),T(m)}}else a(M),T(F)}),()=>{D.current=!1;let d=I.current,n=X.get(d),m=x.current;n===m&&(z--,X.delete(d),z<=0&&f&&(f.terminate(),f=null,M=!1,F=null,K=null,p.clear()))}},[]);let V=De((v,C,N=.5)=>O(null,null,function*(){if(!f||!M)throw new Error("Worker not ready");if(h.current)return null;let k=`req_${++Ie}_${Date.now()}`;return new Promise((R,d)=>{p.set(k,{resolve:R,reject:d});try{h.current=!0,f.postMessage({type:"detect",requestId:k,dimensions:C,bitmap:v,threshold:N},[v])}catch(n){p.delete(k);let m=`Failed to send detect: ${n==null?void 0:n.message}`;d(new Error(m))}finally{h.current=!1}setTimeout(()=>{p.has(k)&&(p.delete(k),d(new Error("Detection timeout")))},1e4)})}),[b]);return{isReady:b,workerReady:b,lastError:W,detect:V}}function ke(o,y){return o?JSON.stringify(o)===JSON.stringify(y):!1}var c={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,IMAGES_TO_RETURN:"mask",VERBOSE:!1};import Re from"p-limit";import{jsx as _e}from"react/jsx-runtime";var ue=we(({videoRef:o,onWorkerReady:y,onWorkerError:h,onStatsUpdate:b,onSegmentedImage:a,task:W=c.TASK,model:T=c.MODEL,verbose:D=c.VERBOSE,bodyPixArchitecture:i=c.BODYPIX_ARCHITECTURE,bodyPixMultiplier:I=c.BODYPIX_MULTIPLIER,bodyPixQuantBytes:x=c.BODYPIX_QUANT_BYTES,bodyPixStride:V=c.BODYPIX_STRIDE,multiSegmentation:v=c.MULTI_SEGMENTATION,segmentBodyParts:C=c.SEGMENT_BODY_PARTS,backgroundShade:N=c.BACKGROUND_SHADE,shirtShade:k=c.SHIRT_SHADE,threshold:R=c.DETECTION_THRESHOLD,targetPartId:d=c.TARGET_PART_ID,imagesToReturn:n=c.IMAGES_TO_RETURN,workerUrl:m},s)=>{let _=w(null),g=w(null),P=w(!1),A=w([]),le=w(null),J=w(!1),Y=w(void 0);Y.current=h;let $=w({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ee=w(0),fe=500,re=5,te=ce(()=>Re(re),[]),de=ce(()=>({task:W,model:T,verbose:D,bodyPixArchitecture:i,bodyPixMultiplier:I,bodyPixQuantBytes:x,bodyPixStride:V,multiSegmentation:v,segmentBodyParts:C,backgroundShade:N,shirtShade:k,threshold:R,targetPartId:d,imagesToReturn:n}),[W,T,D,i,I,x,V,v,C,N,k,R,d,n]),me=()=>{var r,e;return{width:((r=o.current)==null?void 0:r.videoWidth)||0,height:((e=o.current)==null?void 0:e.videoHeight)||0}},{isReady:H,workerReady:S,lastError:L,detect:ge}=Q(de,m);Z(()=>{y==null||y(S)},[S,y]),Z(()=>{var r;L&&(J.current=!0,(r=Y.current)==null||r.call(Y,L))},[L]);let pe=ve(r=>{if(te.activeCount>=re){r.forEach(e=>{var t;return(t=e==null?void 0:e.close)==null?void 0:t.call(e)}),console.warn("[JerseyDetector] Dropped new segmented images \u2014 max 5 classifications running");return}te(()=>O(null,null,function*(){try{yield a==null?void 0:a(r)}catch(e){console.error("[JerseyDetector] Classification error:",e)}finally{r.forEach(e=>{var t;return(t=e==null?void 0:e.close)==null?void 0:t.call(e)})}}))},[a]),ye=()=>O(null,null,function*(){var B,ne,se;let r=o.current,e=_.current;if(J.current||!H||!S||!r||!e||P.current||r.readyState<2||r.paused||r.ended||r.videoWidth===0||r.videoHeight===0)return;let t=e.getContext("2d");if(!t||e.width<=0||e.height<=0)return;let l=null,u=null;try{P.current=!0;let U=r.videoWidth,j=r.videoHeight;le.current={width:U,height:j},l=yield createImageBitmap(r);let he=me(),E=yield ge(l,he,R);if((E==null?void 0:E.type)==="detect_response"){E.bitmap&&n!=="none"&&(u=E.bitmap,(e.width!==U||e.height!==j)&&(e.width=U,e.height=j),t.clearRect(0,0,U,j),n==="mask_with_image"&&t.drawImage(l,0,0),(n==="mask"||n==="mask_with_image")&&t.drawImage(u,0,0)),A.current.push(Date.now()),A.current=A.current.filter(Te=>Date.now()-Te<1e3);let q={jerseyCount:((B=E.stats)==null?void 0:B.detectionCount)||0,confidence:((ne=E.stats)==null?void 0:ne.averageConfidence)||0,fps:A.current.length,processingTime:((se=E.stats)==null?void 0:se.processingTime)||0},oe=$.current;$.current=q;let ae=Date.now();(ae-ee.current>fe||q.jerseyCount!==oe.jerseyCount||q.confidence!==oe.confidence)&&b&&(b(q),ee.current=ae),E.segmentedImages&&a&&pe(E.segmentedImages)}}catch(U){J.current=!0}finally{l==null||l.close(),u==null||u.close(),P.current=!1}});return be(s,()=>({get isReady(){return H},get lastError(){return L},get stats(){return $.current},capture:(r="image/jpeg",e=.92)=>{let t=o.current,l=_.current;if(!t||t.videoWidth<=0||t.videoHeight<=0)throw new Error("Video not ready for capture");let u=document.createElement("canvas");u.width=t.videoWidth,u.height=t.videoHeight;let B=u.getContext("2d");if(!B)throw new Error("Failed to get context for capture canvas");return B.drawImage(t,0,0,u.width,u.height),l&&l.width>0&&l.height>0?B.drawImage(l,0,0,u.width,u.height):console.warn("[capture] Mask canvas not available \u2014 returning raw video frame"),u.toDataURL(r,e)}}),[H,L,S]),Z(()=>{if(!S||!H||J.current)return;let r=o.current,e=_.current;if(!r||!e||r.videoWidth===0||r.videoHeight===0){let l=setTimeout(()=>{g.current=requestAnimationFrame(()=>{})},100);return()=>clearTimeout(l)}(e.width!==r.videoWidth||e.height!==r.videoHeight)&&(e.width=r.videoWidth,e.height=r.videoHeight);let t=()=>O(null,null,function*(){!S||!H||J.current||(yield ye(),g.current=requestAnimationFrame(t))});return g.current=requestAnimationFrame(t),()=>{g.current&&cancelAnimationFrame(g.current)}},[S,H]),_e("canvas",{ref:_,className:"absolute inset-0 pointer-events-none",style:{zIndex:10,width:"100%",height:"100%"}})});ue.displayName="JerseyDetector";export{c as DEFAULT_CONFIG,ue as JerseyDetector,Q as useJerseyWorker};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seg-cam",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -45,8 +45,9 @@
45
45
  "class-variance-authority": "^0.7.1",
46
46
  "clsx": "^2.1.1",
47
47
  "lucide-react": "^0.454.0",
48
- "next": "16.0.10",
48
+ "next": "^16.1.6",
49
49
  "next-themes": "^0.4.6",
50
+ "p-limit": "^7.3.0",
50
51
  "tailwind-merge": "^3.4.0"
51
52
  },
52
53
  "peerDependencies": {