rgbd 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/dist/index.js +82 -0
  2. package/package.json +5 -5
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ var f,b=["color-src","depth-src","grid-size","focal-length","depth-min","depth-max","cam-radius","cam-max-theta","cam-max-phi","cam-smoothness","cam-zoom-amount","boomerang-speed","background-color","img-zoom-amount","xr-enable-button","xr-recenter-yaw","xr-recenter-radius"],I=`#version 300 es
2
+
3
+ precision mediump float;
4
+ precision mediump int;
5
+
6
+ uniform sampler2D u_depthImage;
7
+ uniform mat4 u_projMat;
8
+ uniform mat4 u_viewMat;
9
+ uniform vec2 u_imageSize;
10
+ uniform float u_focal;
11
+ uniform float u_depthMin;
12
+ uniform float u_depthMax;
13
+ uniform ivec2 u_grid;
14
+ uniform uint u_xr;
15
+
16
+ out vec2 v_uv;
17
+
18
+ void main()
19
+ {
20
+ int vid = gl_VertexID;
21
+ int quad = vid / 6;
22
+ int v = vid - quad * 6;
23
+
24
+ int widthGrid = u_grid.x;
25
+ int heightGrid = u_grid.y;
26
+
27
+ int x = quad % widthGrid;
28
+ int y = quad / widthGrid;
29
+
30
+ float fx = float(x) / float(widthGrid);
31
+ float fy = float(y) / float(heightGrid);
32
+ float fx1 = float(x + 1) / float(widthGrid);
33
+ float fy1 = float(y + 1) / float(heightGrid);
34
+
35
+ vec2 uv00 = vec2(fx , 1.0 - fy);
36
+ vec2 uv10 = vec2(fx1, 1.0 - fy);
37
+ vec2 uv01 = vec2(fx , 1.0 - fy1);
38
+ vec2 uv11 = vec2(fx1, 1.0 - fy1);
39
+
40
+ vec2 uv;
41
+ if (v == 0) uv = uv00;
42
+ else if (v == 1) uv = uv10;
43
+ else if (v == 2) uv = uv01;
44
+ else if (v == 3) uv = uv10;
45
+ else if (v == 4) uv = uv11;
46
+ else uv = uv01;
47
+
48
+ float depth = texture(u_depthImage, uv).r;
49
+ float z = mix(u_depthMin, u_depthMax, depth);
50
+ if(u_xr != 0u)
51
+ z *= -1.0;
52
+
53
+ vec2 pixelPos = uv * u_imageSize;
54
+ vec2 pos = (pixelPos - u_imageSize * 0.5) * z / u_focal;
55
+ if(u_xr != 0u)
56
+ pos.x *= -1.0;
57
+
58
+ v_uv = uv;
59
+ gl_Position = u_projMat * u_viewMat * vec4(pos.x, pos.y, z, 1.0);
60
+ }
61
+
62
+ `,P=`#version 300 es
63
+
64
+ precision mediump float;
65
+
66
+ in vec2 v_uv;
67
+
68
+ out vec4 fragColor;
69
+
70
+ uniform sampler2D u_colorImage;
71
+ uniform sampler2D u_depthImage;
72
+
73
+ void main()
74
+ {
75
+ fragColor = texture(u_colorImage, v_uv);
76
+ }
77
+ `,y=typeof window<"u"&&typeof HTMLElement<"u"&&typeof document<"u";y?f=class extends HTMLElement{constructor(){super(),this.s={GRID_SIZE:250,FOCAL_LENGTH:1200,DEPTH_MIN:.1,DEPTH_MAX:10,CAM_RADIUS:1.5,CAM_MAX_THETA:Math.PI/32,CAM_MAX_PHI:Math.PI/32,CAM_SMOOTHNESS:.9,CAM_ZOOM_AMOUNT:.2,BOOMERANG_SPEED:.001,BACKGROUND_COLOR:[0,0,0],IMG_ZOOM_AMOUNT:0,XR_RECENTER_RADIUS:.25,XR_RECENTER_YAW:45},this.U=null,this.i=null,this.t=null,this.d=null,this.n=null,this.P=null,this.O={},this.p=null,this.m={x:0,y:0,hovered:!1},this.o={theta:Math.PI,phi:0,radius:this.s.CAM_RADIUS},this.F=0,this.b=null,this.G=!1,this.$=null,this.tt=null,this.et=this.D.bind(this),this.it=this.xt.bind(this),this.st=this.At.bind(this),this.v=this.H.bind(this),this.ht=!1,this.a=null,this.T=null,this.R=null,this.h=null,this.Et=!1,this.g=null,this.U=this.attachShadow({mode:"open"});let t=document.createElement("div");t.style.position="relative",t.style.width="100%",t.style.height="100%",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.background="black",this.U.appendChild(t);let e=document.createElement("style");e.textContent=`
78
+ :host { display: inline-block; width: 300px; height: 200px; }
79
+ :host([fullbleed]) { display:block; width:100%; height:100%; }
80
+ canvas { touch-action: none; }
81
+ .cover-img, .cover-video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
82
+ `,this.U.appendChild(e),this.i=document.createElement("canvas"),this.i.style.width="100%",this.i.style.height="100%",this.i.style.objectFit="contain",this.i.setAttribute("role","img"),this.i.setAttribute("aria-label","3D image"),t.appendChild(this.i),this.g=document.createElement("button"),this.g.textContent="Enter VR",Object.assign(this.g.style,{position:"absolute",display:"none",top:"1%",right:"1%",color:"white",background:"rgba(0,0,0,0.4)",padding:"8px 8px",fontFamily:"monospace",fontSize:"20px",borderRadius:"8px",border:"1px solid white",backdropFilter:"blur(6px)",whiteSpace:"pre"}),t.appendChild(this.g),this.g.addEventListener("click",()=>{this.a?this.nt():this.Mt()})}connectedCallback(){this.X();let t;try{this.bt(),t=!1}catch{t=!0}this.i.addEventListener("resize",this.et),this.i.addEventListener("mousemove",this.it),this.i.addEventListener("mouseleave",this.st),t?this.B():(this.D(),this.G=!0,this.F=performance.now(),this.b=requestAnimationFrame(this.v)),this.rt()}disconnectedCallback(){this.G=!1,cancelAnimationFrame(this.b),this.i.removeEventListener("resize",this.et),this.i.removeEventListener("mousemove",this.it),this.i.removeEventListener("mouseleave",this.st);try{this.a&&(this.a.end(),this.a=null,this.Et=!1)}catch{}try{if(this.n){let t=this.n;this.P&&t.deleteProgram(this.P);for(let e in this.O)t.deleteTexture(this.O[e].tex)}}catch{}}setViewMatrix(t){this.$=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this.tt=t&&t.length===16?new Float32Array(t):null}get width(){return this.A(this.t)}get height(){return this.E(this.t)}bt(){let t=this.i.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this.n=t;let e=this.vt(t,I,P);if(!e)return;this.P=e,t.useProgram(e);let i=this.ot(t),s=this.ot(t);this.O.color=i,this.O.depth=s,this._("color",this.t),this._("depth",this.d);let h=t.getUniformLocation(e,"u_colorImage"),n=t.getUniformLocation(e,"u_depthImage");t.uniform1i(h,0),t.uniform1i(n,1),this.p={uProjection:t.getUniformLocation(e,"u_projMat"),uView:t.getUniformLocation(e,"u_viewMat"),uImageSize:t.getUniformLocation(e,"u_imageSize"),uFocal:t.getUniformLocation(e,"u_focal"),uDepthMin:t.getUniformLocation(e,"u_depthMin"),uDepthMax:t.getUniformLocation(e,"u_depthMax"),uGridSegs:t.getUniformLocation(e,"u_grid"),uXr:t.getUniformLocation(e,"u_xr")}}at(t=null){if(!this.n)return;let e=this.n;e.bindFramebuffer(e.FRAMEBUFFER,t),e.useProgram(this.P),e.clearColor(...this.s.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST)}ut(t,e){if(!this.n)return;let i=this.n,s=this.A(this.t),h=this.E(this.t),n=s/h,r=Math.max(1,Math.floor(this.s.GRID_SIZE)),o=Math.max(1,Math.round(r/n));i.uniform2f(this.p.uImageSize,s,h),i.uniform1f(this.p.uFocal,this.s.FOCAL_LENGTH),i.uniform1f(this.p.uDepthMin,this.s.DEPTH_MIN),i.uniform1f(this.p.uDepthMax,this.s.DEPTH_MAX),i.uniform2i(this.p.uGridSegs,r,o),i.uniform1ui(this.p.uXr,this.a?1:0),i.uniformMatrix4fv(this.p.uView,!1,t),i.uniformMatrix4fv(this.p.uProjection,!1,e),i.drawArrays(i.TRIANGLES,0,r*o*6)}H(t,e){if(!this.G)return;let i=t-this.F;this.F=t,this.ct(),this.m.hovered||(this.m.x=Math.sin(t*this.s.BOOMERANG_SPEED),this.m.y=Math.sin(t*this.s.BOOMERANG_SPEED*.5+Math.PI));let s=this.m.x*this.s.CAM_MAX_THETA+Math.PI,h=-this.m.y*this.s.CAM_MAX_PHI,n=this.s.CAM_RADIUS*(1-this.s.CAM_ZOOM_AMOUNT),r=this.m.hovered?n:this.s.CAM_RADIUS;if(this.o.theta=this.M(s,this.o.theta,i),this.o.phi=this.M(h,this.o.phi,i),this.o.radius=this.M(r,this.o.radius,i),this.a){let o=this.T.getOffsetReferenceSpace(new XRRigidTransform({x:this.h.x,y:this.h.y,z:this.h.z},{x:0,y:Math.sin(this.h.yaw*.5),z:0,w:Math.cos(this.h.yaw*.5)}));this.h.x=this.M(0,this.h.x,i),this.h.y=this.M(0,this.h.y,i),this.h.z=this.M(0,this.h.z,i),this.h.yaw=this.M(0,this.h.yaw,i);let a=e.getViewerPose(this.T).transform;this.R||(this.R=a);let u=this.R,c=a.position.x-u.position.x,l=a.position.y-u.position.y,p=a.position.z-u.position.z,d=this.lt(a.orientation);(Math.abs(d-this.lt(u.orientation))>this.s.XR_RECENTER_YAW*Math.PI/180||Math.hypot(c,l,p)>this.s.XR_RECENTER_RADIUS)&&(this.h.x=-a.position.x,this.h.y=-a.position.y,this.h.z=-a.position.z,this.h.yaw=-d,this.T=this.T.getOffsetReferenceSpace(new XRRigidTransform(a.position,{x:0,y:Math.sin(d*.5),z:0,w:Math.cos(d*.5)})),this.R=null);let R=e.session,C=e.getViewerPose(o);if(!C){R.requestAnimationFrame(this.v);return}let S=R.renderState.baseLayer;this.at(S.framebuffer);for(let v of C.views){let M=S.getViewport(v);this.n.viewport(M.x,M.y,M.width,M.height);let O=new Float32Array(v.transform.inverse.matrix),D=new Float32Array(v.projectionMatrix);this.ut(O,D)}}else{let o=this.i.width/this.i.height,a=[this.o.radius*Math.cos(this.o.phi)*Math.sin(this.o.theta),this.o.radius*Math.sin(this.o.phi),this.s.CAM_RADIUS+this.o.radius*Math.cos(this.o.phi)*Math.cos(this.o.theta)],u=[0,0,this.s.CAM_RADIUS],c=[0,-1,0],l=this.height*(1-this.s.IMG_ZOOM_AMOUNT),p=2*Math.atan(l/(2*this.s.FOCAL_LENGTH)),d=this.$||new Float32Array(this.yt(a,u,c)),w=this.tt||new Float32Array(this.Tt(p,o,.1,100));this.at(),this.ut(d,w)}this.a?this.b=e.session.requestAnimationFrame(this.v):this.b=requestAnimationFrame(this.v)}rt(){this.ht&&navigator.xr&&navigator.xr.isSessionSupported?navigator.xr.isSessionSupported("immersive-vr").then(t=>{this.g.style.display=t?"block":"none"}).catch(()=>{this.g.style.display="none"}):this.g.style.display="none"}async Mt(){if(!this.a)try{let t=await navigator.xr.requestSession("immersive-vr",{optionalFeatures:["local-floor","bounded-floor"]});this.n.makeXRCompatible&&await this.n.makeXRCompatible(),this.D();let e=new XRWebGLLayer(t,this.n);await t.updateRenderState({baseLayer:e});let i=await t.requestReferenceSpace("local");this.a=t,this.T=i,this.R=null,this.h={x:0,y:0,z:0,yaw:0},cancelAnimationFrame(this.b),t.addEventListener("end",()=>{this.nt()}),t.requestAnimationFrame(this.v)}catch(t){console.warn("Unable to start XR session",t)}}async nt(){if(this.a){try{await this.a.end()}catch{}this.a=null,this.T=null,this.R=null,this.D(),this.b=requestAnimationFrame(this.v)}}xt(t){let e=this.i.getBoundingClientRect();this.m.hovered=!0,this.m.x=(t.clientX-e.left)/e.width*2-1,this.m.y=(t.clientY-e.top)/e.height*2-1}At(){this.m.hovered=!1}D(){let t=window.devicePixelRatio||1,e=this.i.parentElement;if(!e)return;let i=e.clientWidth,s=e.clientHeight,h=this.A(this.t)||1,n=this.E(this.t)||1,r=h/n,o=i,a=o/r;a>s&&(a=s,o=a*r);let u=Math.max(1,Math.floor((this.a?i:o)*t)),c=Math.max(1,Math.floor((this.a?s:a)*t));this.i.width=u,this.i.height=c,this.n&&this.n.viewport(0,0,u,c)}X(){let t=this.s;if(this.hasAttribute("grid-size")&&(t.GRID_SIZE=parseInt(this.getAttribute("grid-size"))??t.GRID_SIZE),this.hasAttribute("focal-length")&&(t.FOCAL_LENGTH=parseFloat(this.getAttribute("focal-length"))??t.FOCAL_LENGTH),this.hasAttribute("depth-min")&&(t.DEPTH_MIN=parseFloat(this.getAttribute("depth-min"))??t.DEPTH_MIN),this.hasAttribute("depth-max")&&(t.DEPTH_MAX=parseFloat(this.getAttribute("depth-max"))??t.DEPTH_MAX),this.hasAttribute("cam-radius")&&(t.CAM_RADIUS=parseFloat(this.getAttribute("cam-radius"))??t.CAM_RADIUS),this.hasAttribute("cam-max-theta")&&(t.CAM_MAX_THETA=parseFloat(this.getAttribute("cam-max-theta"))??t.CAM_MAX_THETA),this.hasAttribute("cam-max-phi")&&(t.CAM_MAX_PHI=parseFloat(this.getAttribute("cam-max-phi"))??t.CAM_MAX_PHI),this.hasAttribute("cam-smoothness")&&(t.CAM_SMOOTHNESS=parseFloat(this.getAttribute("cam-smoothness"))??t.CAM_SMOOTHNESS),this.hasAttribute("cam-zoom-amount")&&(t.CAM_ZOOM_AMOUNT=parseFloat(this.getAttribute("cam-zoom-amount"))??t.CAM_ZOOM_AMOUNT),this.hasAttribute("boomerang-speed")&&(t.BOOMERANG_SPEED=parseFloat(this.getAttribute("boomerang-speed"))??t.BOOMERANG_SPEED),this.hasAttribute("background-color"))try{let e=this.getAttribute("background-color").split(",").map(Number);e.length===3&&(t.BACKGROUND_COLOR=e)}catch{}this.hasAttribute("img-zoom-amount")&&(t.IMG_ZOOM_AMOUNT=parseFloat(this.getAttribute("img-zoom-amount"))??t.IMG_ZOOM_AMOUNT),this.ht=this.hasAttribute("xr-enable-button"),this.hasAttribute("xr-recenter-yaw")&&(t.XR_RECENTER_YAW=parseFloat(this.getAttribute("xr-recenter-yaw"))??t.XR_RECENTER_YAW),this.hasAttribute("xr-recenter-radius")&&(t.XR_RECENTER_RADIUS=parseFloat(this.getAttribute("xr-recenter-radius"))??t.XR_RECENTER_RADIUS),this.rt()}dt(t,e,i){let s=t.createShader(e);return t.shaderSource(s,i),t.compileShader(s),t.getShaderParameter(s,t.COMPILE_STATUS)?s:(console.error(t.getShaderInfoLog(s)),t.deleteShader(s),null)}vt(t,e,i){let s=this.dt(t,t.VERTEX_SHADER,e),h=this.dt(t,t.FRAGMENT_SHADER,i);if(!s||!h)return null;let n=t.createProgram();return t.attachShader(n,s),t.attachShader(n,h),t.linkProgram(n),t.getProgramParameter(n,t.LINK_STATUS)?(t.deleteShader(s),t.deleteShader(h),n):(console.error(t.getProgramInfoLog(n)),t.deleteProgram(n),null)}ot(t){let e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),{tex:e,width:0,height:0}}_(t,e){if(!this.n)return;let i=this.n,s=this.O[t];if(i.activeTexture(t==="color"?i.TEXTURE0:i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,s.tex),!this.W(e)){i.texImage2D(i.TEXTURE_2D,0,i.RGBA,1,1,0,i.RGBA,i.UNSIGNED_BYTE,new Uint8Array([0,0,0,0]));return}try{i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,e),(this.A(e)!=s.width||this.E(e)!=s.height)&&(this.D(),s.width=this.A(e),s.height=this.E(e))}catch{}}Tt(t,e,i,s){let h=1/Math.tan(t/2);return[h/e,0,0,0,0,h,0,0,0,0,(s+i)/(i-s),-1,0,0,2*s*i/(i-s),0]}yt(t,e,i){function s(u){let c=Math.hypot(...u)||1;return u.map(l=>l/c)}function h(u,c){return[u[1]*c[2]-u[2]*c[1],u[2]*c[0]-u[0]*c[2],u[0]*c[1]-u[1]*c[0]]}function n(u,c){return u.map((l,p)=>l-c[p])}let r=s(n(t,e)),o=s(h(i,r)),a=h(r,o);return[o[0],a[0],r[0],0,o[1],a[1],r[1],0,o[2],a[2],r[2],0,-(o[0]*t[0]+o[1]*t[1]+o[2]*t[2]),-(a[0]*t[0]+a[1]*t[1]+a[2]*t[2]),-(r[0]*t[0]+r[1]*t[1]+r[2]*t[2]),1]}lt(t){return Math.atan2(2*(t.w*t.y+t.x*t.z),1-2*(t.y*t.y+t.x*t.x))}M(t,e,i){let s=(1-this.s.CAM_SMOOTHNESS)*i/16.67,h=Math.sign(t-e);return e+=(t-e)*s,Math.sign(t-e)!==h&&(e=t),e}B(){throw new Error("Must implement _createFallback")}ct(){}W(t){throw new Error("Must implement _isSourceReady")}A(t){throw new Error("Must implement _getSourceWidth")}E(t){throw new Error("Must implement _getSourceHeight")}}:f=class{};var g=class extends f{static get observedAttributes(){return b}constructor(){super(),this.t=new Image,this.d=new Image,this.t.crossOrigin="anonymous",this.d.crossOrigin="anonymous",this.t.onload=()=>this._("color",this.t),this.d.onload=()=>this._("depth",this.d)}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.t.src=i||"":t==="depth-src"?this.d.src=i||"":this.X())}B(){this.t.style.display="block",this.t.classList.add("cover-img"),this.i.parentElement.appendChild(this.t)}W(t){return t&&t.complete&&t.naturalWidth>0}A(t){return t?t.width:1}E(t){return t?t.height:1}};var _=class{constructor(){this.context=null,this.sourceNodes=null,this.gainNode=null,this.volume=1,this.sampleRate=0,this.numChannels=0,this.timeSuspended=0,this.timeOffset=0,this.lastTime=0,this.context=null,this.isPaused=!1,this.loopHandle=null}start(t={}){if(this.context)throw new Error("Audio manager already started!");this.audioEnabled=t.audioEnabled??!0,this.sampleRate=t.sampleRate??44100,this.numChannels=t.numChannels??2,this.context=new AudioContext({sampleRate:this.sampleRate}),this.isPaused&&this.context.suspend(),this.sourceNodes=new Set,this.gainNode=this.context.createGain(),this.gainNode.gain.value=this.volume,this.gainNode.connect(this.context.destination),this.timeSuspended=0,this.timeOffset=0,this.lastTime=performance.now(),this.loopHandle=setInterval(()=>{let e=performance.now();!this.isPaused&&this.context.state==="suspended"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e},t.updateInterval??10),this.context.onstatechange=()=>{let e=performance.now();this.context?.state==="running"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e}}async stop(){if(!this.context)throw new Error("Audio manager not started!");clearInterval(this.loopHandle),this.loopHandle=null,await this.context.suspend(),this.context=null}started(){return this.context!=null}getTime(){return(this.context?.currentTime??0)+this.timeSuspended+this.timeOffset}getLatency(){return this.context?(this.context.outputLatency??0)+this.context.baseLatency:0}getVideoTime(){return this.getTime()-this.getLatency()}setVideoTime(t){if(t+=this.getLatency(),this.sourceNodes!=null){for(let e of this.sourceNodes)try{e.stop()}catch{}this.sourceNodes.clear()}this.timeOffset=t-((this.context?.currentTime??0)+this.timeSuspended)}setVolume(t){this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}async resumeContext(){if(!this.context)throw new Error("Audio manager not started!");this.context.state==="suspended"&&!this.isPaused&&await this.context.resume()}async pause(){this.isPaused||(this.context&&await this.context.suspend(),this.isPaused=!0)}async play(){this.isPaused&&(this.context&&await this.context.resume(),this.isPaused=!1)}scheduleChunk(t,e){let i=t[0].length;if(i<=0)return;let s=this.context.createBuffer(this.numChannels,i,this.sampleRate);for(let h=0;h<this.numChannels;h++)s.copyToChannel(t[h],h);if(e-=this.timeSuspended+this.timeOffset,e>this.context.currentTime&&this.context.state!=="suspended"){let h=this.context.createBufferSource();h.buffer=s,h.connect(this.gainNode),this.sourceNodes.add(h),h.onended=()=>this.sourceNodes.delete(h),h.start(e)}this.playHead+=s.duration}};import*as x from"mp4box";var T=class{constructor(t,e){this.l=t,this.ft=0,this.wt=e}write(t){let e=new ArrayBuffer(t.byteLength);new Uint8Array(e).set(t),e.fileStart=this.ft,this.ft+=e.byteLength,this.l.appendBuffer(e)}close(){this.l.flush(),this.wt()}},A=class{constructor(t,e,{onConfig:i,onChunk:s,onEndOfStream:h}){if(this.V=e,this.mt=i,this.Rt=s,this.l=x.createFile(),this.l.onReady=this.Ct.bind(this),this.l.onSamples=this.St.bind(this),t instanceof ArrayBuffer)t.fileStart=0,this.l.appendBuffer(t),this.l.flush(),h();else{let n=new T(this.l,h);fetch(t).then(r=>{r.body.pipeTo(new WritableStream(n,{highWaterMark:2}))})}}pt(t){let i=this.l.getTrackById(t.id).mdia.minf.stbl.stsd.entries[0];if(this.V)return i.esds.esd.descs[0].descs[0].data;{let s=i.avcC||i.hvcC||i.vpcC||i.av1C;if(!s)return null;let h=new x.DataStream(void 0,0,x.DataStream.BIG_ENDIAN);return s.write(h),new Uint8Array(h.buffer,8)}}Ct(t){if(this.V){let e=t.audioTracks[0];this.mt(e?{codec:e.codec,sampleRate:e.audio.sample_rate,numberOfChannels:e.audio.channel_count,description:this.pt(e)}:null),e&&this.l.setExtractionOptions(e.id)}else{let e=t.videoTracks[0];this.mt({codec:e.codec.startsWith("vp08")?"vp8":e.codec,codedHeight:e.video.height,codedWidth:e.video.width,description:this.pt(e)}),this.l.setExtractionOptions(e.id)}this.l.start()}St(t,e,i){for(let s of i){let h;this.V?h=EncodedAudioChunk:h=EncodedVideoChunk,this.Rt(new h({type:s.is_sync?"key":"delta",timestamp:1e6*s.cts/s.timescale,duration:1e6*s.duration/s.timescale,data:s.data}))}}};var L=1,E=class extends f{static get observedAttributes(){return b.concat(["autoplay","loop","muted","controls"])}constructor(){super(),this.r=[],this.u=[],this.c=[],this.j=!1,this.Z=!1,this.I=!0,this.e=new _,this.e.pause(),this.Y=!1,this.C=document.createElement("div"),this.C.classList.add("rgbd-controls"),Object.assign(this.C.style,{position:"absolute",bottom:"1%",left:"50%",transform:"translateX(-50%)",display:"none",alignItems:"center",justifyContent:"center",gap:"8px",background:"rgba(0, 0, 0, 0.4)",padding:"8px 8px",borderRadius:"8px",backdropFilter:"blur(6px)",boxSizing:"border-box",width:"50%",flexWrap:"wrap"}),this.shadowRoot.appendChild(this.C),this.L=document.createElement("button"),Object.assign(this.L.style,{border:"none",background:"transparent",color:"white",fontSize:"24px",cursor:"pointer",padding:"4px",flexShrink:"0"}),this.C.appendChild(this.L),this.L.addEventListener("click",()=>{this.paused?this.play():this.pause()}),this.f=document.createElement("input"),this.f.type="range",this.f.min="0",this.f.max="1",this.f.value="0",this.f.step="any",Object.assign(this.f.style,{flex:"1 1 auto",minWidth:"120px",maxWidth:"100%",cursor:"pointer",accentColor:"#fff"}),this.C.appendChild(this.f),this.f.addEventListener("input",()=>{let t=this.r[0];if(!t||!t.duration)return;let e=t.startTime+this.f.value*t.duration;this.currentTime=e})}disconnectedCallback(){this.e.started()&&this.e.stop(),super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.clear().then(()=>{this.r=[this.S(i,0,!1)],this.c=[this.S(i,0,!0)],this.K=this.r[0],this.q=this.c[0]}):t==="depth-src"?(this.u=[this.S(i,0,!1)],this.J=this.u[0]):t==="autoplay"?(this.j=this.hasAttribute("autoplay"),this.j&&this.e.play()):t==="loop"?this.Z=this.hasAttribute("loop"):t==="muted"?(this.I=this.hasAttribute("muted"),this.e.setVolume(this.I?0:1),!this.I&&this.e.started()&&this.e.resumeContext()):t==="controls"?(this.Y=this.hasAttribute("controls"),this.C.style.display=this.Y?"flex":"none"):this.X())}async play(){await this.e.play()}async pause(){await this.e.pause()}async clear(){for(this.t=null,this.d=null,this._("color",null),this._("depth",null),this.K=null,this.J=null,this.q=null;this.r.length>0;)this.N(this.r.shift());for(;this.u.length>0;)this.N(this.u.shift());for(;this.c.length>0;)this.N(this.c.shift());this.currentTime=0,this.e.started()&&await this.e.stop()}enqueue(t,e,i){this.r.push(this.S(t,i,!1)),this.u.push(this.S(e,i,!1)),this.c.push(this.S(t,i,!0))}get paused(){return this.e.isPaused}get currentTime(){return this.e.getVideoTime()}set currentTime(t){let e=i=>{if(i.length==0)return;this.N(i[0]),i[0]=this.k(i[0],i[0].startTime);let s=i[0];s.demuxer!=null&&console.error("Demuxing not yet finished!");let h=Number.MAX_VALUE,n=-1;for(let r=0;r<s.chunks.length;r++){if(s.chunks[r].type!=="key")continue;let o=Math.abs(t-(s.startTime+s.chunks[r].timestamp/1e6));o<h&&(h=o,n=r)}n<0||(s.curChunk=n)};this.e.setVideoTime(t),this.Q=null,e(this.r),e(this.u),e(this.c)}get volume(){return this.e.volume}set volume(t){this.e.setVolume(t)}Ot(t){if(this.e.started()){if(t==null)return;if(t.sampleRate!=this.e.sampleRate)throw new Error("Audio configs have mismatched sample rates!");if(t.numberOfChannels!=this.e.numChannels)throw new Error("Audio configs have mismatched channel counts!")}else this.e.start(t?{sampleRate:t.sampleRate,numChannels:t.numberOfChannels,volume:1}:{audioEnabled:!1}),this.I||this.e.resumeContext()}gt(t,e){let i=e+t.timestamp/1e6,s=[];for(let h=0;h<t.numberOfChannels;h++){let n=new Float32Array(t.numberOfFrames);t.copyTo(n,{planeIndex:h,format:"f32-planar"}),s.push(n)}this.e.scheduleChunk(s,i)}S(t,e,i){let s={startTime:e,isAudio:i,duration:0,demuxer:null,decoder:null,chunks:[],frames:[],curChunk:0},h;return i?h=AudioDecoder:h=VideoDecoder,s.decoder=new h({output:n=>{i?this.gt(n,s.startTime):s.frames.push(n)},error:n=>{console.error("Decoder encountered an error while decoding: ",n)}}),s.demuxer=new A(t,i,{onConfig:n=>{s.config=n,n?s.decoder?.configure(n):s.done=!0,i&&this.Ot(n)},onChunk:n=>{s.chunks?.push(n),s.duration=Math.max(s.duration,(n.timestamp+n.duration)/1e6)},onEndOfStream:()=>{s.demuxer=null}}),s}k(t,e){let i={startTime:e,isAudio:t.isAudio,duration:t.duration,demuxer:null,decoder:null,config:t.config,chunks:t.chunks,frames:[],curChunk:0},s;return t.isAudio?s=AudioDecoder:s=VideoDecoder,i.decoder=new s({output:h=>{i.isAudio?this.gt(h,i.startTime):i.frames.push(h)},error:h=>{console.error("Decoder encountered an error while decoding: ",h)}}),t.config?i.decoder.configure(t.config):i.done=!0,i}Dt(){let t=!this.paused;this.L.textContent=t?"\u23F8\uFE0F":"\u25B6\uFE0F";let e=this.r[0];if(!e||!e.duration){this.f.value=0;return}let i=this.currentTime-e.startTime,s=Math.max(0,Math.min(1,i/e.duration));this.f.value=s}H(t,e){let i=(h,n)=>{let r=h[n];for(;r.curChunk<r.chunks.length;){let o=r.chunks[r.curChunk];if(r.startTime+o.timestamp/1e6>this.e.getVideoTime()+L)break;r.decoder.decode(o),r.curChunk++}if(r.curChunk>=r.chunks.length&&!r.demuxer&&r.decoder){let o=r.decoder;o.flush().then(()=>{o.close(),r.done=!0}),r.decoder=null}};for(let h=0;h<this.r.length;h++)i(this.r,h);for(let h=0;h<this.u.length;h++)i(this.u,h);for(let h=0;h<this.c.length;h++)this.c[h].config!=null&&i(this.c,h);let s=h=>h?h.done&&h.frames.length==1:!1;s(this.r[0])&&s(this.u[0])&&(this.r.shift(),this.u.shift(),this._t=!0),this.c[0]?.done&&this.c.shift(),this.Z&&this.r.length==0&&this.u.length==0&&this.c.length==0&&this.K!=null&&this.J!=null&&(this.e.setVideoTime(0),this.r=[this.k(this.K,0)],this.u=[this.k(this.J,0)],this.q!=null&&(this.c=[this.k(this.q,0)])),this.Y&&this.Dt(),super.H(t,e)}B(){this.t=document.createElement("video"),this.t.style.display="block",this.t.classList.add("cover-video"),this.t.muted=this.I,this.t.autoplay=this.j,this.t.loop=this.Z,this.t.src=this.getAttribute("color-src"),this.i.parentElement.appendChild(this.t)}ct(){let t=this.r[0],e=this.u[0];if(!t||!e)return;let i=this.e.getVideoTime(),s=this.Q!=null?Math.abs(i-this.Q):Number.MAX_VALUE,h=-1;for(let n=0;n<Math.min(t.frames.length,e.frames.length);n++){let r=Math.abs(i-(t.startTime+t.frames[n].timestamp/1e6));if(r<=s)s=r,h=n;else break}if(!(h<0)){this._t&&(this.t.close(),this.d.close(),this._t=!1),this.t=t.frames[h],this.d=e.frames[h],this.Q=t.startTime+this.t.timestamp/1e6,this.t?.timestamp!==this.d?.timestamp&&console.error("Color and depth frames have mismatched PTS"),this._("color",this.t),this._("depth",this.d);for(let n=0;n<h;n++)t.frames.shift().close(),e.frames.shift().close()}}W(t){return t instanceof VideoFrame}A(t){return t?t.codedWidth:1}E(t){return t?t.codedHeight:1}N(t){t.decoder?.close(),t.decoder=null;for(let e=0;e<t.frames.length;e++)t.frames[e].close()}};y&&(customElements.define("rgbd-img",g),customElements.define("rgbd-video",E));
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "rgbd",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
- "main": "dist/rgbd.js",
6
- "module": "dist/rgbd.js",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
7
  "exports": {
8
- ".": "./dist/rgbd.js"
8
+ ".": "./dist/index.js"
9
9
  },
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "esbuild src/rgbd.js --bundle --external:mp4box --minify --outfile=dist/rgbd.js --format=esm --mangle-props=^_",
14
+ "build": "esbuild src/index.js --bundle --external:mp4box --minify --outfile=dist/index.js --format=esm --mangle-props=^_",
15
15
  "dev": "vite",
16
16
  "prepare": "npm run build"
17
17
  },