@bylqwjc/media-editor-server 1.0.22 → 1.0.23
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/core/dist/browser.cjs +1 -1
- package/core/dist/browser.d.ts +14 -3
- package/core/dist/browser.js +1 -1
- package/core/dist/chunk-7D4QE3R2.js +1 -0
- package/core/dist/chunk-KO6CX4IJ.js +1 -0
- package/core/dist/chunk-T5QIAKTR.js +1 -0
- package/core/dist/chunk-VDEZTXEA.js +1 -0
- package/core/dist/engine.cjs +1 -1
- package/core/dist/engine.d.ts +234 -29
- package/core/dist/engine.js +1 -1
- package/core/dist/filerobot.cjs +1 -1
- package/core/dist/filerobot.d.ts +1 -1
- package/core/dist/filerobot.js +1 -1
- package/core/dist/index.cjs +1 -1
- package/core/dist/index.d.ts +13 -27
- package/core/dist/index.js +1 -1
- package/core/dist/{platform-presets-B-o4C6uY.d.ts → platform-presets-Ca2LbKQ3.d.ts} +1 -1
- package/core/dist/state-D7Of7b_y.d.ts +2088 -0
- package/core/package.json +1 -1
- package/core/zod/v3/types.js +1 -1
- package/dist/adapters/express.cjs +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +1 -1
- package/dist/adapters/web.cjs +1 -1
- package/dist/adapters/web.d.ts +1 -1
- package/dist/adapters/web.js +1 -1
- package/dist/{handler-DL4Inp7o.d.ts → handler-BEalyBz9.d.ts} +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/core/dist/chunk-MGKYVYOH.js +0 -1
- package/core/dist/chunk-USY6UDGL.js +0 -1
- package/core/dist/chunk-XCBM7P7N.js +0 -1
- package/core/dist/state-B85vkf7_.d.ts +0 -1027
package/core/dist/browser.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var v=Math.PI/180;function y(t,e,n){t.strokeStyle=e,t.lineWidth=n,t.lineCap="round",t.lineJoin="round"}function $(t,e,n,r,a,o){const s=Math.atan2(a-n,r-e),i=Math.max(12,3.5*o);t.beginPath(),t.moveTo(r,a),t.lineTo(r-i*Math.cos(s-Math.PI/7),a-i*Math.sin(s-Math.PI/7)),t.moveTo(r,a),t.lineTo(r-i*Math.cos(s+Math.PI/7),a-i*Math.sin(s+Math.PI/7)),t.stroke()}function b(t){if(!Number.isFinite(t))return 0;let e=t%360;return e>180&&(e-=360),e<-180&&(e+=360),Math.abs(e)<.001?0:e}function m(t){return b(t.rotation??0)}function k(t){switch(t.type){case"pen":{let e=1/0,n=1/0,r=-1/0,a=-1/0;for(let o=0;o<t.points.length;o+=2)e=Math.min(e,t.points[o]),r=Math.max(r,t.points[o]),n=Math.min(n,t.points[o+1]),a=Math.max(a,t.points[o+1]);return{x:e,y:n,w:r-e,h:a-n}}case"line":case"arrow":return{x:Math.min(t.x1,t.x2),y:Math.min(t.y1,t.y2),w:Math.abs(t.x2-t.x1),h:Math.abs(t.y2-t.y1)};case"rect":case"ellipse":case"sticker":return{x:t.x,y:t.y,w:t.w,h:t.h};case"text":return{x:t.x,y:t.y,w:t.text.length*t.fontSize*.6,h:1.2*t.fontSize}}}function g(t){const e=k(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function A(t,e,n,r,a){const o=a*v,s=Math.cos(o),i=Math.sin(o),c=t-n,h=e-r;return{x:n+c*s-h*i,y:r+c*i+h*s}}function S(t,e,n,r,a){return{x:n+(t-n)*a,y:r+(e-r)*a}}function P(t,e,n){const r=m(e);if(r){const a=g(e);return t.save(),t.translate(a.x,a.y),t.rotate(r*v),t.translate(-a.x,-a.y),T(t,e,n),void t.restore()}T(t,e,n)}function T(t,e,n){switch(e.type){case"pen":y(t,e.color,e.width),t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let n=2;n<e.points.length;n+=2)t.lineTo(e.points[n],e.points[n+1]);t.stroke();break;case"line":case"arrow":y(t,e.color,e.width),t.beginPath(),t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.stroke(),"arrow"===e.type&&$(t,e.x1,e.y1,e.x2,e.y2,e.width);break;case"rect":y(t,e.color,e.width),t.strokeRect(e.x,e.y,e.w,e.h);break;case"ellipse":y(t,e.color,e.width),t.beginPath(),t.ellipse(e.x+e.w/2,e.y+e.h/2,Math.abs(e.w/2),Math.abs(e.h/2),0,0,2*Math.PI),t.stroke();break;case"text":t.fillStyle=e.color,t.font=`bold ${e.fontSize}px -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif`,t.textBaseline="top",t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=Math.max(2,e.fontSize/16),t.lineJoin="round",t.strokeText(e.text,e.x,e.y),t.fillText(e.text,e.x,e.y);break;case"sticker":if(e.emoji)t.font=`${Math.min(e.w,e.h)}px -apple-system, "Apple Color Emoji", "Segoe UI Emoji", sans-serif`,t.textBaseline="top",t.fillText(e.emoji,e.x,e.y);else if(e.src){const r=n?.get(e.src);r&&t.drawImage(r,e.x,e.y,e.w,e.h)}}}function M(t,e,n){for(const r of e)P(t,r,n)}async function E(t){const e=new Map,n=[...new Set(t.filter(t=>"sticker"===t.type&&t.src).map(t=>t.src))];return await Promise.all(n.map(t=>new Promise(n=>{const r=new Image;r.onload=()=>{e.set(t,r),n()},r.onerror=()=>n(),r.src=t}))),e}async function F(t,e,n){if(!t?.length)return null;const r=document.createElement("canvas");r.width=e,r.height=n;const a=r.getContext("2d");return a?(M(a,t,await E(t)),new Promise(t=>r.toBlob(e=>t(e),"image/png"))):null}function D(t,e,n,r=12){for(let a=t.length-1;a>=0;a--)if(R(t[a],e,n,r))return a;return-1}function N(t,e,n,r,a){return Math.abs(t-n)<=a&&Math.abs(e-r)<=a}function C(t,e,n,r,a,o,s){const i=a-n,c=o-r,h=i*i+c*c||1,l=Math.max(0,Math.min(1,((t-n)*i+(e-r)*c)/h));return(t-(n+l*i))**2+(e-(r+l*c))**2<=s*s}function R(t,e,n,r){const a=m(t);if(a){const o=g(t),s=A(e,n,o.x,o.y,-a);return I(t,s.x,s.y,r)}return I(t,e,n,r)}function I(t,e,n,r){switch(t.type){case"pen":for(let a=0;a+3<t.points.length;a+=2)if(C(e,n,t.points[a],t.points[a+1],t.points[a+2],t.points[a+3],r+t.width/2))return!0;return!1;case"line":case"arrow":return C(e,n,t.x1,t.y1,t.x2,t.y2,r+t.width/2);case"rect":case"ellipse":return e>=t.x-r&&e<=t.x+t.w+r&&n>=t.y-r&&n<=t.y+t.h+r;case"text":return e>=t.x-r&&e<=t.x+t.text.length*t.fontSize*.6+r&&n>=t.y-r&&n<=t.y+t.fontSize+r;case"sticker":return N(e,n,t.x+t.w/2,t.y+t.h/2,Math.max(t.w,t.h)/2+r)}}function _(t,e,n){const r=Math.max(8,n);if(!(t>0&&e>0))return{w:r,h:r};const a=r/Math.max(t,e);return{w:Math.max(8,Math.round(t*a)),h:Math.max(8,Math.round(e*a))}}function J(t,e){const n=Math.max(.05,e),r=g(t);switch(t.type){case"pen":return{...t,points:t.points.map((t,e)=>e%2==0?r.x+(t-r.x)*n:r.y+(t-r.y)*n)};case"line":case"arrow":{const e=S(t.x1,t.y1,r.x,r.y,n),a=S(t.x2,t.y2,r.x,r.y,n);return{...t,x1:e.x,y1:e.y,x2:a.x,y2:a.y}}case"rect":case"ellipse":case"sticker":return{...t,w:Math.max(8,t.w*n),h:Math.max(8,t.h*n)};case"text":return{...t,fontSize:Math.min(512,Math.max(8,t.fontSize*n))};default:return t}}function U(t,e){return{...t,rotation:b(e)}}function V(t,e,n){switch(t.type){case"pen":{const r=t.points.map((t,r)=>r%2==0?t+e:t+n);return{...t,points:r}}case"line":case"arrow":return{...t,x1:t.x1+e,y1:t.y1+n,x2:t.x2+e,y2:t.y2+n};case"rect":case"ellipse":case"sticker":case"text":return{...t,x:t.x+e,y:t.y+n}}}var O=Math.PI/180;function z(t,e,n){const r=W(n);if(0===r||180===r)return{w:t,h:e};if(90===r||270===r)return{w:e,h:t};const a=r*O;return{w:Math.round(Math.abs(t*Math.cos(a))+Math.abs(e*Math.sin(a))),h:Math.round(Math.abs(t*Math.sin(a))+Math.abs(e*Math.cos(a)))}}function W(t){return(t%360+360)%360}function f(t){const e=Math.round(t);return e-e%2}function L(t,e){let n=t.w,r=n/e;return r>t.h&&(r=t.h,n=r*e),{x:Math.round((t.w-n)/2),y:Math.round((t.h-r)/2),width:Math.round(n),height:Math.round(r)}}function j(t,e,n){const r={x:0,y:0,width:t.width,height:t.height},a={x:0,y:0,width:e.w,height:e.h};return"cover"===n?{src:L({w:t.width,h:t.height},e.w/e.h),dst:a}:"contain"===n?{src:r,dst:L({w:e.w,h:e.h},t.width/t.height)}:{src:r,dst:a}}function B(t,e){if(e.scale)return{w:f(e.scale.width),h:f(e.scale.height)};if(e.crop)return{w:f(e.crop.width),h:f(e.crop.height)};const n=z(t.w,t.h,e.rotation);return{w:f(n.w),h:f(n.h)}}function q(t){const e=String(t??"").match(/^data:(image\/(?:png|jpe?g));base64,([a-z0-9+/=]+)$/i);if(!e)return null;const n=atob(e[2]),r=new Uint8Array(n.length);for(let t=0;t<n.length;t++)r[t]=n.charCodeAt(t);return new Blob([r],{type:e[1].toLowerCase()})}async function H(t,e,n=[]){const r=t.getExportPlan(),a=new FormData;r.videoSrcOrder.forEach((t,n)=>{const r=e[t];r&&a.append(`video_${n}`,r,r.name||`video_${n}.mp4`)}),r.audioSrcOrder.forEach((t,e)=>{const r=n[t];r&&a.append(`audio_${e}`,r,r.name||`audio_${e}`)});const o=B(r.state.canvas,r.state),s=await F(r.state.overlays,o.w,o.h);s&&a.append("overlay",s,"overlay.png");const i=r.state.poster?.useAsVideoCover?q(r.state.poster.preview):null;i&&a.append("videoCover",i,"video-cover.png");const c=r.state.poster?.preview?{...r.state,poster:{...r.state.poster,preview:void 0}}:r.state;return a.append("editState",JSON.stringify(c)),a}var Y=[{id:"bw",label:"黑白",vf:"hue=s=0",css:"grayscale(1)"},{id:"sepia",label:"复古",vf:"colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131",css:"sepia(0.85)"},{id:"warm",label:"暖阳",vf:"colorbalance=rs=.15:gs=.04:bs=-.15",css:"sepia(0.25) saturate(1.25) brightness(1.03)"},{id:"cool",label:"冷调",vf:"colorbalance=rs=-.14:bs=.16",css:"hue-rotate(12deg) saturate(0.95) brightness(1.02)"},{id:"vivid",label:"鲜艳",vf:"eq=saturation=1.45:contrast=1.08",css:"saturate(1.45) contrast(1.08)"}];function X(t){return t?Y.find(e=>e.id===t):void 0}function G(t,e){const n=X(e)?.css??"";return[`brightness(${1+t.brightness})`,`contrast(${1+t.contrast})`,`saturate(${1+t.saturation})`,n].filter(Boolean).join(" ")}function K(t,e,n,r,a,o=1,s,i=!0){const c=B(r,a);t.width=Math.max(2,Math.round(c.w*o)),t.height=Math.max(2,Math.round(c.h*o));const h=t.getContext("2d");if(!h)return;const l=z(r.w,r.h,a.rotation),u=a.crop??{x:0,y:0,width:l.w,height:l.h},d=a.scale?.fit??"force",{src:x,dst:f}=j({width:u.width,height:u.height},c,d);"contain"===d&&(h.fillStyle="#000",h.fillRect(0,0,t.width,t.height)),h.filter=G(a.filters,a.filterPreset),h.save(),"contain"===d&&(h.beginPath(),h.rect(o*f.x,o*f.y,o*f.width,o*f.height),h.clip()),h.translate(o*f.x,o*f.y),h.scale(o*f.width/x.width,o*f.height/x.height),h.translate(-(u.x+x.x),-(u.y+x.y)),h.translate(l.w/2,l.h/2),h.rotate(a.rotation*O),h.scale(a.flipX?-1:1,a.flipY?-1:1);const p=j({width:n.w,height:n.h},{w:r.w,h:r.h},"cover");h.drawImage(e,p.src.x,p.src.y,p.src.width,p.src.height,-r.w/2,-r.h/2,r.w,r.h),h.restore(),h.filter="none",i&&a.overlays?.length&&(h.setTransform(o,0,0,o,0,0),M(h,a.overlays,s),h.setTransform(1,0,0,1,0,0))}function Q(t,e){return new Promise(n=>{const r=()=>{t.removeEventListener("seeked",r),n()};t.addEventListener("seeked",r),t.currentTime=Math.min(Math.max(0,e),t.duration||e)})}async function Z(t,e,n=160){const r=t.duration;if(!r||!isFinite(r)||e<=0)return[];const a=t.videoWidth||16,o=t.videoHeight||9,s=Math.min(n,a),i=Math.max(1,Math.round(s*o/a)),c=document.createElement("canvas");c.width=s,c.height=i;const h=c.getContext("2d");if(!h)return[];const l=[];for(let n=0;n<e;n++)await Q(t,r*(n+.5)/e),h.drawImage(t,0,0,s,i),l.push(c.toDataURL("image/jpeg",.6));return l}function tt(t,e={}){const n=e.mode??"overlay",r=document.createElement("button");r.type="button",r.className=["me-fullscreen-toggle",e.className].filter(Boolean).join(" "),r.dataset.meFullscreenToggle="true",r.dataset.mode=n,r.title="全屏 / 退出全屏",r.style.cssText=["overlay"===n?"position:absolute;left:8px;bottom:8px;z-index:30;":"position:static;","width:32px;height:32px;padding:0;","display:inline-flex;align-items:center;justify-content:center;","border:1px solid var(--me-border,#26262b);border-radius:6px;","background:var(--me-chip,#1c1c20);color:var(--me-fg,#e7e7ee);","cursor:pointer;font-size:15px;line-height:1;opacity:0.9;font:inherit;"].join(""),t.classList.add("me-fullscreen-host");const a=()=>{const e=document.fullscreenElement===t;r.textContent=e?"×":"⛶",r.setAttribute("aria-label",e?"退出全屏":"全屏"),t.classList.toggle("me-is-fullscreen",e),t.dataset.meFullscreen=e?"true":"false"};a();const o=()=>a(),s=()=>{(document.fullscreenElement===t?document.exitFullscreen?.():t.requestFullscreen?.())?.catch?.(()=>{})};return r.addEventListener("click",s),document.addEventListener("fullscreenchange",o),{button:r,dispose:()=>{document.removeEventListener("fullscreenchange",o),r.removeEventListener("click",s),r.remove(),t.classList.remove("me-fullscreen-host","me-is-fullscreen"),delete t.dataset.meFullscreen}}}exports.buildVideoExportFormData=H,exports.createFullscreenToggle=tt,exports.drawOverlay=P,exports.drawOverlays=M,exports.drawVideoFrame=K,exports.fitStickerBox=_,exports.generateThumbnails=Z,exports.getOverlayRotation=m,exports.hitTestOverlay=D,exports.loadOverlayImages=E,exports.overlayBBox=k,exports.renderOverlaysToPng=F,exports.rotateOverlay=U,exports.scaleOverlay=J,exports.translateOverlay=V;
|
|
1
|
+
"use strict";var zod=require("../zod/index.cjs"),DEG2RAD=Math.PI/180,TEXT_FONT_STACK='-apple-system, "PingFang SC", "Microsoft YaHei", sans-serif';function isDrawableOverlay(e){return"adjust"!==e.type}function isOverlayHidden(e){return Boolean(e.hidden)}function isOverlayLocked(e){return Boolean(e.locked)}function overlayTrack(e,t){const o=Number(e.timelineTrack);return Number.isFinite(o)?Math.max(0,Math.round(o)):t}function overlayLayerRenderOrder(e){return e.map((e,t)=>({overlay:e,index:t,track:overlayTrack(e,t)})).sort((e,t)=>t.track-e.track||e.index-t.index).map(e=>e.overlay)}function strokeStyle(e,t,o){e.strokeStyle=t,e.lineWidth=o,e.lineCap="round",e.lineJoin="round"}function drawArrowHead(e,t,o,n,r,a){const i=Math.atan2(r-o,n-t),s=Math.max(12,3.5*a);e.beginPath(),e.moveTo(n,r),e.lineTo(n-s*Math.cos(i-Math.PI/7),r-s*Math.sin(i-Math.PI/7)),e.moveTo(n,r),e.lineTo(n-s*Math.cos(i+Math.PI/7),r-s*Math.sin(i+Math.PI/7)),e.stroke()}function normalizeOverlayRotation(e){if(!Number.isFinite(e))return 0;let t=e%360;return t>180&&(t-=360),t<-180&&(t+=360),Math.abs(t)<.001?0:t}function getOverlayRotation(e){return normalizeOverlayRotation(e.rotation??0)}function overlayBBox(e){switch(e.type){case"pen":{let t=1/0,o=1/0,n=-1/0,r=-1/0;for(let a=0;a<e.points.length;a+=2)t=Math.min(t,e.points[a]),n=Math.max(n,e.points[a]),o=Math.min(o,e.points[a+1]),r=Math.max(r,e.points[a+1]);return{x:t,y:o,w:n-t,h:r-o}}case"line":case"arrow":return{x:Math.min(e.x1,e.x2),y:Math.min(e.y1,e.y2),w:Math.abs(e.x2-e.x1),h:Math.abs(e.y2-e.y1)};case"rect":case"ellipse":case"sticker":case"adjust":return{x:e.x,y:e.y,w:e.w,h:e.h};case"text":return textBBox(e)}}function textLines(e){return String(e.text||"").split(/\r?\n/)}function textLineHeight(e){return e.fontSize*(e.lineHeight??1.15)}function textPaddingX(e){return e.paddingX??0}function textPaddingY(e){return e.paddingY??0}function textContentWidth(e){const t=Math.max(.6*e.fontSize,...textLines(e).map(t=>Math.max(1,t.length)*e.fontSize*.6));return Math.max(1,e.width??t+2*textPaddingX(e))}function textBBox(e){const t=textLines(e);return{x:e.x,y:e.y,w:textContentWidth(e),h:Math.max(e.fontSize,t.length*textLineHeight(e))+2*textPaddingY(e)}}function textFont(e){const t=e.fontWeight??"700",o=e.italic?"italic ":"",n=e.fontFamily?`"${e.fontFamily}", ${TEXT_FONT_STACK}`:TEXT_FONT_STACK;return`${o}${t} ${e.fontSize}px ${n}`}function textLineX(e,t,o,n){const r=textPaddingX(t),a=t.align??"left",i=e.measureText(o||" ").width;return"center"===a?t.x+n/2-i/2:"right"===a?t.x+n-r-i:t.x+r}function overlayCenter(e){const t=overlayBBox(e);return{x:t.x+t.w/2,y:t.y+t.h/2}}function rotatePoint(e,t,o,n,r){const a=r*DEG2RAD,i=Math.cos(a),s=Math.sin(a),l=e-o,d=t-n;return{x:o+l*i-d*s,y:n+l*s+d*i}}function scalePoint(e,t,o,n,r){return{x:o+(e-o)*r,y:n+(t-n)*r}}function overlayTimeRange(e){const t=e,o=Number.isFinite(t.startAt)?Math.max(0,Number(t.startAt)):null,n=Number.isFinite(t.endAt)?Math.max(o??0,Number(t.endAt)):null;if(null==o&&null==n)return null;const r=o??0;return{start:r,end:Math.max(r,n??r)}}function isOverlayActiveAt(e,t){const o=overlayTimeRange(e);return!o||Number.isFinite(t)&&t>=o.start&&t<=o.end}function filterOverlaysAtTime(e,t){if(!e?.length)return[];const o=e.filter(e=>!isOverlayHidden(e));return Number.isFinite(t)?o.filter(e=>isOverlayActiveAt(e,t)):o}function drawOverlay(e,t,o){if(isOverlayHidden(t))return;if(!isDrawableOverlay(t))return;const n=getOverlayRotation(t);if(n){const r=overlayCenter(t);return e.save(),e.translate(r.x,r.y),e.rotate(n*DEG2RAD),e.translate(-r.x,-r.y),drawOverlayBase(e,t,o),void e.restore()}drawOverlayBase(e,t,o)}function drawOverlayBase(e,t,o){switch(t.type){case"pen":strokeStyle(e,t.color,t.width),e.beginPath(),e.moveTo(t.points[0],t.points[1]);for(let o=2;o<t.points.length;o+=2)e.lineTo(t.points[o],t.points[o+1]);e.stroke();break;case"line":case"arrow":strokeStyle(e,t.color,t.width),e.beginPath(),e.moveTo(t.x1,t.y1),e.lineTo(t.x2,t.y2),e.stroke(),"arrow"===t.type&&drawArrowHead(e,t.x1,t.y1,t.x2,t.y2,t.width);break;case"rect":strokeStyle(e,t.color,t.width),e.strokeRect(t.x,t.y,t.w,t.h);break;case"ellipse":strokeStyle(e,t.color,t.width),e.beginPath(),e.ellipse(t.x+t.w/2,t.y+t.h/2,Math.abs(t.w/2),Math.abs(t.h/2),0,0,2*Math.PI),e.stroke();break;case"text":{const o=textBBox(t),n=textLines(t),r=Number.isFinite(t.opacity)?Math.min(1,Math.max(0,(t.opacity??100)/100)):1;e.save(),e.globalAlpha*=r,t.backgroundColor&&"transparent"!==t.backgroundColor&&(e.fillStyle=t.backgroundColor,e.fillRect(t.x,t.y,o.w,o.h)),e.fillStyle=t.color,e.font=textFont(t),e.textBaseline="top",e.strokeStyle=t.strokeColor??"rgba(0,0,0,0.45)",e.lineWidth=t.borderWidth??Math.max(2,t.fontSize/16),e.lineJoin="round",n.forEach((n,r)=>{const a=textLineX(e,t,n,o.w),i=t.y+textPaddingY(t)+r*textLineHeight(t),s=e.measureText(n||" ").width;if(e.lineWidth>0&&e.strokeText(n,a,i),e.fillText(n,a,i),(t.underline||t.strikethrough)&&s>0){const o=Math.max(1,t.fontSize/18);e.fillStyle=t.color,t.underline&&e.fillRect(a,i+.92*t.fontSize,s,o),t.strikethrough&&e.fillRect(a,i+.52*t.fontSize,s,o)}}),e.restore();break}case"sticker":if(t.emoji)e.save(),e.font=.86*Math.min(t.w,t.h)+'px -apple-system, "Apple Color Emoji", "Segoe UI Emoji", sans-serif',e.textAlign="center",e.textBaseline="middle",e.fillText(t.emoji,t.x+t.w/2,t.y+t.h/2),e.restore();else if(t.src){const n=o?.get(t.src);n&&e.drawImage(n,t.x,t.y,t.w,t.h)}}}function drawOverlays(e,t,o,n){const r="number"==typeof n?filterOverlaysAtTime(t,n):t;for(const t of r)!isOverlayHidden(t)&&isDrawableOverlay(t)&&drawOverlay(e,t,o)}async function loadOverlayImages(e){const t=new Map,o=[...new Set(e.filter(e=>"sticker"===e.type&&e.src).map(e=>e.src))];return await Promise.all(o.map(e=>new Promise(o=>{const n=new Image;n.onload=()=>{t.set(e,n),o()},n.onerror=()=>o(),n.src=e}))),t}async function renderOverlaysToPng(e,t,o){const n=e?.filter(e=>!isOverlayHidden(e)&&isDrawableOverlay(e))??[];if(!n.length)return null;const r=document.createElement("canvas");r.width=t,r.height=o;const a=r.getContext("2d");return a?(drawOverlays(a,n,await loadOverlayImages(n)),new Promise(e=>r.toBlob(t=>e(t),"image/png"))):null}function hitTestOverlay(e,t,o,n=12){for(let r=e.length-1;r>=0;r--){const a=e[r];if(!isOverlayHidden(a)&&hitOne(a,t,o,n))return r}return-1}function near(e,t,o,n,r){return Math.abs(e-o)<=r&&Math.abs(t-n)<=r}function nearSegment(e,t,o,n,r,a,i){const s=r-o,l=a-n,d=s*s+l*l||1,m=Math.max(0,Math.min(1,((e-o)*s+(t-n)*l)/d));return(e-(o+m*s))**2+(t-(n+m*l))**2<=i*i}function hitOne(e,t,o,n){const r=getOverlayRotation(e);if(r){const a=overlayCenter(e),i=rotatePoint(t,o,a.x,a.y,-r);return hitOneBase(e,i.x,i.y,n)}return hitOneBase(e,t,o,n)}function hitOneBase(e,t,o,n){switch(e.type){case"pen":for(let r=0;r+3<e.points.length;r+=2)if(nearSegment(t,o,e.points[r],e.points[r+1],e.points[r+2],e.points[r+3],n+e.width/2))return!0;return!1;case"line":case"arrow":return nearSegment(t,o,e.x1,e.y1,e.x2,e.y2,n+e.width/2);case"rect":case"ellipse":return t>=e.x-n&&t<=e.x+e.w+n&&o>=e.y-n&&o<=e.y+e.h+n;case"text":{const r=textBBox(e);return t>=r.x-n&&t<=r.x+r.w+n&&o>=r.y-n&&o<=r.y+r.h+n}case"sticker":return near(t,o,e.x+e.w/2,e.y+e.h/2,Math.max(e.w,e.h)/2+n);case"adjust":return!1}}function fitStickerBox(e,t,o){const n=Math.max(8,o);if(!(e>0&&t>0))return{w:n,h:n};const r=n/Math.max(e,t);return{w:Math.max(8,Math.round(e*r)),h:Math.max(8,Math.round(t*r))}}function scaleOverlay(e,t){const o=Math.max(.05,t),n=overlayCenter(e);switch(e.type){case"pen":return{...e,points:e.points.map((e,t)=>t%2==0?n.x+(e-n.x)*o:n.y+(e-n.y)*o)};case"line":case"arrow":{const t=scalePoint(e.x1,e.y1,n.x,n.y,o),r=scalePoint(e.x2,e.y2,n.x,n.y,o);return{...e,x1:t.x,y1:t.y,x2:r.x,y2:r.y}}case"rect":case"ellipse":case"sticker":case"adjust":return{...e,w:Math.max(8,e.w*o),h:Math.max(8,e.h*o)};case"text":return{...e,fontSize:Math.min(512,Math.max(8,e.fontSize*o)),width:e.width?Math.max(16,e.width*o):e.width,paddingX:e.paddingX?Math.max(0,e.paddingX*o):e.paddingX,paddingY:e.paddingY?Math.max(0,e.paddingY*o):e.paddingY,borderWidth:e.borderWidth?Math.max(0,e.borderWidth*o):e.borderWidth};default:return e}}function rotateOverlay(e,t){return{...e,rotation:normalizeOverlayRotation(t)}}function translateOverlay(e,t,o){switch(e.type){case"pen":{const n=e.points.map((e,n)=>n%2==0?e+t:e+o);return{...e,points:n}}case"line":case"arrow":return{...e,x1:e.x1+t,y1:e.y1+o,x2:e.x2+t,y2:e.y2+o};case"rect":case"ellipse":case"sticker":case"adjust":case"text":return{...e,x:e.x+t,y:e.y+o}}}var DEG2RAD2=Math.PI/180;function rotatedSize(e,t,o){const n=normalizeDeg(o);if(0===n||180===n)return{w:e,h:t};if(90===n||270===n)return{w:t,h:e};const r=n*DEG2RAD2;return{w:Math.round(Math.abs(e*Math.cos(r))+Math.abs(t*Math.sin(r))),h:Math.round(Math.abs(e*Math.sin(r))+Math.abs(t*Math.cos(r)))}}function normalizeDeg(e){return(e%360+360)%360}function evenize(e){const t=Math.round(e);return t-t%2}function centeredMaxRect(e,t){let o=e.w,n=o/t;return n>e.h&&(n=e.h,o=n*t),{x:Math.round((e.w-o)/2),y:Math.round((e.h-n)/2),width:Math.round(o),height:Math.round(n)}}function fitRects(e,t,o){const n={x:0,y:0,width:e.width,height:e.height},r={x:0,y:0,width:t.w,height:t.h};return"cover"===o?{src:centeredMaxRect({w:e.width,h:e.height},t.w/t.h),dst:r}:"contain"===o?{src:n,dst:centeredMaxRect({w:t.w,h:t.h},e.width/e.height)}:{src:n,dst:r}}function outputSize(e,t){if(t.scale)return{w:evenize(t.scale.width),h:evenize(t.scale.height)};if(t.crop)return{w:evenize(t.crop.width),h:evenize(t.crop.height)};const o=rotatedSize(e.w,e.h,t.rotation);return{w:evenize(o.w),h:evenize(o.h)}}function dataUrlToBlob(e){const t=e.match(/^data:(image\/(?:png|jpe?g));base64,([a-z0-9+/=]+)$/i);if(!t)return null;const o=atob(t[2]),n=new Uint8Array(o.length);for(let e=0;e<o.length;e++)n[e]=o.charCodeAt(e);return new Blob([n],{type:t[1].toLowerCase()})}async function buildVideoExportFormData(e,t,o=[]){const n=e.getExportPlan(),r=new FormData;n.videoSrcOrder.forEach((e,o)=>{const n=t[e];n&&r.append(`video_${o}`,n,n.name||`video_${o}.mp4`)}),n.audioSrcOrder.forEach((e,t)=>{const n=o[e];n&&r.append(`audio_${t}`,n,n.name||`audio_${t}`)});const a=overlayLayerRenderOrder(n.state.overlays??[]).filter(e=>!isOverlayHidden(e)&&isDrawableOverlay(e)),i=outputSize(n.state.canvas,n.state);for(let e=0;e<a.length;e++){const t=await renderOverlaysToPng([a[e]],i.w,i.h);t&&r.append(`textOverlay_${e}`,t,`textOverlay_${e}.png`)}const s=n.state.poster?.useAsVideoCover?n.state.poster.preview||n.state.poster.src:"",l=s?dataUrlToBlob(s):null;if(l){const e="image/png"===l.type?"video-cover.png":"video-cover.jpg";r.append("videoCover",l,e)}const d=n.state.poster?.preview||n.state.poster?.src?{...n.state,poster:{...n.state.poster,preview:void 0,src:void 0}}:n.state;return r.append("editState",JSON.stringify(d)),r}var StrokeCommon={color:zod.z.string().max(32),width:zod.z.number().positive().max(200)},RotationCommon={rotation:zod.z.number().min(-180).max(180).optional()},TimelineCommon={startAt:zod.z.number().min(0).optional(),endAt:zod.z.number().min(0).optional(),timelineTrack:zod.z.number().int().min(0).max(99).optional(),hidden:zod.z.boolean().optional(),locked:zod.z.boolean().optional()},FilterCommon={brightness:zod.z.number().min(-1).max(1).default(0),contrast:zod.z.number().min(-1).max(1).default(0),saturation:zod.z.number().min(-1).max(1).default(0),temperature:zod.z.number().min(-1).max(1).default(0),tint:zod.z.number().min(-1).max(1).default(0),vibrance:zod.z.number().min(-1).max(1).default(0),gamma:zod.z.number().min(-1).max(1).default(0),highlights:zod.z.number().min(-1).max(1).default(0),shadows:zod.z.number().min(-1).max(1).default(0),whites:zod.z.number().min(-1).max(1).default(0),blacks:zod.z.number().min(-1).max(1).default(0),lightSense:zod.z.number().min(-1).max(1).default(0),sharpen:zod.z.number().min(0).max(1).default(0),clarity:zod.z.number().min(0).max(1).default(0),grain:zod.z.number().min(0).max(1).default(0),fade:zod.z.number().min(0).max(1).default(0),vignette:zod.z.number().min(0).max(1).default(0)},Overlay=zod.z.discriminatedUnion("type",[zod.z.object({type:zod.z.literal("pen"),points:zod.z.array(zod.z.number()).min(4),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("line"),x1:zod.z.number(),y1:zod.z.number(),x2:zod.z.number(),y2:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("arrow"),x1:zod.z.number(),y1:zod.z.number(),x2:zod.z.number(),y2:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("rect"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number(),h:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("ellipse"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number(),h:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("text"),x:zod.z.number(),y:zod.z.number(),text:zod.z.string().max(500),color:zod.z.string().max(32),fontSize:zod.z.number().positive().max(512),fontFamily:zod.z.string().max(120).optional(),fontWeight:zod.z.string().max(20).optional(),italic:zod.z.boolean().optional(),underline:zod.z.boolean().optional(),strikethrough:zod.z.boolean().optional(),align:zod.z.enum(["left","center","right"]).optional(),width:zod.z.number().positive().max(8192).optional(),backgroundColor:zod.z.string().max(32).optional(),strokeColor:zod.z.string().max(32).optional(),borderWidth:zod.z.number().min(0).max(64).optional(),paddingX:zod.z.number().min(0).max(256).optional(),paddingY:zod.z.number().min(0).max(256).optional(),lineHeight:zod.z.number().positive().max(4).optional(),opacity:zod.z.number().min(0).max(100).optional(),...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("sticker"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number().positive(),h:zod.z.number().positive(),emoji:zod.z.string().max(16).optional(),src:zod.z.string().optional(),...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("adjust"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number().positive(),h:zod.z.number().positive(),layerKind:zod.z.enum(["adjust","filter"]).optional(),filterPreset:zod.z.string().max(32).optional(),...FilterCommon,...TimelineCommon,...RotationCommon})]),Clip=zod.z.object({srcIdx:zod.z.number().int().min(0).max(7),in:zod.z.number().min(0),out:zod.z.number().min(0),hidden:zod.z.boolean().optional(),locked:zod.z.boolean().optional()}),AudioClip=zod.z.object({srcIdx:zod.z.number().int().min(0).max(2),track:zod.z.number().int().min(0).default(0),startAt:zod.z.number().min(0),in:zod.z.number().min(0),out:zod.z.number().min(0),speed:zod.z.number().min(.5).max(2).default(1),volume:zod.z.number().min(0).max(10),muted:zod.z.boolean().optional(),locked:zod.z.boolean().optional(),fadeIn:zod.z.number().min(0).default(0),fadeOut:zod.z.number().min(0).default(0)}),Transition=zod.z.object({type:zod.z.enum(["none","fade","slide","wipe","flip","clockWipe","star","circle","rectangle"]).default("none"),duration:zod.z.number().min(0).max(2).default(.4)}),ExportSettings=zod.z.object({fileName:zod.z.string().max(120).optional(),format:zod.z.enum(["mp4","mov","mxf"]).default("mp4"),width:zod.z.number().int().min(2).max(8192).optional(),height:zod.z.number().int().min(2).max(8192).optional(),frameRate:zod.z.number().int().min(12).max(120).default(30),videoBitrateKbps:zod.z.number().int().min(100).max(5e4).optional(),audioBitrateKbps:zod.z.number().int().min(32).max(1024).optional(),audioCodec:zod.z.enum(["aac","mp3"]).default("aac")}).optional(),DEFAULT_FILTERS={brightness:0,contrast:0,saturation:0,temperature:0,tint:0,vibrance:0,gamma:0,highlights:0,shadows:0,whites:0,blacks:0,lightSense:0,sharpen:0,clarity:0,grain:0,fade:0,vignette:0};zod.z.object({clips:zod.z.array(Clip).min(1).max(50),audioClips:zod.z.array(AudioClip).max(8).default([]),canvas:zod.z.object({w:zod.z.number().int().min(2).max(4096),h:zod.z.number().int().min(2).max(4096)}),crop:zod.z.object({x:zod.z.number().min(0),y:zod.z.number().min(0),width:zod.z.number().positive(),height:zod.z.number().positive()}).optional(),scale:zod.z.object({width:zod.z.number().positive(),height:zod.z.number().positive(),fit:zod.z.enum(["contain","cover","force"]),backgroundColor:zod.z.string().max(32).optional()}).optional(),rotation:zod.z.number().min(-180).max(180).default(0),flipX:zod.z.boolean().default(!1),flipY:zod.z.boolean().default(!1),filters:zod.z.object(FilterCommon).default(DEFAULT_FILTERS),filterPreset:zod.z.string().max(32).optional(),overlays:zod.z.array(Overlay).max(200).optional(),transitions:zod.z.array(Transition).max(49).default([]),keepAudio:zod.z.boolean().default(!0),poster:zod.z.object({time:zod.z.number().min(0),src:zod.z.string().optional(),useAsVideoCover:zod.z.boolean().optional(),preview:zod.z.string().optional()}).optional(),exportSettings:ExportSettings}).superRefine((e,t)=>{e.clips.forEach((e,o)=>{e.out<=e.in&&t.addIssue({code:zod.z.ZodIssueCode.custom,message:`clips[${o}].out 必须大于 in`,path:["clips",o,"out"]})}),e.audioClips?.forEach((e,o)=>{e.out<=e.in&&t.addIssue({code:zod.z.ZodIssueCode.custom,message:`audioClips[${o}].out 必须大于 in`,path:["audioClips",o,"out"]})}),e.canvas.w%2==0&&e.canvas.h%2==0||t.addIssue({code:zod.z.ZodIssueCode.custom,message:"canvas 宽高必须为偶数",path:["canvas"]}),null!=e.exportSettings?.width&&e.exportSettings.width%2!=0&&t.addIssue({code:zod.z.ZodIssueCode.custom,message:"exportSettings.width must be even",path:["exportSettings","width"]}),null!=e.exportSettings?.height&&e.exportSettings.height%2!=0&&t.addIssue({code:zod.z.ZodIssueCode.custom,message:"exportSettings.height must be even",path:["exportSettings","height"]})});var FILTER_PRESETS=[{id:"bw",label:"黑白",vf:"hue=s=0",css:"grayscale(1)"},{id:"sepia",label:"复古",vf:"colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131",css:"sepia(0.85)"},{id:"warm",label:"暖阳",vf:"colorbalance=rs=.15:gs=.04:bs=-.15",css:"sepia(0.25) saturate(1.25) brightness(1.03)"},{id:"cool",label:"冷调",vf:"colorbalance=rs=-.14:bs=.16",css:"hue-rotate(12deg) saturate(0.95) brightness(1.02)"},{id:"vivid",label:"鲜艳",vf:"eq=saturation=1.45:contrast=1.08",css:"saturate(1.45) contrast(1.08)"}];function findFilterPreset(e){return e?FILTER_PRESETS.find(t=>t.id===e):void 0}function buildFilterCss(e,t){const o=findFilterPreset(t)?.css??"",n=e.temperature??0,r=e.tint??0,a=e.vibrance??0,i=e.gamma??0,s=e.sharpen??0,l=e.clarity??0;return[`brightness(${1+e.brightness})`,`contrast(${1+e.contrast})`,`saturate(${1+e.saturation})`,o,a?`saturate(${(1+.65*a).toFixed(3)})`:"",n>0?`sepia(${Math.min(.36,.28*n).toFixed(3)})`:"",n?`hue-rotate(${(14*-n).toFixed(2)}deg)`:"",r?`hue-rotate(${(10*r).toFixed(2)}deg)`:"",i?`brightness(${(1+.08*i).toFixed(3)})`:"",l||s?`contrast(${(1+.16*l+.1*s).toFixed(3)})`:""].filter(Boolean).join(" ")}var DEFAULT_SCALE_BACKGROUND="#000000";function normalizeScaleBackgroundColor(e){if("string"!=typeof e)return DEFAULT_SCALE_BACKGROUND;const t=e.trim(),o=t.match(/^#?([0-9a-fA-F]{3})$/);if(o)return`#${o[1].split("").map(e=>e+e).join("").toLowerCase()}`;const n=t.match(/^#?([0-9a-fA-F]{6})$/);return n?`#${n[1].toLowerCase()}`:DEFAULT_SCALE_BACKGROUND}function hasAdjustmentEffect(e){return Boolean(e.filterPreset)||Object.keys(DEFAULT_FILTERS).some(t=>Math.abs(Number(e[t])||0)>1e-4)}function applyAdjustmentOverlay(e,t,o,n){if(!hasAdjustmentEffect(o))return;const r=Math.max(0,Math.round(o.x*n)),a=Math.max(0,Math.round(o.y*n)),i=Math.min(t.width-r,Math.max(1,Math.round(o.w*n))),s=Math.min(t.height-a,Math.max(1,Math.round(o.h*n)));if(i<=0||s<=0)return;const l=document.createElement("canvas");l.width=i,l.height=s;const d=l.getContext("2d");d&&(d.drawImage(t,r,a,i,s,0,0,i,s),e.save(),e.filter=buildFilterCss({...DEFAULT_FILTERS,...o},o.filterPreset),e.drawImage(l,r,a,i,s),e.restore(),e.filter="none")}function drawLayeredOverlays(e,t,o,n,r,a=1){if(o?.length){e.setTransform(a,0,0,a,0,0);for(const i of overlayLayerRenderOrder(o))isOverlayHidden(i)||("number"!=typeof r||isOverlayActiveAt(i,r))&&("adjust"===i.type?(e.setTransform(1,0,0,1,0,0),applyAdjustmentOverlay(e,t,i,a),e.setTransform(a,0,0,a,0,0)):drawOverlay(e,i,n));e.setTransform(1,0,0,1,0,0)}}function drawVideoFrame(e,t,o,n,r,a=1,i,s=!0){const l=outputSize(n,r);e.width=Math.max(2,Math.round(l.w*a)),e.height=Math.max(2,Math.round(l.h*a));const d=e.getContext("2d");if(!d)return;if(Boolean(r.__mePreviewVideoHidden)){d.fillStyle="#000000",d.fillRect(0,0,e.width,e.height);const t=Number.isFinite(r.__mePreviewTimelineTime)?Number(r.__mePreviewTimelineTime):void 0;return void(s&&r.overlays?.length&&drawLayeredOverlays(d,e,r.overlays,i,t,a))}const m=rotatedSize(n.w,n.h,r.rotation),c=r.crop??{x:0,y:0,width:m.w,height:m.h},u=r.scale?.fit??"force",{src:h,dst:z}=fitRects({width:c.width,height:c.height},l,u);"contain"===u&&(d.fillStyle=normalizeScaleBackgroundColor(r.scale?.backgroundColor),d.fillRect(0,0,e.width,e.height)),d.filter=buildFilterCss(r.filters,r.filterPreset),d.save(),"contain"===u&&(d.beginPath(),d.rect(a*z.x,a*z.y,a*z.width,a*z.height),d.clip()),d.translate(a*z.x,a*z.y),d.scale(a*z.width/h.width,a*z.height/h.height),d.translate(-(c.x+h.x),-(c.y+h.y)),d.translate(m.w/2,m.h/2),d.rotate(r.rotation*DEG2RAD2),d.scale(r.flipX?-1:1,r.flipY?-1:1);const p=fitRects({width:o.w,height:o.h},{w:n.w,h:n.h},"cover");d.drawImage(t,p.src.x,p.src.y,p.src.width,p.src.height,-n.w/2,-n.h/2,n.w,n.h),d.restore(),d.filter="none";const x=Number.isFinite(r.__mePreviewTimelineTime)?Number(r.__mePreviewTimelineTime):void 0;s&&r.overlays?.length&&drawLayeredOverlays(d,e,r.overlays,i,x,a)}function seekVideo(e,t){return new Promise(o=>{const n=()=>{e.removeEventListener("seeked",n),o()};e.addEventListener("seeked",n),e.currentTime=Math.min(Math.max(0,t),e.duration||t)})}async function generateThumbnails(e,t,o=160){const n=e.duration;if(!n||!isFinite(n)||t<=0)return[];const r=e.videoWidth||16,a=e.videoHeight||9,i=Math.min(o,r),s=Math.max(1,Math.round(i*a/r)),l=document.createElement("canvas");l.width=i,l.height=s;const d=l.getContext("2d");if(!d)return[];const m=[];for(let o=0;o<t;o++)await seekVideo(e,n*(o+.5)/t),d.drawImage(e,0,0,i,s),m.push(l.toDataURL("image/jpeg",.6));return m}function createFullscreenToggle(e,t={}){const o=t.mode??"overlay",n=document.createElement("button");n.type="button",n.className=["me-fullscreen-toggle",t.className].filter(Boolean).join(" "),n.dataset.meFullscreenToggle="true",n.dataset.mode=o,n.title="全屏 / 退出全屏",n.style.cssText=["overlay"===o?"position:absolute;left:8px;bottom:8px;z-index:30;":"position:static;","width:32px;height:32px;padding:0;","display:inline-flex;align-items:center;justify-content:center;","border:1px solid var(--me-border,#26262b);border-radius:6px;","background:var(--me-chip,#1c1c20);color:var(--me-fg,#e7e7ee);","cursor:pointer;font-size:15px;line-height:1;opacity:0.9;font:inherit;"].join(""),e.classList.add("me-fullscreen-host");const r=()=>{const t=document.fullscreenElement===e;n.textContent=t?"×":"⛶",n.setAttribute("aria-label",t?"退出全屏":"全屏"),e.classList.toggle("me-is-fullscreen",t),e.dataset.meFullscreen=t?"true":"false"};r();const a=()=>r(),i=()=>{const t=document.fullscreenElement===e?document.exitFullscreen?.():e.requestFullscreen?.();t?.catch?.(()=>{})};return n.addEventListener("click",i),document.addEventListener("fullscreenchange",a),{button:n,dispose:()=>{document.removeEventListener("fullscreenchange",a),n.removeEventListener("click",i),n.remove(),e.classList.remove("me-fullscreen-host","me-is-fullscreen"),delete e.dataset.meFullscreen}}}exports.buildVideoExportFormData=buildVideoExportFormData,exports.createFullscreenToggle=createFullscreenToggle,exports.drawLayeredOverlays=drawLayeredOverlays,exports.drawOverlay=drawOverlay,exports.drawOverlays=drawOverlays,exports.drawVideoFrame=drawVideoFrame,exports.filterOverlaysAtTime=filterOverlaysAtTime,exports.fitStickerBox=fitStickerBox,exports.generateThumbnails=generateThumbnails,exports.getOverlayRotation=getOverlayRotation,exports.hitTestOverlay=hitTestOverlay,exports.isDrawableOverlay=isDrawableOverlay,exports.isOverlayActiveAt=isOverlayActiveAt,exports.isOverlayHidden=isOverlayHidden,exports.isOverlayLocked=isOverlayLocked,exports.loadOverlayImages=loadOverlayImages,exports.overlayBBox=overlayBBox,exports.overlayLayerRenderOrder=overlayLayerRenderOrder,exports.overlayTimeRange=overlayTimeRange,exports.renderOverlaysToPng=renderOverlaysToPng,exports.rotateOverlay=rotateOverlay,exports.scaleOverlay=scaleOverlay,exports.translateOverlay=translateOverlay;
|
package/core/dist/browser.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OverlayT, V as VideoEditStateT } from './state-
|
|
1
|
+
import { O as OverlayT, V as VideoEditStateT } from './state-D7Of7b_y.js';
|
|
2
2
|
import { VideoEditorEngine } from './engine.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
@@ -8,6 +8,10 @@ import 'zod';
|
|
|
8
8
|
* 坐标系 = 最终输出空间(旋转/裁剪/缩放后),导出 PNG 即按输出分辨率渲染。
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
declare function isDrawableOverlay(o: OverlayT): boolean;
|
|
12
|
+
declare function isOverlayHidden(o: OverlayT): boolean;
|
|
13
|
+
declare function isOverlayLocked(o: OverlayT): boolean;
|
|
14
|
+
declare function overlayLayerRenderOrder<T extends OverlayT>(overlays: readonly T[]): T[];
|
|
11
15
|
declare function getOverlayRotation(o: OverlayT): number;
|
|
12
16
|
declare function overlayBBox(o: OverlayT): {
|
|
13
17
|
x: number;
|
|
@@ -15,9 +19,15 @@ declare function overlayBBox(o: OverlayT): {
|
|
|
15
19
|
w: number;
|
|
16
20
|
h: number;
|
|
17
21
|
};
|
|
22
|
+
declare function overlayTimeRange(o: OverlayT): {
|
|
23
|
+
start: number;
|
|
24
|
+
end: number;
|
|
25
|
+
} | null;
|
|
26
|
+
declare function isOverlayActiveAt(o: OverlayT, time: number): boolean;
|
|
27
|
+
declare function filterOverlaysAtTime(overlays: OverlayT[] | undefined, time: number): OverlayT[];
|
|
18
28
|
/** 单个对象绘制;sticker 的位图经 imageCache 提供(加载由调用方负责) */
|
|
19
29
|
declare function drawOverlay(ctx: CanvasRenderingContext2D, o: OverlayT, imageCache?: Map<string, HTMLImageElement>): void;
|
|
20
|
-
declare function drawOverlays(ctx: CanvasRenderingContext2D, overlays: OverlayT[], imageCache?: Map<string, HTMLImageElement
|
|
30
|
+
declare function drawOverlays(ctx: CanvasRenderingContext2D, overlays: OverlayT[], imageCache?: Map<string, HTMLImageElement>, time?: number): void;
|
|
21
31
|
/** sticker 位图预加载(dataURL → HTMLImageElement) */
|
|
22
32
|
declare function loadOverlayImages(overlays: OverlayT[]): Promise<Map<string, HTMLImageElement>>;
|
|
23
33
|
/** 导出:把 overlays 渲染成输出分辨率的透明 PNG Blob(无 overlay 返回 null) */
|
|
@@ -63,6 +73,7 @@ declare function buildVideoExportFormData(engine: VideoEditorEngine, videoFiles:
|
|
|
63
73
|
|
|
64
74
|
/** drawImage 可接受的源(video / image / canvas) */
|
|
65
75
|
type FrameSource = CanvasImageSource;
|
|
76
|
+
declare function drawLayeredOverlays(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, overlays: OverlayT[] | undefined, imageCache?: Map<string, HTMLImageElement>, time?: number, k?: number): void;
|
|
66
77
|
/**
|
|
67
78
|
* 把一帧合成绘到 canvas(物理分辨率 = 输出尺寸 × k)。
|
|
68
79
|
* @param srcDims 活动源原始分辨率(逐片段可能不同)
|
|
@@ -97,4 +108,4 @@ interface FullscreenToggleOptions {
|
|
|
97
108
|
}
|
|
98
109
|
declare function createFullscreenToggle(host: HTMLElement, options?: FullscreenToggleOptions): FullscreenToggle;
|
|
99
110
|
|
|
100
|
-
export { type FrameSource, type FullscreenToggle, type FullscreenToggleOptions, buildVideoExportFormData, createFullscreenToggle, drawOverlay, drawOverlays, drawVideoFrame, fitStickerBox, generateThumbnails, getOverlayRotation, hitTestOverlay, loadOverlayImages, overlayBBox, renderOverlaysToPng, rotateOverlay, scaleOverlay, translateOverlay };
|
|
111
|
+
export { type FrameSource, type FullscreenToggle, type FullscreenToggleOptions, buildVideoExportFormData, createFullscreenToggle, drawLayeredOverlays, drawOverlay, drawOverlays, drawVideoFrame, filterOverlaysAtTime, fitStickerBox, generateThumbnails, getOverlayRotation, hitTestOverlay, isDrawableOverlay, isOverlayActiveAt, isOverlayHidden, isOverlayLocked, loadOverlayImages, overlayBBox, overlayLayerRenderOrder, overlayTimeRange, renderOverlaysToPng, rotateOverlay, scaleOverlay, translateOverlay };
|
package/core/dist/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{outputSize as t,rotatedSize as e,fitRects as n,buildFilterCss as r,DEG2RAD as a,findFilterPreset as i}from"./chunk-USY6UDGL.js";var o=Math.PI/180;function s(t,e,n){t.strokeStyle=e,t.lineWidth=n,t.lineCap="round",t.lineJoin="round"}function c(t){if(!Number.isFinite(t))return 0;let e=t%360;return e>180&&(e-=360),e<-180&&(e+=360),Math.abs(e)<.001?0:e}var l=null;function h(t){return Math.min(512,Math.max(8,Number(t.fontSize)||24))}function u(t){return"center"===t.textAlign||"right"===t.textAlign?t.textAlign:"left"}function d(t){return Number.isFinite(t)&&t>=0}function m(t){const e=function(t){if(!f(t))return null;const e=d(t.startAt)?Number(t.startAt):null,n=d(t.endAt)?Number(t.endAt):null;if(null==e&&null==n)return null;const r=Math.max(0,e??0);return{start:r,end:Math.max(r,n??r)}}(t);return!!e&&e.end>e.start}function f(t){return"pen"===t?.type||"line"===t?.type||"arrow"===t?.type||"rect"===t?.type||"ellipse"===t?.type||"text"===t?.type||"sticker"===t?.type}function x(t){return"text"===t?.type||"sticker"===t?.type||"filter"===t?.type||"adjust"===t?.type}function p(t){return Number.isFinite(t?.timelineTrack)?Math.max(0,Math.round(Number(t.timelineTrack))):0}function g(t){return d(t?.startAt)?Number(t.startAt):0}function y(t){const e=h(t),n=function(t,e){return Number.isFinite(t.paddingX)?Math.max(0,t.paddingX):Math.max(8,Math.round(.18*e))}(t,e),r=function(t,e){return Number.isFinite(t.paddingY)?Math.max(0,t.paddingY):Math.max(6,Math.round(.14*e))}(t,e),a=function(t,e){return(Number.isFinite(t.lineHeight)?Math.max(.9,t.lineHeight):1.1)*e}(t,e),i=function(t,e){const n=function(t,e){const n=null==t?"":String(t);switch(e){case"uppercase":return n.toUpperCase();case"lowercase":return n.toLowerCase();case"capitalize":return n.toLowerCase().replace(/(^|\s)(\S)/g,(t,e,n)=>`${e}${n.toUpperCase()}`);default:return n}}(t,e).replace(/\r\n/g,"\n").split("\n");return n.length?n:[""]}(t.text,t.textTransform),o=typeof document>"u"?null:(l??(l=document.createElement("canvas")),l.getContext("2d")),s=function(t){const e=h(t);return`${t.fontStyle||"normal"} ${t.fontWeight||"700"} ${e}px ${t.fontFamily||'-apple-system, "PingFang SC", "Microsoft YaHei", sans-serif'}`}(t);o&&(o.font=s);const c=i.map(t=>{const n=""===t?" ":t;return o?o.measureText(n).width:Math.max(1,n.length)*e*.6}),d=c.length?Math.max(...c):.6*e,m=Math.max(e,i.length*a),f=Math.max(Number.isFinite(t.width)?t.width:0,d+2*n);return{font:s,fontSize:e,paddingX:n,paddingY:r,lineHeight:a,lines:i,widths:c,boxWidth:f,boxHeight:m+2*r,align:u(t)}}function w(t){return c(t.rotation??0)}function M(t){switch(t.type){case"pen":{let e=1/0,n=1/0,r=-1/0,a=-1/0;for(let i=0;i<t.points.length;i+=2)e=Math.min(e,t.points[i]),r=Math.max(r,t.points[i]),n=Math.min(n,t.points[i+1]),a=Math.max(a,t.points[i+1]);return{x:e,y:n,w:r-e,h:a-n}}case"line":case"arrow":return{x:Math.min(t.x1,t.x2),y:Math.min(t.y1,t.y2),w:Math.abs(t.x2-t.x1),h:Math.abs(t.y2-t.y1)};case"rect":case"ellipse":case"sticker":return{x:t.x,y:t.y,w:t.w,h:t.h};case"text":{const e=y(t);return{x:t.x,y:t.y,w:e.boxWidth,h:e.boxHeight}}}}function b(t){const e=M(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function v(t,e,n,r,a){return{x:n+(t-n)*a,y:r+(e-r)*a}}function k(t,e,n){const r=w(e);if(r){const a=b(e);return t.save(),t.translate(a.x,a.y),t.rotate(r*o),t.translate(-a.x,-a.y),S(t,e,n),void t.restore()}S(t,e,n)}function S(t,e,n){switch(e.type){case"pen":s(t,e.color,e.width),t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let n=2;n<e.points.length;n+=2)t.lineTo(e.points[n],e.points[n+1]);t.stroke();break;case"line":case"arrow":s(t,e.color,e.width),t.beginPath(),t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.stroke(),"arrow"===e.type&&function(t,e,n,r,a,i){const o=Math.atan2(a-n,r-e),s=Math.max(12,3.5*i);t.beginPath(),t.moveTo(r,a),t.lineTo(r-s*Math.cos(o-Math.PI/7),a-s*Math.sin(o-Math.PI/7)),t.moveTo(r,a),t.lineTo(r-s*Math.cos(o+Math.PI/7),a-s*Math.sin(o+Math.PI/7)),t.stroke()}(t,e.x1,e.y1,e.x2,e.y2,e.width);break;case"rect":s(t,e.color,e.width),t.strokeRect(e.x,e.y,e.w,e.h);break;case"ellipse":s(t,e.color,e.width),t.beginPath(),t.ellipse(e.x+e.w/2,e.y+e.h/2,Math.abs(e.w/2),Math.abs(e.h/2),0,0,2*Math.PI),t.stroke();break;case"text":{const n=y(e),r=Number.isFinite(e.opacity)?Math.min(1,Math.max(0,e.opacity/100)):1,a=Number.isFinite(e.borderWidth)?Math.max(0,e.borderWidth):0,i=!1!==e.autoOutline;t.save(),t.globalAlpha*=r,e.backgroundColor&&"transparent"!==e.backgroundColor&&(t.fillStyle=e.backgroundColor,t.fillRect(e.x,e.y,n.boxWidth,n.boxHeight)),t.fillStyle=e.color||"#fff",t.font=n.font,t.textBaseline="top",t.lineJoin="round";const o=e.boxShadow;o&&(t.shadowColor=o.color||"transparent",t.shadowOffsetX=o.x||0,t.shadowOffsetY=o.y||0,t.shadowBlur=o.blur||0),n.lines.forEach((r,o)=>{const s=n.widths[o]??0,c=function(t,e,n){return"center"===e.align?t.x+e.boxWidth/2-n/2:"right"===e.align?t.x+e.boxWidth-e.paddingX-n:t.x+e.paddingX}(e,n,s),l=e.y+n.paddingY+o*n.lineHeight;(a>0||i)&&(t.strokeStyle=a>0?e.borderColor||"#000":e.strokeColor||"rgba(0,0,0,0.45)",t.lineWidth=a>0?a:Math.max(1,n.fontSize/18),t.strokeText(r,c,l)),t.fillText(r,c,l),function(t,e,n,r,a,i){if(!e.textDecoration||i<=0)return;const o=n.fontSize,s=String(e.textDecoration).includes("underline"),c=String(e.textDecoration).includes("line-through");if(s||c){if(t.save(),t.strokeStyle=e.color||"#fff",t.lineWidth=Math.max(1,o/18),s){const e=a+o+Math.max(1,.08*o);t.beginPath(),t.moveTo(r,e),t.lineTo(r+i,e),t.stroke()}if(c){const e=a+.56*o;t.beginPath(),t.moveTo(r,e),t.lineTo(r+i,e),t.stroke()}t.restore()}}(t,e,n,c,l,s)}),t.restore();break}case"sticker":if(e.emoji){const n=function(t){const e=Math.max(8,Number(t?.w)||0),n=Math.max(8,Number(t?.h)||0),r=Math.max(8,.84*Math.min(e,n));return{x:(Number(t?.x)||0)+(e-r)/2,y:(Number(t?.y)||0)+(n-r)/2,size:r}}(e);t.save(),t.font=`${n.size}px -apple-system, "Apple Color Emoji", "Segoe UI Emoji", sans-serif`,t.textAlign="center",t.textBaseline="middle",t.fillText(e.emoji,n.x+n.size/2,n.y+n.size/2),t.restore()}else if(e.src){const r=n?.get(e.src);r&&t.drawImage(r,e.x,e.y,e.w,e.h)}}}function T(t,e,n){for(const r of e)k(t,r,n)}async function N(t){const e=new Map,n=[...new Set(t.filter(t=>"sticker"===t.type&&t.src).map(t=>t.src))];return await Promise.all(n.map(t=>new Promise(n=>{const r=new Image;r.onload=()=>{e.set(t,r),n()},r.onerror=()=>n(),r.src=t}))),e}async function F(t,e,n){if(!t?.length)return null;const r=document.createElement("canvas");r.width=e,r.height=n;const a=r.getContext("2d");return a?(T(a,t,await N(t)),new Promise(t=>r.toBlob(e=>t(e),"image/png"))):null}function C(t,e,n,r=12){for(let a=t.length-1;a>=0;a--)if(A(t[a],e,n,r))return a;return-1}function P(t,e,n,r,a,i,o){const s=a-n,c=i-r,l=s*s+c*c||1,h=Math.max(0,Math.min(1,((t-n)*s+(e-r)*c)/l));return(t-(n+h*s))**2+(e-(r+h*c))**2<=o*o}function A(t,e,n,r){const a=w(t);if(a){const i=b(t),s=function(t,e,n,r,a){const i=a*o,s=Math.cos(i),c=Math.sin(i),l=t-n,h=e-r;return{x:n+l*s-h*c,y:r+l*c+h*s}}(e,n,i.x,i.y,-a);return E(t,s.x,s.y,r)}return E(t,e,n,r)}function E(t,e,n,r){switch(t.type){case"pen":for(let a=0;a+3<t.points.length;a+=2)if(P(e,n,t.points[a],t.points[a+1],t.points[a+2],t.points[a+3],r+t.width/2))return!0;return!1;case"line":case"arrow":return P(e,n,t.x1,t.y1,t.x2,t.y2,r+t.width/2);case"rect":case"ellipse":return e>=t.x-r&&e<=t.x+t.w+r&&n>=t.y-r&&n<=t.y+t.h+r;case"text":{const a=y(t);return e>=t.x-r&&e<=t.x+a.boxWidth+r&&n>=t.y-r&&n<=t.y+a.boxHeight+r}case"sticker":return function(t,e,n,r,a){return Math.abs(t-n)<=a&&Math.abs(e-r)<=a}(e,n,t.x+t.w/2,t.y+t.h/2,Math.max(t.w,t.h)/2+r)}}function W(t,e,n){const r=Math.max(8,n);if(!(t>0&&e>0))return{w:r,h:r};const a=r/Math.max(t,e);return{w:Math.max(8,Math.round(t*a)),h:Math.max(8,Math.round(e*a))}}function z(t,e){const n=Math.max(.05,e),r=b(t);switch(t.type){case"pen":return{...t,points:t.points.map((t,e)=>e%2==0?r.x+(t-r.x)*n:r.y+(t-r.y)*n)};case"line":case"arrow":{const e=v(t.x1,t.y1,r.x,r.y,n),a=v(t.x2,t.y2,r.x,r.y,n);return{...t,x1:e.x,y1:e.y,x2:a.x,y2:a.y}}case"rect":case"ellipse":case"sticker":return{...t,w:Math.max(8,t.w*n),h:Math.max(8,t.h*n)};case"text":return{...t,fontSize:Math.min(512,Math.max(8,t.fontSize*n)),width:Number.isFinite(t.width)?Math.max(80,t.width*n):t.width,paddingX:Number.isFinite(t.paddingX)?Math.max(0,t.paddingX*n):t.paddingX,paddingY:Number.isFinite(t.paddingY)?Math.max(0,t.paddingY*n):t.paddingY,borderWidth:Number.isFinite(t.borderWidth)?Math.max(0,t.borderWidth*n):t.borderWidth,boxShadow:t.boxShadow?{...t.boxShadow,x:(t.boxShadow.x||0)*n,y:(t.boxShadow.y||0)*n,blur:(t.boxShadow.blur||0)*n}:t.boxShadow};default:return t}}function I(t,e){return{...t,rotation:c(e)}}function O(t,e,n){switch(t.type){case"pen":{const r=t.points.map((t,r)=>r%2==0?t+e:t+n);return{...t,points:r}}case"line":case"arrow":return{...t,x1:t.x1+e,y1:t.y1+n,x2:t.x2+e,y2:t.y2+n};case"rect":case"ellipse":case"sticker":case"text":return{...t,x:t.x+e,y:t.y+n}}}async function L(e,n,r=[]){const a=e.getExportPlan(),i=new FormData;a.videoSrcOrder.forEach((t,e)=>{const r=n[t];r&&i.append(`video_${e}`,r,r.name||`video_${e}.mp4`)}),a.audioSrcOrder.forEach((t,e)=>{const n=r[t];n&&i.append(`audio_${e}`,n,n.name||`audio_${e}`)});const o=t(a.state.canvas,a.state),s=a.state.overlays??[],c=s.filter(t=>m(t)),l=s.filter(t=>!m(t)&&f(t)),h=await F(l,o.w,o.h);h&&i.append("overlay",h,"overlay.png");for(let t=0;t<c.length;t++){const e=await F([c[t]],o.w,o.h);e&&i.append(`textOverlay_${t}`,e,`text-overlay-${t}.png`)}const u=a.state.poster?.useAsVideoCover?function(t){const e=String(t??"").match(/^data:(image\/(?:png|jpe?g));base64,([a-z0-9+/=]+)$/i);if(!e)return null;const n=atob(e[2]),r=new Uint8Array(n.length);for(let t=0;t<n.length;t++)r[t]=n.charCodeAt(t);return new Blob([r],{type:e[1].toLowerCase()})}(a.state.poster.preview):null;u&&i.append("videoCover",u,"video-cover.png");const d=a.state.poster?.preview?{...a.state,poster:{...a.state.poster,preview:void 0}}:a.state;return i.append("editState",JSON.stringify(d)),i}function $(t){return Math.max(-1,Math.min(1,Number(t)||0))}function j(t){return Math.max(0,Math.min(1,Number(t)||0))}function Y(t){return Math.max(0,Math.min(1,t))}function D(t){return Math.max(0,Math.min(255,t))}function X(t,e,n){if(t===e)return n<t?0:1;const r=Math.max(0,Math.min(1,(n-t)/(e-t)));return r*r*(3-2*r)}function H(t){return Y(X(.08,.4,t)*(1-X(.6,.92,t))*2.2)}function B(t,e,n=0){const r=43758.5453*Math.sin(12.9898*t+78.233*e+37.719*n);return r-Math.floor(r)}var R=null;function _(t,e,n,r){if(!r||"none"===r)return;const a=function(t,e){return typeof document>"u"?null:(R??(R=document.createElement("canvas")),R.width!==t&&(R.width=t),R.height!==e&&(R.height=e),R)}(e,n),i=a?.getContext("2d");!a||!i||(i.setTransform(1,0,0,1,0,0),i.clearRect(0,0,e,n),i.drawImage(t.canvas,0,0,e,n),t.save(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e,n),t.filter=r,t.drawImage(a,0,0,e,n),t.restore(),t.filter="none")}function U(t,e,n,r={}){if(!function(t={}){return!!["temperature","tint","vibrance","gamma","highlights","shadows","whites","blacks","lightSense"].some(e=>Math.abs($(t[e]))>1e-4)||["sharpen","clarity","grain","fade","vignette"].some(e=>j(t[e])>1e-4)}(r))return;let a;try{a=t.getImageData(0,0,e,n)}catch{return}const i=$(r.temperature),o=$(r.tint),s=$(r.vibrance),c=$(r.gamma),l=$(r.highlights),h=$(r.shadows),u=$(r.whites),d=$(r.blacks),m=$(r.lightSense),f=j(r.sharpen),x=j(r.clarity),p=j(r.grain),g=j(r.fade),y=j(r.vignette),w=1+c*(c>0?1:.5),M=0===c?1:1/Math.max(.01,w),b=.18*i,v=.02*i,k=.18*-i,S=.1*o,T=.12*-o,N=a.data;for(let t=0;t<N.length;t+=4){let e=N[t]/255,n=N[t+1]/255,r=N[t+2]/255;if((0!==i||0!==o)&&(e=Y(e+b+S),n=Y(n+v+T),r=Y(r+k+S)),0!==s){const t=Math.max(e,n,r)-Math.min(e,n,r),a=(e+n+r)/3,i=s>0?s*(1-t):s*(.35+.65*t);e=Y(a+(e-a)*(1+i)),n=Y(a+(n-a)*(1+i)),r=Y(a+(r-a)*(1+i))}if(0!==c&&(e=Y(Math.pow(e,M)),n=Y(Math.pow(n,M)),r=Y(Math.pow(r,M))),0!==l||0!==h||0!==u||0!==d||0!==m||0!==g){const t=.2126*e+.7152*n+.0722*r,a=1-X(.18,.62,t),i=1-X(.04,.32,t),o=h*a*.28+l*X(.38,.84,t)*.24+d*i*.2+u*X(.7,.98,t)*.2+m*H(t)*.18+g*(.12+.06*a);if(e=Y(e+o),n=Y(n+o),r=Y(r+o),g>0){const t=(e+n+r)/3,a=.16*g;e=Y(e*(1-a)+t*a),n=Y(n*(1-a)+t*a),r=Y(r*(1-a)+t*a)}}N[t]=Math.round(255*e),N[t+1]=Math.round(255*n),N[t+2]=Math.round(255*r)}if(f>1e-4||x>1e-4){const t=new Uint8ClampedArray(N),r=4*e;for(let a=1;a<n-1;a++)for(let n=1;n<e-1;n++){const e=a*r+4*n,i=(t[e-4]+t[e+4]+t[e-r]+t[e+r]+4*t[e])/8,o=(t[e-3]+t[e+5]+t[e-r+1]+t[e+r+1]+4*t[e+1])/8,s=(t[e-2]+t[e+6]+t[e-r+2]+t[e+r+2]+4*t[e+2])/8,c=(.2126*t[e]+.7152*t[e+1]+.0722*t[e+2])/255,l=Math.min(1.8,1.45*f+.9*x*H(c));N[e]=D(t[e]+(t[e]-i)*l),N[e+1]=D(t[e+1]+(t[e+1]-o)*l),N[e+2]=D(t[e+2]+(t[e+2]-s)*l)}}if(p>1e-4){const t=26*p;for(let r=0;r<n;r++)for(let n=0;n<e;n++){const a=4*(r*e+n),i=.4+.9*H((.2126*N[a]+.7152*N[a+1]+.0722*N[a+2])/255),o=(B(n,r)-.5)*t*i,s=(B(n,r,1)-.5)*t*.22*p;N[a]=D(N[a]+o+s),N[a+1]=D(N[a+1]+.88*o),N[a+2]=D(N[a+2]+o-s)}}if(y>1e-4){const t=(e-1)/2,r=(n-1)/2,a=Math.sqrt(t*t+r*r)||1;for(let i=0;i<n;i++)for(let n=0;n<e;n++){const o=4*(i*e+n),s=n-t,c=i-r,l=1-X(.32,1,Math.sqrt(s*s+c*c)/a)*y*.62;N[o]=D(N[o]*l),N[o+1]=D(N[o+1]*l),N[o+2]=D(N[o+2]*l)}}t.putImageData(a,0,0)}function q(o,s,c,l,h,u=1,m,y=!0){const w=t(l,h);o.width=Math.max(2,Math.round(w.w*u)),o.height=Math.max(2,Math.round(w.h*u));const M=o.getContext("2d");if(!M)return;const b=e(l.w,l.h,h.rotation),v=h.crop??{x:0,y:0,width:b.w,height:b.h},S=h.scale?.fit??"force",{src:N,dst:F}=n({width:v.width,height:v.height},w,S);"contain"===S&&(M.fillStyle="#000",M.fillRect(0,0,o.width,o.height)),M.filter=r(h.filters,h.filterPreset),M.save(),"contain"===S&&(M.beginPath(),M.rect(u*F.x,u*F.y,u*F.width,u*F.height),M.clip()),M.translate(u*F.x,u*F.y),M.scale(u*F.width/N.width,u*F.height/N.height),M.translate(-(v.x+N.x),-(v.y+N.y)),M.translate(b.w/2,b.h/2),M.rotate(h.rotation*a),M.scale(h.flipX?-1:1,h.flipY?-1:1);const C=n({width:c.w,height:c.h},{w:l.w,h:l.h},"cover");if(M.drawImage(s,C.src.x,C.src.y,C.src.width,C.src.height,-l.w/2,-l.h/2,l.w,l.h),M.restore(),M.filter="none",U(M,o.width,o.height,h.filters),y&&h.overlays?.length){const t=Number.isFinite(h?.__mePreviewTimelineTime)?Number(h.__mePreviewTimelineTime):null,e=null==t?h.overlays:function(t,e){return t?.length?Number.isFinite(e)?t.filter(t=>function(t,e){const n=function(t){if(!f(t)&&"filter"!==t?.type&&"adjust"!==t?.type)return null;const e=d(t.startAt)?Number(t.startAt):null,n=d(t.endAt)?Number(t.endAt):null;if(null==e&&null==n)return null;const r=Math.max(0,e??0);return{start:r,end:Math.max(r,n??r)}}(t);return!n||!!Number.isFinite(e)&&e>=n.start&&e<=n.end}(t,e)):t:[]}(h.overlays,t),n=e.map((t,e)=>({overlay:t,index:e})).filter(t=>x(t.overlay)).sort((t,e)=>{const n=p(e.overlay)-p(t.overlay);if(0!==n)return n;const r=g(t.overlay)-g(e.overlay);return Math.abs(r)>1e-6?r:t.index-e.index}),a=e.filter(t=>!x(t));M.setTransform(u,0,0,u,0,0),n.forEach(t=>"filter"===t.overlay?.type?(M.setTransform(1,0,0,1,0,0),function(t,e,n,r){_(t,e,n,i(r?.filterPreset)?.css??"")}(M,o.width,o.height,t.overlay),void M.setTransform(u,0,0,u,0,0)):"adjust"===t.overlay?.type?(M.setTransform(1,0,0,1,0,0),function(t,e,n,a){_(t,e,n,r(a??{},"")),U(t,e,n,a??{})}(M,o.width,o.height,t.overlay),void M.setTransform(u,0,0,u,0,0)):void k(M,t.overlay,m)),T(M,a,m),M.setTransform(1,0,0,1,0,0)}}function J(t,e){return new Promise(n=>{const r=()=>{t.removeEventListener("seeked",r),n()};t.addEventListener("seeked",r),t.currentTime=Math.min(Math.max(0,e),t.duration||e)})}async function V(t,e,n=160){const r=t.duration;if(!r||!isFinite(r)||e<=0)return[];const a=t.videoWidth||16,i=t.videoHeight||9,o=Math.min(n,a),s=Math.max(1,Math.round(o*i/a)),c=document.createElement("canvas");c.width=o,c.height=s;const l=c.getContext("2d");if(!l)return[];const h=[];for(let n=0;n<e;n++)await J(t,r*(n+.5)/e),l.drawImage(t,0,0,o,s),h.push(c.toDataURL("image/jpeg",.6));return h}function G(t,e={}){const n=e.mode??"overlay",r=document.createElement("button");r.type="button",r.className=["me-fullscreen-toggle",e.className].filter(Boolean).join(" "),r.dataset.meFullscreenToggle="true",r.dataset.mode=n,r.title="全屏 / 退出全屏",r.style.cssText=["overlay"===n?"position:absolute;left:8px;bottom:8px;z-index:30;":"position:static;","width:32px;height:32px;padding:0;","display:inline-flex;align-items:center;justify-content:center;","border:1px solid var(--me-border,#26262b);border-radius:6px;","background:var(--me-chip,#1c1c20);color:var(--me-fg,#e7e7ee);","cursor:pointer;font-size:15px;line-height:1;opacity:0.9;font:inherit;"].join(""),t.classList.add("me-fullscreen-host");const a=()=>{const e=document.fullscreenElement===t;r.textContent=e?"×":"⛶",r.setAttribute("aria-label",e?"退出全屏":"全屏"),t.classList.toggle("me-is-fullscreen",e),t.dataset.meFullscreen=e?"true":"false"};a();const i=()=>a(),o=()=>{(document.fullscreenElement===t?document.exitFullscreen?.():t.requestFullscreen?.())?.catch?.(()=>{})};return r.addEventListener("click",o),document.addEventListener("fullscreenchange",i),{button:r,dispose:()=>{document.removeEventListener("fullscreenchange",i),r.removeEventListener("click",o),r.remove(),t.classList.remove("me-fullscreen-host","me-is-fullscreen"),delete t.dataset.meFullscreen}}}export{L as buildVideoExportFormData,G as createFullscreenToggle,k as drawOverlay,T as drawOverlays,q as drawVideoFrame,W as fitStickerBox,V as generateThumbnails,w as getOverlayRotation,C as hitTestOverlay,N as loadOverlayImages,M as overlayBBox,F as renderOverlaysToPng,I as rotateOverlay,z as scaleOverlay,O as translateOverlay};
|
|
1
|
+
import{overlayLayerRenderOrder as e,isOverlayHidden as t,isDrawableOverlay as r,outputSize as n,renderOverlaysToPng as a,isOverlayActiveAt as o,drawOverlay as i,rotatedSize as s,fitRects as l,buildFilterCss as c,DEG2RAD as d}from"./chunk-VDEZTXEA.js";export{drawOverlay,drawOverlays,filterOverlaysAtTime,fitStickerBox,getOverlayRotation,hitTestOverlay,isDrawableOverlay,isOverlayActiveAt,isOverlayHidden,isOverlayLocked,loadOverlayImages,overlayBBox,overlayLayerRenderOrder,overlayTimeRange,renderOverlaysToPng,rotateOverlay,scaleOverlay,translateOverlay}from"./chunk-VDEZTXEA.js";import{DEFAULT_FILTERS as h}from"./chunk-T5QIAKTR.js";async function m(o,i,s=[]){const l=o.getExportPlan(),c=new FormData;l.videoSrcOrder.forEach((e,t)=>{const r=i[e];r&&c.append(`video_${t}`,r,r.name||`video_${t}.mp4`)}),l.audioSrcOrder.forEach((e,t)=>{const r=s[e];r&&c.append(`audio_${t}`,r,r.name||`audio_${t}`)});const d=l.state.overlays??[],h=e(d).filter(e=>!t(e)&&r(e)),m=n(l.state.canvas,l.state);for(let e=0;e<h.length;e++){const t=await a([h[e]],m.w,m.h);t&&c.append(`textOverlay_${e}`,t,`textOverlay_${e}.png`)}const u=l.state.poster?.useAsVideoCover?l.state.poster.preview||l.state.poster.src:"",f=u?function(e){const t=e.match(/^data:(image\/(?:png|jpe?g));base64,([a-z0-9+/=]+)$/i);if(!t)return null;const r=atob(t[2]),n=new Uint8Array(r.length);for(let e=0;e<r.length;e++)n[e]=r.charCodeAt(e);return new Blob([n],{type:t[1].toLowerCase()})}(u):null;if(f){const e="image/png"===f.type?"video-cover.png":"video-cover.jpg";c.append("videoCover",f,e)}const v=l.state.poster?.preview||l.state.poster?.src?{...l.state,poster:{...l.state.poster,preview:void 0,src:void 0}}:l.state;return c.append("editState",JSON.stringify(v)),c}var u="#000000";function f(e,t,r,n){if(a=r,!Boolean(a.filterPreset)&&!Object.keys(h).some(e=>Math.abs(Number(a[e])||0)>1e-4))return;var a;const o=Math.max(0,Math.round(r.x*n)),i=Math.max(0,Math.round(r.y*n)),s=Math.min(t.width-o,Math.max(1,Math.round(r.w*n))),l=Math.min(t.height-i,Math.max(1,Math.round(r.h*n)));if(s<=0||l<=0)return;const d=document.createElement("canvas");d.width=s,d.height=l;const m=d.getContext("2d");m&&(m.drawImage(t,o,i,s,l,0,0,s,l),e.save(),e.filter=c({...h,...r},r.filterPreset),e.drawImage(d,o,i,s,l),e.restore(),e.filter="none")}function v(r,n,a,s,l,c=1){if(a?.length){r.setTransform(c,0,0,c,0,0);for(const d of e(a))t(d)||("number"!=typeof l||o(d,l))&&("adjust"===d.type?(r.setTransform(1,0,0,1,0,0),f(r,n,d,c),r.setTransform(c,0,0,c,0,0)):i(r,d,s));r.setTransform(1,0,0,1,0,0)}}function g(e,t,r,a,o,i=1,h,m=!0){const f=n(a,o);e.width=Math.max(2,Math.round(f.w*i)),e.height=Math.max(2,Math.round(f.h*i));const g=e.getContext("2d");if(!g)return;if(Boolean(o.__mePreviewVideoHidden)){g.fillStyle="#000000",g.fillRect(0,0,e.width,e.height);const t=Number.isFinite(o.__mePreviewTimelineTime)?Number(o.__mePreviewTimelineTime):void 0;return void(m&&o.overlays?.length&&v(g,e,o.overlays,h,t,i))}const p=s(a.w,a.h,o.rotation),y=o.crop??{x:0,y:0,width:p.w,height:p.h},w=o.scale?.fit??"force",{src:x,dst:b}=l({width:y.width,height:y.height},f,w);"contain"===w&&(g.fillStyle=function(e){if("string"!=typeof e)return u;const t=e.trim(),r=t.match(/^#?([0-9a-fA-F]{3})$/);if(r)return`#${r[1].split("").map(e=>e+e).join("").toLowerCase()}`;const n=t.match(/^#?([0-9a-fA-F]{6})$/);return n?`#${n[1].toLowerCase()}`:u}(o.scale?.backgroundColor),g.fillRect(0,0,e.width,e.height)),g.filter=c(o.filters,o.filterPreset),g.save(),"contain"===w&&(g.beginPath(),g.rect(i*b.x,i*b.y,i*b.width,i*b.height),g.clip()),g.translate(i*b.x,i*b.y),g.scale(i*b.width/x.width,i*b.height/x.height),g.translate(-(y.x+x.x),-(y.y+x.y)),g.translate(p.w/2,p.h/2),g.rotate(o.rotation*d),g.scale(o.flipX?-1:1,o.flipY?-1:1);const T=l({width:r.w,height:r.h},{w:a.w,h:a.h},"cover");g.drawImage(t,T.src.x,T.src.y,T.src.width,T.src.height,-a.w/2,-a.h/2,a.w,a.h),g.restore(),g.filter="none";const O=Number.isFinite(o.__mePreviewTimelineTime)?Number(o.__mePreviewTimelineTime):void 0;m&&o.overlays?.length&&v(g,e,o.overlays,h,O,i)}function p(e,t){return new Promise(r=>{const n=()=>{e.removeEventListener("seeked",n),r()};e.addEventListener("seeked",n),e.currentTime=Math.min(Math.max(0,t),e.duration||t)})}async function y(e,t,r=160){const n=e.duration;if(!n||!isFinite(n)||t<=0)return[];const a=e.videoWidth||16,o=e.videoHeight||9,i=Math.min(r,a),s=Math.max(1,Math.round(i*o/a)),l=document.createElement("canvas");l.width=i,l.height=s;const c=l.getContext("2d");if(!c)return[];const d=[];for(let r=0;r<t;r++)await p(e,n*(r+.5)/t),c.drawImage(e,0,0,i,s),d.push(l.toDataURL("image/jpeg",.6));return d}function w(e,t={}){const r=t.mode??"overlay",n=document.createElement("button");n.type="button",n.className=["me-fullscreen-toggle",t.className].filter(Boolean).join(" "),n.dataset.meFullscreenToggle="true",n.dataset.mode=r,n.title="全屏 / 退出全屏",n.style.cssText=["overlay"===r?"position:absolute;left:8px;bottom:8px;z-index:30;":"position:static;","width:32px;height:32px;padding:0;","display:inline-flex;align-items:center;justify-content:center;","border:1px solid var(--me-border,#26262b);border-radius:6px;","background:var(--me-chip,#1c1c20);color:var(--me-fg,#e7e7ee);","cursor:pointer;font-size:15px;line-height:1;opacity:0.9;font:inherit;"].join(""),e.classList.add("me-fullscreen-host");const a=()=>{const t=document.fullscreenElement===e;n.textContent=t?"×":"⛶",n.setAttribute("aria-label",t?"退出全屏":"全屏"),e.classList.toggle("me-is-fullscreen",t),e.dataset.meFullscreen=t?"true":"false"};a();const o=()=>a(),i=()=>{const t=document.fullscreenElement===e?document.exitFullscreen?.():e.requestFullscreen?.();t?.catch?.(()=>{})};return n.addEventListener("click",i),document.addEventListener("fullscreenchange",o),{button:n,dispose:()=>{document.removeEventListener("fullscreenchange",o),n.removeEventListener("click",i),n.remove(),e.classList.remove("me-fullscreen-host","me-is-fullscreen"),delete e.dataset.meFullscreen}}}export{m as buildVideoExportFormData,w as createFullscreenToggle,v as drawLayeredOverlays,g as drawVideoFrame,y as generateThumbnails};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=.1;function n(t){return t.out-t.in}function e(t){return t.reduce((t,e)=>t+n(e),0)}function r(t,e){let r=0;for(let u=0;u<e&&u<t.length;u++)r+=n(t[u]);return r}function u(t,e){if(!t.length||e<0)return null;let r=0;for(let u=0;u<t.length;u++){const i=n(t[u]);if(e<r+i)return{idx:u,srcTime:t[u].in+(e-r)};r+=i}if(Math.abs(e-r)<1e-9||e<=r){const n=t.length-1;return{idx:n,srcTime:t[n].out}}return null}function i(n,e){const r=u(n,e);if(!r)return n;const i=n[r.idx];return r.srcTime<i.in+t||r.srcTime>i.out-t?n:[...n.slice(0,r.idx),{...i,out:r.srcTime},{...i,in:r.srcTime},...n.slice(r.idx+1)]}function s(t,n){return t.length<=1||!t[n]?t:t.filter((t,e)=>e!==n)}function c(t,n){const e=t[n];return e?[...t.slice(0,n+1),{...e},...t.slice(n+1)]:t}function o(t,n,e){if(n===e||!t[n]||e<0||e>=t.length)return t;const r=[...t],[u]=r.splice(n,1);return r.splice(e,0,u),r}function a(n,e,r,u,i){if(!n[e])return n;const s=n.map(t=>({...t}));return"in"===r?s[e].in=Math.min(Math.max(u,0),s[e].out-t):s[e].out=Math.max(Math.min(u,i),s[e].in+t),s}function f(n,e,r){const u=Math.max(Math.min(n.out,e),t),i=Math.min(Math.max(n.in,0),u-t),s=Math.min(Math.max(n.startAt,0),Math.max(0,r-t));return{...n,in:i,out:u,startAt:s}}function p(t,n=[]){const r=e(t),u=n.reduce((t,n)=>Math.max(t,n.startAt+(n.out-n.in)/Math.max(.01,n.speed??1)),0);return Math.max(r,u)}function h(t){return[...new Set(t.map(t=>t.srcIdx))].sort((t,n)=>t-n)}function l(t,n){const e=new Map(n.map((t,n)=>[t,n]));return t.map(t=>({...t,srcIdx:e.get(t.srcIdx)??0}))}function m(t){return{past:[],present:t,future:[]}}function x(t,n){if(n===t.present)return t;const e=[...t.past,t.present];return e.length>100&&e.shift(),{past:e,present:n,future:[]}}function M(t,n){return n===t.present?t:{...t,present:n}}function d(t){return t.past.length>0}function g(t){return t.future.length>0}function T(t){return d(t)?{past:t.past.slice(0,-1),present:t.past[t.past.length-1],future:[t.present,...t.future]}:t}function A(t){if(!g(t))return t;const[n,...e]=t.future;return{past:[...t.past,t.present],present:n,future:e}}export{t as MIN_CLIP,g as canRedo,d as canUndo,f as clampAudioClip,n as clipDuration,r as clipStartsAt,p as contentDuration,m as createHistory,c as duplicateClip,u as locateOutput,x as pushHistory,A as redo,l as remapSrcIndices,s as removeClip,o as reorderClips,M as replacePresent,i as splitAtOutput,e as totalDuration,a as trimClipEdge,T as undo,h as usedVideoSrcIndices};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e={"tool.trim":"剪辑","tool.crop":"裁剪","tool.tune":"调色","tool.filter":"滤镜","tool.annotate":"标注","tool.sticker":"贴纸","tool.resize":"比例","tune.brightness":"亮度","tune.contrast":"对比","tune.saturation":"饱和","tune.gamma":"Gamma","tune.temperature":"色温","tune.tint":"色调","tune.vibrance":"自然饱和","tune.highlights":"高光","tune.shadows":"阴影","tune.whites":"白色","tune.blacks":"黑色","tune.lightSense":"光感","tune.sharpen":"锐化","tune.clarity":"清晰度","tune.grain":"颗粒","tune.fade":"褪色","tune.vignette":"暗角","overlay.select":"选择","overlay.pen":"画笔","overlay.eraser":"橡皮","overlay.line":"直线","overlay.arrow":"箭头","overlay.rect":"矩形","overlay.ellipse":"椭圆","overlay.text":"文字","overlay.color":"线色","overlay.width":"线宽","overlay.fontSize":"字号","overlay.font":"字体","overlay.align":"对齐","overlay.background":"背景","overlay.copySelected":"复制","overlay.delSelected":"删除选中","overlay.editSelected":"编辑","overlay.pickImage":"选择图片","overlay.hint":"点 emoji/图片添加 → 画布上拖动摆位,拖右下角紫色把手缩放","overlay.textPlaceholder":"输入文字,回车确认","filter.none":"原图","filter.bw":"黑白","filter.sepia":"复古","filter.warm":"暖阳","filter.cool":"冷调","filter.vivid":"鲜艳","ratio.orig":"原始","ratio.free":"自由比例","ratio.9:16":"竖屏 9:16","ratio.16:9":"横屏 16:9","ratio.1:1":"方形 1:1","ratio.4:5":"竖图 4:5","ratio.3:4":"竖图 3:4","ratio.2:3":"竖图 2:3","ratio.1.91:1":"横幅 1.91:1","act.fit":"适应","act.zoomFit":"缩放至适当大小","act.zoomTo":"缩放至 {value}%","act.split":"分割","act.copy":"复制","act.delete":"删除","act.restore":"还原","act.deleteMusic":"删除音乐","act.cancel":"取消","act.exportPoster":"导出封面","act.exporting":"导出中…","act.poster":"🖼 封面","act.again":"再次下载","act.saveDrive":"存网盘","act.changeImage":"← 换一张","act.changeVideo":"← 换一个","crop.rotateLeft":"↺ 向左旋转","crop.flipX":"⇋ 水平翻转","crop.flipY":"⇵ 垂直翻转","crop.rotateLeftShort":"左转","crop.flipXShort":"横翻","crop.flipYShort":"竖翻","tip.close":"关闭(换文件)","tip.undo":"撤销","tip.redo":"重做","tip.resetOpened":"重置到打开文件时","tip.previewZoom":"预览缩放比例","tip.previewZoomOut":"缩小预览","tip.previewZoomIn":"放大预览","tip.previewZoomFit":"适应预览","tip.previewPointer":"指针工具","tip.previewPan":"手工具:拖动画面","tip.poster":"预览并选择封面帧","tip.keepAudio":"原视频声音开关(与音乐混音;预览同步)","tip.split":"在播放头处把当前片段一分为二","tip.zoomOut":"缩小时间轴(Ctrl+滚轮)","tip.zoomIn":"放大时间轴(Ctrl+滚轮)","tip.fit":"缩放到适应宽度","tip.addVideo":"添加视频片段","tip.addAudio":"添加音乐(音频文件,或选含声音的视频自动提取音轨;与原声混音)","tip.dupClip":"复制该片段(插到其后)","tip.delClip":"删除该片段","tip.lockAspect":"锁定纵横比","tip.dblConfirm":"双击确认裁剪","err.notVideo":"请选择视频文件","err.maxVideo":"最多 {max} 个视频素材","err.videoLoad":"视频加载失败,请换一个文件","err.notAudio":"请选择音频文件(mp3/wav/m4a),或含声音的视频(自动提取音轨)","err.maxAudio":"最多 {max} 个音频素材","err.audioLoad":"音频加载失败,请换一个文件","err.processFailed":"处理失败","err.posterFailed":"封面渲染失败","err.canvas":"canvas 不可用","err.imageRead":"图片读取失败,请换一张","err.notImage":"请选择图片文件","err.fileType":"只支持图片或视频文件","err.saveDrive":"存网盘失败","msg.processing":"正在导出中…","msg.exportingHint":"请稍候,导出完成后会自动返回结果。","msg.done":"完成 ✓","msg.loading":"素材加载中…","msg.exported":"已导出:","msg.saving":"存网盘中…","msg.saved":"已存到网盘 ✓","lbl.ratioSection":"画面比例(裁剪,不变形)","lbl.dragToReposition":"↔ 拖动预览可调整裁剪位置","lbl.sizeSection":"导出尺寸(像素;比例不符时 cover 居中裁剪)","lbl.currentOut":"当前输出","lbl.zoomSize":"大小","lbl.noScale":"(未缩放)","lbl.coverNote":"· 比例不一致时居中裁剪(cover),不变形","lbl.audioTrackHint":"♪ 音频轨(右侧 + 添加音乐,与原声混音)","lbl.volume":"音量","lbl.volNote":"(预览最大 100%,导出按设定值)","lbl.music":"音乐","kbd.fit":"⇧ F","poster.title":"选择封面帧","panel.title":"媒体编辑器","panel.subtitle":"上传图片 / 视频,裁剪 · 滤镜 · 文字 · 导出","panel.pick":"点击选择图片或视频","panel.pickHint":"图片用 Filerobot · 视频可裁剪/静音/封面"},o={"简":"簡","体":"體","图":"圖","频":"頻","视":"視","辑":"輯","调":"調","滤":"濾","标":"標","注":"註","贴":"貼","选":"選","择":"擇","线":"線","箭":"箭","头":"頭","复":"複","删":"刪","除":"除","编":"編","边":"邊","输":"輸","入":"入","确":"確","认":"認","饱":"飽","对":"對","暖":"暖","阳":"陽","冷":"冷","纵":"縱","横":"橫","适":"適","应":"應","缩":"縮","实":"實","际":"際","导":"導","出":"出","封":"封","面":"面","换":"換","张":"張","预":"預","览":"覽","动":"動","声":"聲","开":"開","关":"關","与":"與","乐":"樂","混":"混","处":"處","载":"載","错":"錯","误":"誤","读":"讀","仅":"僅","终":"終","稍":"稍","候":"候","返回":"返回","当前":"目前","输出":"輸出","画":"畫","变":"變","音频":"音訊","音轨":"音軌","添加":"新增","删除":"刪除","保存":"儲存","加载":"載入","网盘":"網盤"},t=e=>{let t=e;for(const[e,a]of Object.entries(o).sort((e,o)=>o[0].length-e[0].length))t=t.replaceAll(e,a);return t},a={zh:e,en:{"tool.trim":"Trim","tool.crop":"Crop","tool.tune":"Tune","tool.filter":"Filters","tool.annotate":"Annotate","tool.sticker":"Stickers","tool.resize":"Ratio","tune.brightness":"Brightness","tune.contrast":"Contrast","tune.saturation":"Saturation","tune.gamma":"Gamma","tune.temperature":"Temperature","tune.tint":"Tint","tune.vibrance":"Vibrance","tune.highlights":"Highlights","tune.shadows":"Shadows","tune.whites":"Whites","tune.blacks":"Blacks","tune.lightSense":"Light","tune.sharpen":"Sharpen","tune.clarity":"Clarity","tune.grain":"Grain","tune.fade":"Fade","tune.vignette":"Vignette","overlay.select":"Select","overlay.pen":"Pen","overlay.eraser":"Eraser","overlay.line":"Line","overlay.arrow":"Arrow","overlay.rect":"Rect","overlay.ellipse":"Ellipse","overlay.text":"Text","overlay.color":"Color","overlay.width":"Width","overlay.fontSize":"Size","overlay.font":"Font","overlay.align":"Align","overlay.background":"Background","overlay.copySelected":"Copy","overlay.delSelected":"Delete selected","overlay.editSelected":"Edit","overlay.pickImage":"Pick image","overlay.hint":"Tap emoji/image to add → drag to place, drag the purple corner handle to scale","overlay.textPlaceholder":"Type text, Enter to confirm","filter.none":"Original","filter.bw":"B&W","filter.sepia":"Sepia","filter.warm":"Warm","filter.cool":"Cool","filter.vivid":"Vivid","ratio.orig":"Original","ratio.free":"Free ratio","ratio.9:16":"Portrait 9:16","ratio.16:9":"Landscape 16:9","ratio.1:1":"Square 1:1","ratio.4:5":"Vertical 4:5","ratio.3:4":"Vertical 3:4","ratio.2:3":"Vertical 2:3","ratio.1.91:1":"Wide 1.91:1","act.fit":"Fit","act.zoomFit":"Zoom to fit","act.zoomTo":"Zoom to {value}%","act.split":"Split","act.copy":"Copy","act.delete":"Delete","act.restore":"Reset","act.deleteMusic":"Remove music","act.cancel":"Cancel","act.exportPoster":"Export cover","act.exporting":"Exporting…","act.poster":"🖼 Cover","act.again":"Download again","act.saveDrive":"Save to drive","act.changeImage":"← Change image","act.changeVideo":"← Change file","crop.rotateLeft":"↺ Rotate left","crop.flipX":"⇋ Flip horizontal","crop.flipY":"⇵ Flip vertical","crop.rotateLeftShort":"Rot","crop.flipXShort":"Flip","crop.flipYShort":"Flip","tip.close":"Close (change file)","tip.undo":"Undo","tip.redo":"Redo","tip.resetOpened":"Reset to opened file","tip.previewZoom":"Preview zoom","tip.previewZoomOut":"Zoom out preview","tip.previewZoomIn":"Zoom in preview","tip.previewZoomFit":"Fit preview","tip.previewPointer":"Pointer tool","tip.previewPan":"Hand tool: pan canvas","tip.poster":"Preview and pick a cover frame","tip.keepAudio":"Original audio on/off (mixed with music; preview follows)","tip.split":"Split the current clip at the playhead","tip.zoomOut":"Zoom out timeline (Ctrl+wheel)","tip.zoomIn":"Zoom in timeline (Ctrl+wheel)","tip.fit":"Fit to width","tip.addVideo":"Add video clip","tip.addAudio":"Add music (audio file, or a video with sound to extract its track; mixed with original)","tip.dupClip":"Duplicate clip (insert after)","tip.delClip":"Delete clip","tip.lockAspect":"Lock aspect ratio","tip.dblConfirm":"Double-click to confirm crop","err.notVideo":"Please choose a video file","err.maxVideo":"Up to {max} video sources","err.videoLoad":"Failed to load video, try another file","err.notAudio":"Choose an audio file (mp3/wav/m4a), or a video with sound (audio auto-extracted)","err.maxAudio":"Up to {max} audio sources","err.audioLoad":"Failed to load audio, try another file","err.processFailed":"Processing failed","err.posterFailed":"Failed to render cover","err.canvas":"Canvas unavailable","err.imageRead":"Failed to read image, try another","err.notImage":"Please choose an image file","err.fileType":"Only image or video files are supported","err.saveDrive":"Failed to save to drive","msg.processing":"Exporting…","msg.exportingHint":"Please wait. The result will be returned automatically when export finishes.","msg.done":"Done ✓","msg.loading":"Loading media…","msg.exported":"Exported: ","msg.saving":"Saving…","msg.saved":"Saved to drive ✓","lbl.ratioSection":"Frame ratio (crop, no distortion)","lbl.dragToReposition":"↔ Drag the preview to reposition the crop","lbl.sizeSection":"Export size (px; cover center-crop when ratios differ)","lbl.currentOut":"Output","lbl.zoomSize":"Size","lbl.noScale":"(no scaling)","lbl.coverNote":"· center-cropped (cover) when ratios differ, no distortion","lbl.audioTrackHint":"♪ Audio track (+ on the right to add music, mixed with original)","lbl.volume":"Volume","lbl.volNote":"(preview caps at 100%, export uses the set value)","lbl.music":"Music","kbd.fit":"⇧ F","poster.title":"Pick a cover frame","panel.title":"Media Editor","panel.subtitle":"Upload an image / video — crop · filters · text · export","panel.pick":"Click to choose an image or video","panel.pickHint":"Images via Filerobot · videos: trim/mute/cover"},es:{"tool.trim":"Editar","tool.crop":"Recortar","tool.tune":"Ajustar color","tool.filter":"Filtros","tool.annotate":"Anotar","tool.sticker":"Stickers","tool.resize":"Proporción","tune.brightness":"Brillo","tune.contrast":"Contraste","tune.saturation":"Saturación","tune.gamma":"Gamma","tune.temperature":"Temperatura","tune.tint":"Tinte","tune.vibrance":"Intensidad","tune.highlights":"Altas luces","tune.shadows":"Sombras","tune.whites":"Blancos","tune.blacks":"Negros","tune.lightSense":"Luz","tune.sharpen":"Enfoque","tune.clarity":"Claridad","tune.grain":"Grano","tune.fade":"Desvanecer","tune.vignette":"Viñeta","overlay.select":"Seleccionar","overlay.pen":"Pincel","overlay.eraser":"Borrador","overlay.line":"Línea","overlay.arrow":"Flecha","overlay.rect":"Rectángulo","overlay.ellipse":"Elipse","overlay.text":"Texto","overlay.color":"Color","overlay.width":"Grosor","overlay.fontSize":"Tamaño","overlay.font":"Fuente","overlay.align":"Alinear","overlay.background":"Fondo","overlay.copySelected":"Copiar","overlay.delSelected":"Eliminar seleccionado","overlay.editSelected":"Editar","overlay.pickImage":"Elegir imagen","overlay.hint":"Toca un emoji/imagen para añadirlo → arrastra para colocarlo, arrastra el tirador morado para escalar","overlay.textPlaceholder":"Escribe texto, Enter para confirmar","filter.none":"Original","filter.bw":"Blanco y negro","filter.sepia":"Sepia","filter.warm":"Cálido","filter.cool":"Frío","filter.vivid":"Intenso","ratio.orig":"Original","ratio.free":"Libre","ratio.9:16":"Vertical 9:16","ratio.16:9":"Horizontal 16:9","ratio.1:1":"Cuadrado 1:1","ratio.4:5":"Vertical 4:5","ratio.3:4":"Vertical 3:4","ratio.2:3":"Vertical 2:3","ratio.1.91:1":"Panorámico 1.91:1","act.fit":"Ajustar","act.zoomFit":"Ajustar a pantalla","act.zoomTo":"Zoom al {value}%","act.split":"Dividir","act.copy":"Copiar","act.delete":"Eliminar","act.restore":"Restablecer","act.deleteMusic":"Quitar música","act.cancel":"Cancelar","act.exportPoster":"Exportar portada","act.exporting":"Exportando…","act.poster":"🖼 Portada","act.again":"Descargar de nuevo","act.saveDrive":"Guardar en disco","act.changeImage":"← Cambiar imagen","act.changeVideo":"← Cambiar archivo","crop.rotateLeft":"↺ Girar a la izquierda","crop.flipX":"⇋ Voltear horizontal","crop.flipY":"⇵ Voltear vertical","crop.rotateLeftShort":"Giro","crop.flipXShort":"Flip","crop.flipYShort":"Flip","tip.close":"Cerrar (cambiar archivo)","tip.undo":"Deshacer","tip.redo":"Rehacer","tip.resetOpened":"Restablecer al archivo abierto","tip.previewZoom":"Zoom de vista previa","tip.previewZoomOut":"Reducir vista previa","tip.previewZoomIn":"Ampliar vista previa","tip.previewZoomFit":"Ajustar vista previa","tip.previewPointer":"Herramienta de puntero","tip.previewPan":"Mano: desplazar lienzo","tip.poster":"Previsualizar y elegir portada","tip.keepAudio":"Activar/desactivar audio original (mezclado con música; la vista previa lo refleja)","tip.split":"Dividir el clip actual en el cursor","tip.zoomOut":"Reducir línea de tiempo (Ctrl+rueda)","tip.zoomIn":"Ampliar línea de tiempo (Ctrl+rueda)","tip.fit":"Ajustar al ancho","tip.addVideo":"Añadir clip de vídeo","tip.addAudio":"Añadir música (archivo de audio o vídeo con sonido para extraer la pista; se mezcla con el original)","tip.dupClip":"Duplicar clip (insertar después)","tip.delClip":"Eliminar clip","tip.lockAspect":"Bloquear proporción","tip.dblConfirm":"Doble clic para confirmar recorte","err.notVideo":"Elige un archivo de vídeo","err.maxVideo":"Máximo {max} vídeos","err.videoLoad":"No se pudo cargar el vídeo, prueba con otro archivo","err.notAudio":"Elige un audio (mp3/wav/m4a) o un vídeo con sonido (se extrae automáticamente)","err.maxAudio":"Máximo {max} audios","err.audioLoad":"No se pudo cargar el audio, prueba con otro archivo","err.processFailed":"Error de procesamiento","err.posterFailed":"No se pudo renderizar la portada","err.canvas":"Canvas no disponible","err.imageRead":"No se pudo leer la imagen, prueba con otra","err.notImage":"Elige un archivo de imagen","err.fileType":"Solo se admiten archivos de imagen o vídeo","err.saveDrive":"No se pudo guardar en disco","msg.processing":"Exportando…","msg.exportingHint":"Espera un momento. El resultado se devolverá automáticamente al finalizar.","msg.done":"Listo ✓","msg.loading":"Cargando medios…","msg.exported":"Exportado: ","msg.saving":"Guardando…","msg.saved":"Guardado en disco ✓","lbl.ratioSection":"Proporción de imagen (recorte, sin deformar)","lbl.dragToReposition":"↔ Arrastra la vista previa para reposicionar el recorte","lbl.sizeSection":"Tamaño de exportación (px; recorte cover centrado si la proporción difiere)","lbl.currentOut":"Salida","lbl.zoomSize":"Tamaño","lbl.noScale":"(sin escala)","lbl.coverNote":"· recorte centrado (cover) cuando la proporción difiere, sin deformar","lbl.audioTrackHint":"♪ Pista de audio (+ a la derecha para añadir música, mezclada con el original)","lbl.volume":"Volumen","lbl.volNote":"(la vista previa limita a 100%, la exportación usa el valor definido)","lbl.music":"Música","kbd.fit":"⇧ F","poster.title":"Elegir portada","panel.title":"Editor multimedia","panel.subtitle":"Sube una imagen / vídeo — recorta · filtros · texto · exporta","panel.pick":"Haz clic para elegir una imagen o vídeo","panel.pickHint":"Imágenes con Filerobot · vídeos: cortar/silenciar/portada"},"zh-Hant":Object.fromEntries(Object.entries(e).map(([e,o])=>[e,t(o)]))};function i(e,o,t){let i=a[e]?.[o]??a.zh[o]??o;if(t)for(const[e,o]of Object.entries(t))i=i.replaceAll(`{${e}}`,String(o));return i}var r=[{platform:"tiktok",postType:"video",label:"TikTok Video",shortLabel:"TT·Video",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"instagram",postType:"post",label:"Instagram Post",shortLabel:"IG·Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"instagram",postType:"reels",label:"Instagram Reels",shortLabel:"IG·Reels",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"instagram",postType:"story",label:"Instagram Story",shortLabel:"IG·Story",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"facebook",postType:"post",label:"Facebook Post",shortLabel:"FB·Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"facebook",postType:"reels",label:"Facebook Reels",shortLabel:"FB·Reels",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"youtube",postType:"video",label:"YouTube Video",shortLabel:"YT·Video",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"1080p"},{platform:"youtube",postType:"shorts",label:"YouTube Shorts",shortLabel:"YT·Shorts",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"pinterest",postType:"pin",label:"Pinterest Pin",shortLabel:"PIN",ratio:"2:3",imageSize:"1664x2496",videoRatio:"9:16",videoResolution:"720p"},{platform:"x",postType:"post",label:"X Post",shortLabel:"X·Post",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"720p"},{platform:"linkedin",postType:"post",label:"LinkedIn Post",shortLabel:"LI·Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"linkedin",postType:"video",label:"LinkedIn Video",shortLabel:"LI·Video",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"1080p"},{platform:"threads",postType:"post",label:"Threads Post",shortLabel:"TH·Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"telegram",postType:"post",label:"Telegram Post",shortLabel:"TG·Post",ratio:"1:1",imageSize:"2048x2048",videoRatio:"9:16",videoResolution:"720p"},{platform:"reddit",postType:"post",label:"Reddit Post",shortLabel:"RD·Post",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"720p"}],l={"1:1":"方形 1:1","4:5":"竖图 4:5","3:4":"竖图 3:4","9:16":"竖屏 9:16","16:9":"横屏 16:9","2:3":"竖图 2:3","1.91:1":"横幅 1.91:1"};function n(e){const[o,t]=e.split(":").map(Number);return o&&t?o/t:1}function p(e){const o=new Set,t=[];for(const a of e)a&&!o.has(a)&&(o.add(a),t.push({ratio:a,value:n(a),label:l[a]??a}));return t}var s=p(["1:1","4:5","3:4","2:3","9:16","16:9","1.91:1"]),c=p(["9:16","16:9","1:1","4:5","3:4","2:3","1.91:1"]);function d(e=r){const o=new Set,t=[];for(const a of e){if(!a.videoRatio)continue;const e=`${a.platform}:${a.postType}:${a.videoRatio}`;if(o.has(e))continue;o.add(e);const i=a.label.split(" ").slice(0,-1).join(" ")||a.label;t.push({platform:a.platform,postType:a.postType,label:`${i} ${a.videoRatio}`,ratio:a.videoRatio,value:n(a.videoRatio)})}return t}var u=d();function v(e=r){const o=new Map;for(const t of e){const e=o.get(t.platform);(!e||"post"!==e.postType&&"post"===t.postType)&&o.set(t.platform,t)}return Array.from(o.values()).map(e=>{const[o,t]=e.imageSize.split("x").map(Number),a=e.label.split(" ").slice(0,-1).join(" ")||e.label;return{platform:e.platform,label:`${a} ${e.ratio}`,ratio:e.ratio,value:n(e.ratio),w:o,h:t}})}var m=v();function g(e,o){return e>=1?{w:2*Math.round(o*e/2),h:o}:{w:o,h:2*Math.round(o/e/2)}}function f(e=r){const o=new Set,t=[];for(const a of e){if(!a.videoRatio||!a.videoResolution)continue;const e="1080p"===a.videoResolution?1080:720,{w:i,h:r}=g(n(a.videoRatio),e),l=`${i}x${r}`;o.has(l)||(o.add(l),t.push({label:`${a.shortLabel} ${i}×${r}`,w:i,h:r}))}return t}var h=f();function b(e,o){if(e.isDuplicated)return{};if(0!==(e.rotation??0))return{};const t=o.adjustments?.rotation??0;return t?{rotation:-t}:{}}export{r as DEFAULT_PLATFORM_TARGETS,a as EDITOR_MESSAGES,m as IMAGE_PLATFORM_PRESETS,s as IMAGE_RATIO_PRESETS,u as VIDEO_PLATFORM_RATIO_PRESETS,c as VIDEO_RATIO_PRESETS,h as VIDEO_SIZE_PRESETS,v as buildImagePlatformPresets,d as buildVideoPlatformRatioPresets,f as buildVideoSizePresets,b as compensateAnnotationRotation,n as parseRatio,i as tEditor,t as toHant};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as e}from"../zod/index.js";var t={color:e.string().max(32),width:e.number().positive().max(200)},n={rotation:e.number().min(-180).max(180).optional()},i={startAt:e.number().min(0).optional(),endAt:e.number().min(0).optional(),timelineTrack:e.number().int().min(0).max(99).optional(),hidden:e.boolean().optional(),locked:e.boolean().optional()},a={brightness:e.number().min(-1).max(1).default(0),contrast:e.number().min(-1).max(1).default(0),saturation:e.number().min(-1).max(1).default(0),temperature:e.number().min(-1).max(1).default(0),tint:e.number().min(-1).max(1).default(0),vibrance:e.number().min(-1).max(1).default(0),gamma:e.number().min(-1).max(1).default(0),highlights:e.number().min(-1).max(1).default(0),shadows:e.number().min(-1).max(1).default(0),whites:e.number().min(-1).max(1).default(0),blacks:e.number().min(-1).max(1).default(0),lightSense:e.number().min(-1).max(1).default(0),sharpen:e.number().min(0).max(1).default(0),clarity:e.number().min(0).max(1).default(0),grain:e.number().min(0).max(1).default(0),fade:e.number().min(0).max(1).default(0),vignette:e.number().min(0).max(1).default(0)},o=e.discriminatedUnion("type",[e.object({type:e.literal("pen"),points:e.array(e.number()).min(4),...t,...i,...n}),e.object({type:e.literal("line"),x1:e.number(),y1:e.number(),x2:e.number(),y2:e.number(),...t,...i,...n}),e.object({type:e.literal("arrow"),x1:e.number(),y1:e.number(),x2:e.number(),y2:e.number(),...t,...i,...n}),e.object({type:e.literal("rect"),x:e.number(),y:e.number(),w:e.number(),h:e.number(),...t,...i,...n}),e.object({type:e.literal("ellipse"),x:e.number(),y:e.number(),w:e.number(),h:e.number(),...t,...i,...n}),e.object({type:e.literal("text"),x:e.number(),y:e.number(),text:e.string().max(500),color:e.string().max(32),fontSize:e.number().positive().max(512),fontFamily:e.string().max(120).optional(),fontWeight:e.string().max(20).optional(),italic:e.boolean().optional(),underline:e.boolean().optional(),strikethrough:e.boolean().optional(),align:e.enum(["left","center","right"]).optional(),width:e.number().positive().max(8192).optional(),backgroundColor:e.string().max(32).optional(),strokeColor:e.string().max(32).optional(),borderWidth:e.number().min(0).max(64).optional(),paddingX:e.number().min(0).max(256).optional(),paddingY:e.number().min(0).max(256).optional(),lineHeight:e.number().positive().max(4).optional(),opacity:e.number().min(0).max(100).optional(),...i,...n}),e.object({type:e.literal("sticker"),x:e.number(),y:e.number(),w:e.number().positive(),h:e.number().positive(),emoji:e.string().max(16).optional(),src:e.string().optional(),...i,...n}),e.object({type:e.literal("adjust"),x:e.number(),y:e.number(),w:e.number().positive(),h:e.number().positive(),layerKind:e.enum(["adjust","filter"]).optional(),filterPreset:e.string().max(32).optional(),...a,...i,...n})]),m=e.object({srcIdx:e.number().int().min(0).max(7),in:e.number().min(0),out:e.number().min(0),hidden:e.boolean().optional(),locked:e.boolean().optional()}),r=e.object({srcIdx:e.number().int().min(0).max(2),track:e.number().int().min(0).default(0),startAt:e.number().min(0),in:e.number().min(0),out:e.number().min(0),speed:e.number().min(.5).max(2).default(1),volume:e.number().min(0).max(10),muted:e.boolean().optional(),locked:e.boolean().optional(),fadeIn:e.number().min(0).default(0),fadeOut:e.number().min(0).default(0)}),u=e.object({type:e.enum(["none","fade","slide","wipe","flip","clockWipe","star","circle","rectangle"]).default("none"),duration:e.number().min(0).max(2).default(.4)}),l=e.object({fileName:e.string().max(120).optional(),format:e.enum(["mp4","mov","mxf"]).default("mp4"),width:e.number().int().min(2).max(8192).optional(),height:e.number().int().min(2).max(8192).optional(),frameRate:e.number().int().min(12).max(120).default(30),videoBitrateKbps:e.number().int().min(100).max(5e4).optional(),audioBitrateKbps:e.number().int().min(32).max(1024).optional(),audioCodec:e.enum(["aac","mp3"]).default("aac")}).optional(),s={brightness:0,contrast:0,saturation:0,temperature:0,tint:0,vibrance:0,gamma:0,highlights:0,shadows:0,whites:0,blacks:0,lightSense:0,sharpen:0,clarity:0,grain:0,fade:0,vignette:0},b=e.object({clips:e.array(m).min(1).max(50),audioClips:e.array(r).max(8).default([]),canvas:e.object({w:e.number().int().min(2).max(4096),h:e.number().int().min(2).max(4096)}),crop:e.object({x:e.number().min(0),y:e.number().min(0),width:e.number().positive(),height:e.number().positive()}).optional(),scale:e.object({width:e.number().positive(),height:e.number().positive(),fit:e.enum(["contain","cover","force"]),backgroundColor:e.string().max(32).optional()}).optional(),rotation:e.number().min(-180).max(180).default(0),flipX:e.boolean().default(!1),flipY:e.boolean().default(!1),filters:e.object(a).default(s),filterPreset:e.string().max(32).optional(),overlays:e.array(o).max(200).optional(),transitions:e.array(u).max(49).default([]),keepAudio:e.boolean().default(!0),poster:e.object({time:e.number().min(0),src:e.string().optional(),useAsVideoCover:e.boolean().optional(),preview:e.string().optional()}).optional(),exportSettings:l}).superRefine((t,n)=>{t.clips.forEach((t,i)=>{t.out<=t.in&&n.addIssue({code:e.ZodIssueCode.custom,message:`clips[${i}].out 必须大于 in`,path:["clips",i,"out"]})}),t.audioClips?.forEach((t,i)=>{t.out<=t.in&&n.addIssue({code:e.ZodIssueCode.custom,message:`audioClips[${i}].out 必须大于 in`,path:["audioClips",i,"out"]})}),t.canvas.w%2==0&&t.canvas.h%2==0||n.addIssue({code:e.ZodIssueCode.custom,message:"canvas 宽高必须为偶数",path:["canvas"]}),null!=t.exportSettings?.width&&t.exportSettings.width%2!=0&&n.addIssue({code:e.ZodIssueCode.custom,message:"exportSettings.width must be even",path:["exportSettings","width"]}),null!=t.exportSettings?.height&&t.exportSettings.height%2!=0&&n.addIssue({code:e.ZodIssueCode.custom,message:"exportSettings.height must be even",path:["exportSettings","height"]})});function p(){return{clips:[],audioClips:[],canvas:{w:2,h:2},rotation:0,flipX:!1,flipY:!1,filters:s,transitions:[],keepAudio:!0}}export{r as AudioClip,m as Clip,s as DEFAULT_FILTERS,l as ExportSettings,o as Overlay,u as Transition,b as VideoEditState,p as defaultVideoEditState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=Math.PI/180;function n(n,r,a){const i=e(a);if(0===i||180===i)return{w:n,h:r};if(90===i||270===i)return{w:r,h:n};const o=i*t;return{w:Math.round(Math.abs(n*Math.cos(o))+Math.abs(r*Math.sin(o))),h:Math.round(Math.abs(n*Math.sin(o))+Math.abs(r*Math.cos(o)))}}function e(t){return(t%360+360)%360}function r(t){const n=Math.round(t);return n-n%2}function a(t,n,e=40){const r=Math.min(Math.max(e,t.width),n.w),a=Math.min(Math.max(e,t.height),n.h),i=Math.min(Math.max(0,t.x),n.w-r),o=Math.min(Math.max(0,t.y),n.h-a);return{x:Math.round(i),y:Math.round(o),width:Math.round(r),height:Math.round(a)}}function i(t,n){let e=t.w,r=e/n;return r>t.h&&(r=t.h,e=r*n),{x:Math.round((t.w-e)/2),y:Math.round((t.h-r)/2),width:Math.round(e),height:Math.round(r)}}function o(t,n,e){const r={x:0,y:0,width:t.width,height:t.height},a={x:0,y:0,width:n.w,height:n.h};return"cover"===e?{src:i({w:t.width,h:t.height},n.w/n.h),dst:a}:"contain"===e?{src:r,dst:i({w:n.w,h:n.h},t.width/t.height)}:{src:r,dst:a}}function s(t,e){if(e.scale)return{w:r(e.scale.width),h:r(e.scale.height)};if(e.crop)return{w:r(e.crop.width),h:r(e.crop.height)};const a=n(t.w,t.h,e.rotation);return{w:r(a.w),h:r(a.h)}}var h=[{id:"bw",label:"黑白",vf:"hue=s=0",css:"grayscale(1)"},{id:"sepia",label:"复古",vf:"colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131",css:"sepia(0.85)"},{id:"warm",label:"暖阳",vf:"colorbalance=rs=.15:gs=.04:bs=-.15",css:"sepia(0.25) saturate(1.25) brightness(1.03)"},{id:"cool",label:"冷调",vf:"colorbalance=rs=-.14:bs=.16",css:"hue-rotate(12deg) saturate(0.95) brightness(1.02)"},{id:"vivid",label:"鲜艳",vf:"eq=saturation=1.45:contrast=1.08",css:"saturate(1.45) contrast(1.08)"}];function c(t){return t?h.find(n=>n.id===t):void 0}function u(t,n){const e=c(n)?.css??"",r=t.temperature??0,a=t.tint??0,i=t.vibrance??0,o=t.gamma??0,s=t.sharpen??0,h=t.clarity??0;return[`brightness(${1+t.brightness})`,`contrast(${1+t.contrast})`,`saturate(${1+t.saturation})`,e,i?`saturate(${(1+.65*i).toFixed(3)})`:"",r>0?`sepia(${Math.min(.36,.28*r).toFixed(3)})`:"",r?`hue-rotate(${(14*-r).toFixed(2)}deg)`:"",a?`hue-rotate(${(10*a).toFixed(2)}deg)`:"",o?`brightness(${(1+.08*o).toFixed(3)})`:"",h||s?`contrast(${(1+.16*h+.1*s).toFixed(3)})`:""].filter(Boolean).join(" ")}var l=Math.PI/180,d='-apple-system, "PingFang SC", "Microsoft YaHei", sans-serif';function x(t){return"adjust"!==t.type}function f(t){return Boolean(t.hidden)}function m(t){return Boolean(t.locked)}function M(t,n){const e=Number(t.timelineTrack);return Number.isFinite(e)?Math.max(0,Math.round(e)):n}function w(t){return t.map((t,n)=>({overlay:t,index:n,track:M(t,n)})).sort((t,n)=>n.track-t.track||t.index-n.index).map(t=>t.overlay)}function p(t,n,e){t.strokeStyle=n,t.lineWidth=e,t.lineCap="round",t.lineJoin="round"}function y(t){if(!Number.isFinite(t))return 0;let n=t%360;return n>180&&(n-=360),n<-180&&(n+=360),Math.abs(n)<.001?0:n}function g(t){return y(t.rotation??0)}function b(t){switch(t.type){case"pen":{let n=1/0,e=1/0,r=-1/0,a=-1/0;for(let i=0;i<t.points.length;i+=2)n=Math.min(n,t.points[i]),r=Math.max(r,t.points[i]),e=Math.min(e,t.points[i+1]),a=Math.max(a,t.points[i+1]);return{x:n,y:e,w:r-n,h:a-e}}case"line":case"arrow":return{x:Math.min(t.x1,t.x2),y:Math.min(t.y1,t.y2),w:Math.abs(t.x2-t.x1),h:Math.abs(t.y2-t.y1)};case"rect":case"ellipse":case"sticker":case"adjust":return{x:t.x,y:t.y,w:t.w,h:t.h};case"text":return $(t)}}function k(t){return String(t.text||"").split(/\r?\n/)}function v(t){return t.fontSize*(t.lineHeight??1.15)}function S(t){return t.paddingX??0}function F(t){return t.paddingY??0}function P(t){const n=Math.max(.6*t.fontSize,...k(t).map(n=>Math.max(1,n.length)*t.fontSize*.6));return Math.max(1,t.width??n+2*S(t))}function $(t){const n=k(t);return{x:t.x,y:t.y,w:P(t),h:Math.max(t.fontSize,n.length*v(t))+2*F(t)}}function T(t){const n=b(t);return{x:n.x+n.w/2,y:n.y+n.h/2}}function z(t,n,e,r,a){return{x:e+(t-e)*a,y:r+(n-r)*a}}function j(t){const n=t,e=Number.isFinite(n.startAt)?Math.max(0,Number(n.startAt)):null,r=Number.isFinite(n.endAt)?Math.max(e??0,Number(n.endAt)):null;if(null==e&&null==r)return null;const a=e??0;return{start:a,end:Math.max(a,r??a)}}function I(t,n){const e=j(t);return!e||Number.isFinite(n)&&n>=e.start&&n<=e.end}function N(t,n){if(!t?.length)return[];const e=t.filter(t=>!f(t));return Number.isFinite(n)?e.filter(t=>I(t,n)):e}function W(t,n,e){if(f(n))return;if(!x(n))return;const r=g(n);if(r){const a=T(n);return t.save(),t.translate(a.x,a.y),t.rotate(r*l),t.translate(-a.x,-a.y),C(t,n,e),void t.restore()}C(t,n,e)}function C(t,n,e){switch(n.type){case"pen":p(t,n.color,n.width),t.beginPath(),t.moveTo(n.points[0],n.points[1]);for(let e=2;e<n.points.length;e+=2)t.lineTo(n.points[e],n.points[e+1]);t.stroke();break;case"line":case"arrow":p(t,n.color,n.width),t.beginPath(),t.moveTo(n.x1,n.y1),t.lineTo(n.x2,n.y2),t.stroke(),"arrow"===n.type&&function(t,n,e,r,a,i){const o=Math.atan2(a-e,r-n),s=Math.max(12,3.5*i);t.beginPath(),t.moveTo(r,a),t.lineTo(r-s*Math.cos(o-Math.PI/7),a-s*Math.sin(o-Math.PI/7)),t.moveTo(r,a),t.lineTo(r-s*Math.cos(o+Math.PI/7),a-s*Math.sin(o+Math.PI/7)),t.stroke()}(t,n.x1,n.y1,n.x2,n.y2,n.width);break;case"rect":p(t,n.color,n.width),t.strokeRect(n.x,n.y,n.w,n.h);break;case"ellipse":p(t,n.color,n.width),t.beginPath(),t.ellipse(n.x+n.w/2,n.y+n.h/2,Math.abs(n.w/2),Math.abs(n.h/2),0,0,2*Math.PI),t.stroke();break;case"text":{const e=$(n),r=k(n),a=Number.isFinite(n.opacity)?Math.min(1,Math.max(0,(n.opacity??100)/100)):1;t.save(),t.globalAlpha*=a,n.backgroundColor&&"transparent"!==n.backgroundColor&&(t.fillStyle=n.backgroundColor,t.fillRect(n.x,n.y,e.w,e.h)),t.fillStyle=n.color,t.font=function(t){const n=t.fontWeight??"700",e=t.italic?"italic ":"",r=t.fontFamily?`"${t.fontFamily}", ${d}`:d;return`${e}${n} ${t.fontSize}px ${r}`}(n),t.textBaseline="top",t.strokeStyle=n.strokeColor??"rgba(0,0,0,0.45)",t.lineWidth=n.borderWidth??Math.max(2,n.fontSize/16),t.lineJoin="round",r.forEach((r,a)=>{const i=function(t,n,e,r){const a=S(n),i=n.align??"left",o=t.measureText(e||" ").width;return"center"===i?n.x+r/2-o/2:"right"===i?n.x+r-a-o:n.x+a}(t,n,r,e.w),o=n.y+F(n)+a*v(n),s=t.measureText(r||" ").width;if(t.lineWidth>0&&t.strokeText(r,i,o),t.fillText(r,i,o),(n.underline||n.strikethrough)&&s>0){const e=Math.max(1,n.fontSize/18);t.fillStyle=n.color,n.underline&&t.fillRect(i,o+.92*n.fontSize,s,e),n.strikethrough&&t.fillRect(i,o+.52*n.fontSize,s,e)}}),t.restore();break}case"sticker":if(n.emoji)t.save(),t.font=.86*Math.min(n.w,n.h)+'px -apple-system, "Apple Color Emoji", "Segoe UI Emoji", sans-serif',t.textAlign="center",t.textBaseline="middle",t.fillText(n.emoji,n.x+n.w/2,n.y+n.h/2),t.restore();else if(n.src){const r=e?.get(n.src);r&&t.drawImage(r,n.x,n.y,n.w,n.h)}}}function A(t,n,e,r){const a="number"==typeof r?N(n,r):n;for(const n of a)!f(n)&&x(n)&&W(t,n,e)}async function B(t){const n=new Map,e=[...new Set(t.filter(t=>"sticker"===t.type&&t.src).map(t=>t.src))];return await Promise.all(e.map(t=>new Promise(e=>{const r=new Image;r.onload=()=>{n.set(t,r),e()},r.onerror=()=>e(),r.src=t}))),n}async function Y(t,n,e){const r=t?.filter(t=>!f(t)&&x(t))??[];if(!r.length)return null;const a=document.createElement("canvas");a.width=n,a.height=e;const i=a.getContext("2d");return i?(A(i,r,await B(r)),new Promise(t=>a.toBlob(n=>t(n),"image/png"))):null}function X(t,n,e,r=12){for(let a=t.length-1;a>=0;a--){const i=t[a];if(!f(i)&&R(i,n,e,r))return a}return-1}function E(t,n,e,r,a,i,o){const s=a-e,h=i-r,c=s*s+h*h||1,u=Math.max(0,Math.min(1,((t-e)*s+(n-r)*h)/c));return(t-(e+u*s))**2+(n-(r+u*h))**2<=o*o}function R(t,n,e,r){const a=g(t);if(a){const i=T(t),o=function(t,n,e,r,a){const i=a*l,o=Math.cos(i),s=Math.sin(i),h=t-e,c=n-r;return{x:e+h*o-c*s,y:r+h*s+c*o}}(n,e,i.x,i.y,-a);return H(t,o.x,o.y,r)}return H(t,n,e,r)}function H(t,n,e,r){switch(t.type){case"pen":for(let a=0;a+3<t.points.length;a+=2)if(E(n,e,t.points[a],t.points[a+1],t.points[a+2],t.points[a+3],r+t.width/2))return!0;return!1;case"line":case"arrow":return E(n,e,t.x1,t.y1,t.x2,t.y2,r+t.width/2);case"rect":case"ellipse":return n>=t.x-r&&n<=t.x+t.w+r&&e>=t.y-r&&e<=t.y+t.h+r;case"text":{const a=$(t);return n>=a.x-r&&n<=a.x+a.w+r&&e>=a.y-r&&e<=a.y+a.h+r}case"sticker":return function(t,n,e,r,a){return Math.abs(t-e)<=a&&Math.abs(n-r)<=a}(n,e,t.x+t.w/2,t.y+t.h/2,Math.max(t.w,t.h)/2+r);case"adjust":return!1}}function J(t,n,e){const r=Math.max(8,e);if(!(t>0&&n>0))return{w:r,h:r};const a=r/Math.max(t,n);return{w:Math.max(8,Math.round(t*a)),h:Math.max(8,Math.round(n*a))}}function q(t,n){const e=Math.max(.05,n),r=T(t);switch(t.type){case"pen":return{...t,points:t.points.map((t,n)=>n%2==0?r.x+(t-r.x)*e:r.y+(t-r.y)*e)};case"line":case"arrow":{const n=z(t.x1,t.y1,r.x,r.y,e),a=z(t.x2,t.y2,r.x,r.y,e);return{...t,x1:n.x,y1:n.y,x2:a.x,y2:a.y}}case"rect":case"ellipse":case"sticker":case"adjust":return{...t,w:Math.max(8,t.w*e),h:Math.max(8,t.h*e)};case"text":return{...t,fontSize:Math.min(512,Math.max(8,t.fontSize*e)),width:t.width?Math.max(16,t.width*e):t.width,paddingX:t.paddingX?Math.max(0,t.paddingX*e):t.paddingX,paddingY:t.paddingY?Math.max(0,t.paddingY*e):t.paddingY,borderWidth:t.borderWidth?Math.max(0,t.borderWidth*e):t.borderWidth};default:return t}}function U(t,n){return{...t,rotation:y(n)}}function D(t,n,e){switch(t.type){case"pen":{const r=t.points.map((t,r)=>r%2==0?t+n:t+e);return{...t,points:r}}case"line":case"arrow":return{...t,x1:t.x1+n,y1:t.y1+e,x2:t.x2+n,y2:t.y2+e};case"rect":case"ellipse":case"sticker":case"adjust":case"text":return{...t,x:t.x+n,y:t.y+e}}}export{t as DEG2RAD,h as FILTER_PRESETS,u as buildFilterCss,i as centeredMaxRect,a as clampRect,W as drawOverlay,A as drawOverlays,r as evenize,N as filterOverlaysAtTime,c as findFilterPreset,o as fitRects,J as fitStickerBox,g as getOverlayRotation,X as hitTestOverlay,x as isDrawableOverlay,I as isOverlayActiveAt,f as isOverlayHidden,m as isOverlayLocked,B as loadOverlayImages,e as normalizeDeg,s as outputSize,b as overlayBBox,w as overlayLayerRenderOrder,j as overlayTimeRange,Y as renderOverlaysToPng,U as rotateOverlay,n as rotatedSize,q as scaleOverlay,D as translateOverlay};
|
package/core/dist/engine.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var s=require("zod"),p={color:s.z.string().max(32),width:s.z.number().positive().max(200)},u={rotation:s.z.number().min(-180).max(180).optional()},A=s.z.discriminatedUnion("type",[s.z.object({type:s.z.literal("pen"),points:s.z.array(s.z.number()).min(4),...p,...u}),s.z.object({type:s.z.literal("line"),x1:s.z.number(),y1:s.z.number(),x2:s.z.number(),y2:s.z.number(),...p,...u}),s.z.object({type:s.z.literal("arrow"),x1:s.z.number(),y1:s.z.number(),x2:s.z.number(),y2:s.z.number(),...p,...u}),s.z.object({type:s.z.literal("rect"),x:s.z.number(),y:s.z.number(),w:s.z.number(),h:s.z.number(),...p,...u}),s.z.object({type:s.z.literal("ellipse"),x:s.z.number(),y:s.z.number(),w:s.z.number(),h:s.z.number(),...p,...u}),s.z.object({type:s.z.literal("text"),x:s.z.number(),y:s.z.number(),text:s.z.string().max(500),color:s.z.string().max(32),fontSize:s.z.number().positive().max(512),...u}),s.z.object({type:s.z.literal("sticker"),x:s.z.number(),y:s.z.number(),w:s.z.number().positive(),h:s.z.number().positive(),emoji:s.z.string().max(16).optional(),src:s.z.string().optional(),...u})]),B=s.z.object({srcIdx:s.z.number().int().min(0).max(7),in:s.z.number().min(0),out:s.z.number().min(0)}),I=s.z.object({srcIdx:s.z.number().int().min(0).max(2),startAt:s.z.number().min(0),in:s.z.number().min(0),out:s.z.number().min(0),volume:s.z.number().min(0).max(2)}),w=s.z.object({type:s.z.enum(["none","fade","slide","wipe","flip","clockWipe","star","circle","rectangle"]).default("none"),duration:s.z.number().min(0).max(2).default(.4)}),j=s.z.object({clips:s.z.array(B).min(1).max(50),audioClips:s.z.array(I).max(8).default([]),canvas:s.z.object({w:s.z.number().int().min(2).max(4096),h:s.z.number().int().min(2).max(4096)}),crop:s.z.object({x:s.z.number().min(0),y:s.z.number().min(0),width:s.z.number().positive(),height:s.z.number().positive()}).optional(),scale:s.z.object({width:s.z.number().positive(),height:s.z.number().positive(),fit:s.z.enum(["contain","cover","force"])}).optional(),rotation:s.z.number().min(-180).max(180).default(0),flipX:s.z.boolean().default(!1),flipY:s.z.boolean().default(!1),filters:s.z.object({brightness:s.z.number().min(-1).max(1),contrast:s.z.number().min(-1).max(1),saturation:s.z.number().min(-1).max(1),gamma:s.z.number().min(-1).max(1).default(0)}).default({brightness:0,contrast:0,saturation:0,gamma:0}),filterPreset:s.z.string().max(32).optional(),overlays:s.z.array(A).max(200).optional(),transitions:s.z.array(w).max(49).default([]),keepAudio:s.z.boolean().default(!0),poster:s.z.object({time:s.z.number().min(0)}).optional()}).superRefine((t,i)=>{t.clips.forEach((t,e)=>{t.out<=t.in&&i.addIssue({code:s.z.ZodIssueCode.custom,message:`clips[${e}].out 必须大于 in`,path:["clips",e,"out"]})}),t.audioClips?.forEach((t,e)=>{t.out<=t.in&&i.addIssue({code:s.z.ZodIssueCode.custom,message:`audioClips[${e}].out 必须大于 in`,path:["audioClips",e,"out"]})}),(t.canvas.w%2!=0||t.canvas.h%2!=0)&&i.addIssue({code:s.z.ZodIssueCode.custom,message:"canvas 宽高必须为偶数",path:["canvas"]})});function c(){return{clips:[],audioClips:[],canvas:{w:2,h:2},rotation:0,flipX:!1,flipY:!1,filters:{brightness:0,contrast:0,saturation:0,gamma:0},transitions:[],keepAudio:!0}}var E=100;function m(t){return{past:[],present:t,future:[]}}function d(t,s){if(s===t.present)return t;const i=[...t.past,t.present];return i.length>E&&i.shift(),{past:i,present:s,future:[]}}function y(t,s){return s===t.present?t:{...t,present:s}}function z(t){return t.past.length>0}function f(t){return t.future.length>0}function P(t){return z(t)?{past:t.past.slice(0,-1),present:t.past[t.past.length-1],future:[t.present,...t.future]}:t}function F(t){if(!f(t))return t;const[s,...i]=t.future;return{past:[...t.past,t.present],present:s,future:i}}var l=.1;function b(t){return t.out-t.in}function h(t){return t.reduce((t,s)=>t+b(s),0)}function x(t,s){if(!t.length||s<0)return null;let i=0;for(let e=0;e<t.length;e++){const r=b(t[e]);if(s<i+r)return{idx:e,srcTime:t[e].in+(s-i)};i+=r}if(Math.abs(s-i)<1e-9||s<=i){const s=t.length-1;return{idx:s,srcTime:t[s].out}}return null}function T(t,s){const i=x(t,s);if(!i)return t;const e=t[i.idx];return i.srcTime<e.in+l||i.srcTime>e.out-l?t:[...t.slice(0,i.idx),{...e,out:i.srcTime},{...e,in:i.srcTime},...t.slice(i.idx+1)]}function k(t,s){return t.length<=1||!t[s]?t:t.filter((t,i)=>i!==s)}function O(t,s){const i=t[s];return i?[...t.slice(0,s+1),{...i},...t.slice(s+1)]:t}function V(t,s,i){if(s===i||!t[s]||i<0||i>=t.length)return t;const e=[...t],[r]=e.splice(s,1);return e.splice(i,0,r),e}function X(t,s,i,e,r){if(!t[s])return t;const n=t.map(t=>({...t}));return"in"===i?n[s].in=Math.min(Math.max(e,0),n[s].out-l):n[s].out=Math.max(Math.min(e,r),n[s].in+l),n}function M(t,s,i){const e=Math.max(Math.min(t.out,s),l),r=Math.min(Math.max(t.in,0),e-l),n=Math.min(Math.max(t.startAt,0),Math.max(0,i-l));return{...t,in:r,out:e,startAt:n}}function Y(t,s=[]){const i=h(t),e=s.reduce((t,s)=>Math.max(t,s.startAt+(s.out-s.in)),0);return Math.max(i,e)}function v(t){return[...new Set(t.map(t=>t.srcIdx))].sort((t,s)=>t-s)}function D(t,s){const i=new Map(s.map((t,s)=>[t,s]));return t.map(t=>({...t,srcIdx:i.get(t.srcIdx)??0}))}function g(t){const s=Math.min(Math.max(Math.round(t),2),4096);return s%2==0?s:s-1}var C=t=>Math.min(Math.max(t,-180),180),R=class{constructor(t=c()){this.videoSources=[],this.audioSources=[],this.listeners=new Set,this.transientBase=null,this.getSnapshot=()=>this.history.present,this.subscribe=t=>(this.listeners.add(t),()=>this.listeners.delete(t)),this.history=m(t)}getState(){return this.history.present}emit(){const t=this.history.present;for(const s of this.listeners)s(t)}canUndo(){return z(this.history)}canRedo(){return f(this.history)}undo(){this.transientBase=null,this.history=P(this.history),this.emit()}redo(){this.transientBase=null,this.history=F(this.history),this.emit()}applyMut(t,s=!1){if(s)null===this.transientBase&&(this.transientBase=this.history.present),this.history=y(this.history,t(this.transientBase));else{const s=t(this.transientBase??this.history.present),i=this.transientBase?{...this.history,present:this.transientBase}:this.history;this.history=d(i,s),this.transientBase=null}this.emit()}registerVideoSource(t){const s=this.videoSources.length;this.videoSources.push(t);const i={srcIdx:s,in:0,out:t.duration};return 0===s||0===this.history.present.clips.length?(this.transientBase=null,this.history=m({...c(),clips:[i],canvas:{w:g(t.width),h:g(t.height)},poster:{time:Math.min(1,t.duration/2)}}),this.emit()):this.applyMut(t=>({...t,clips:[...t.clips,i]})),s}registerAudioSource(t){const s=this.audioSources.length;return this.audioSources.push(t),this.applyMut(i=>{const e=M({srcIdx:s,startAt:0,in:0,out:t.duration,volume:1},t.duration,h(i.clips));return{...i,audioClips:[...i.audioClips,e]}}),s}getVideoSource(t){return this.videoSources[t]}getAudioSource(t){return this.audioSources[t]}addClipFromSource(t){const s=this.videoSources[t];s&&this.applyMut(i=>({...i,clips:[...i.clips,{srcIdx:t,in:0,out:s.duration}]}))}splitAtPlayhead(t){this.applyMut(s=>({...s,clips:T(s.clips,t)}))}removeClip(t){this.applyMut(s=>({...s,clips:k(s.clips,t)}))}duplicateClip(t){this.applyMut(s=>({...s,clips:O(s.clips,t)}))}reorderClips(t,s){this.applyMut(i=>({...i,clips:V(i.clips,t,s)}))}trimClip(t,s,i,e){this.applyMut(e=>{const r=e.clips[t];if(!r)return e;const n=this.videoSources[r.srcIdx]?.duration??r.out;return{...e,clips:X(e.clips,t,s,i,n)}},e?.transient)}moveAudioClip(t,s,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,startAt:s})),i?.transient)}trimAudioClip(t,s,i,e){this.applyMut(e=>this.patchAudio(e,t,t=>{if("in"===s){const s=i-t.in;return{...t,in:i,startAt:t.startAt+s}}return{...t,out:i}}),e?.transient)}setAudioVolume(t,s,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,volume:s}),!1),i?.transient)}removeAudioClip(t){this.applyMut(s=>({...s,audioClips:s.audioClips.filter((s,i)=>i!==t)}))}patchAudio(t,s,i,e=!0){const r=t.audioClips[s];if(!r)return t;let n=i(r);if(e){const s=this.audioSources[r.srcIdx]?.duration??r.out;n=M(n,s,h(t.clips))}return{...t,audioClips:t.audioClips.map((t,i)=>i===s?n:t)}}setCrop(t,s){this.applyMut(s=>({...s,crop:t}),s?.transient)}clearCrop(){this.applyMut(t=>({...t,crop:void 0}))}setScale(t){this.applyMut(s=>({...s,scale:t}))}clearScale(){this.applyMut(t=>({...t,scale:void 0}))}setRotation(t,s){this.applyMut(s=>({...s,rotation:C(t)}),s?.transient)}rotateBy(t){this.applyMut(s=>{let i=s.rotation+t;return i>180&&(i-=360),i<-180&&(i+=360),{...s,rotation:C(i)}})}flipX(){this.applyMut(t=>({...t,flipX:!t.flipX}))}flipY(){this.applyMut(t=>({...t,flipY:!t.flipY}))}setFilter(t,s,i){this.applyMut(i=>({...i,filters:{...i.filters,[t]:s}}),i?.transient)}setFilters(t,s){this.applyMut(s=>({...s,filters:{...s.filters,...t}}),s?.transient)}setFilterPreset(t){this.applyMut(s=>({...s,filterPreset:t}))}addOverlay(t){this.applyMut(s=>({...s,overlays:[...s.overlays??[],t]}))}updateOverlay(t,s,i){this.applyMut(i=>{const e=i.overlays??[];return e[t]?{...i,overlays:e.map((i,e)=>e===t?{...i,...s}:i)}:i},i?.transient)}removeOverlay(t){this.applyMut(s=>({...s,overlays:(s.overlays??[]).filter((s,i)=>i!==t)}))}patch(t,s){s?.transient?(null===this.transientBase&&(this.transientBase=this.history.present),this.history=y(this.history,{...this.transientBase,...t}),this.emit()):this.commit(t)}commit(t){const s=t?{...this.history.present,...t}:this.history.present,i=this.transientBase;this.transientBase=null,this.history=d(i?{...this.history,present:i}:this.history,s),this.emit()}setKeepAudio(t){this.applyMut(s=>({...s,keepAudio:t}))}setPoster(t){this.applyMut(s=>({...s,poster:{time:Math.max(0,t)}}))}totalDuration(){return h(this.history.present.clips)}contentDuration(){const t=this.history.present;return Y(t.clips,t.audioClips)}locate(t){return x(this.history.present.clips,t)}usedVideoSources(){return v(this.history.present.clips)}getExportPlan(){const t=this.history.present,s=v(t.clips),i=[...new Set(t.audioClips.map(t=>t.srcIdx))].sort((t,s)=>t-s),e=new Map(i.map((t,s)=>[t,s]));return{state:{...t,clips:D(t.clips,s),audioClips:t.audioClips.map(t=>({...t,srcIdx:e.get(t.srcIdx)??0}))},videoSrcOrder:s,audioSrcOrder:i}}validate(){return j.safeParse(this.getExportPlan().state)}reset(t=c()){this.transientBase=null,this.history=m(t),this.emit()}};exports.VideoEditorEngine=R;
|
|
1
|
+
"use strict";var zod=require("../zod/index.cjs"),StrokeCommon={color:zod.z.string().max(32),width:zod.z.number().positive().max(200)},RotationCommon={rotation:zod.z.number().min(-180).max(180).optional()},TimelineCommon={startAt:zod.z.number().min(0).optional(),endAt:zod.z.number().min(0).optional(),timelineTrack:zod.z.number().int().min(0).max(99).optional(),hidden:zod.z.boolean().optional(),locked:zod.z.boolean().optional()},FilterCommon={brightness:zod.z.number().min(-1).max(1).default(0),contrast:zod.z.number().min(-1).max(1).default(0),saturation:zod.z.number().min(-1).max(1).default(0),temperature:zod.z.number().min(-1).max(1).default(0),tint:zod.z.number().min(-1).max(1).default(0),vibrance:zod.z.number().min(-1).max(1).default(0),gamma:zod.z.number().min(-1).max(1).default(0),highlights:zod.z.number().min(-1).max(1).default(0),shadows:zod.z.number().min(-1).max(1).default(0),whites:zod.z.number().min(-1).max(1).default(0),blacks:zod.z.number().min(-1).max(1).default(0),lightSense:zod.z.number().min(-1).max(1).default(0),sharpen:zod.z.number().min(0).max(1).default(0),clarity:zod.z.number().min(0).max(1).default(0),grain:zod.z.number().min(0).max(1).default(0),fade:zod.z.number().min(0).max(1).default(0),vignette:zod.z.number().min(0).max(1).default(0)},Overlay=zod.z.discriminatedUnion("type",[zod.z.object({type:zod.z.literal("pen"),points:zod.z.array(zod.z.number()).min(4),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("line"),x1:zod.z.number(),y1:zod.z.number(),x2:zod.z.number(),y2:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("arrow"),x1:zod.z.number(),y1:zod.z.number(),x2:zod.z.number(),y2:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("rect"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number(),h:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("ellipse"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number(),h:zod.z.number(),...StrokeCommon,...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("text"),x:zod.z.number(),y:zod.z.number(),text:zod.z.string().max(500),color:zod.z.string().max(32),fontSize:zod.z.number().positive().max(512),fontFamily:zod.z.string().max(120).optional(),fontWeight:zod.z.string().max(20).optional(),italic:zod.z.boolean().optional(),underline:zod.z.boolean().optional(),strikethrough:zod.z.boolean().optional(),align:zod.z.enum(["left","center","right"]).optional(),width:zod.z.number().positive().max(8192).optional(),backgroundColor:zod.z.string().max(32).optional(),strokeColor:zod.z.string().max(32).optional(),borderWidth:zod.z.number().min(0).max(64).optional(),paddingX:zod.z.number().min(0).max(256).optional(),paddingY:zod.z.number().min(0).max(256).optional(),lineHeight:zod.z.number().positive().max(4).optional(),opacity:zod.z.number().min(0).max(100).optional(),...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("sticker"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number().positive(),h:zod.z.number().positive(),emoji:zod.z.string().max(16).optional(),src:zod.z.string().optional(),...TimelineCommon,...RotationCommon}),zod.z.object({type:zod.z.literal("adjust"),x:zod.z.number(),y:zod.z.number(),w:zod.z.number().positive(),h:zod.z.number().positive(),layerKind:zod.z.enum(["adjust","filter"]).optional(),filterPreset:zod.z.string().max(32).optional(),...FilterCommon,...TimelineCommon,...RotationCommon})]),Clip=zod.z.object({srcIdx:zod.z.number().int().min(0).max(7),in:zod.z.number().min(0),out:zod.z.number().min(0),hidden:zod.z.boolean().optional(),locked:zod.z.boolean().optional()}),AudioClip=zod.z.object({srcIdx:zod.z.number().int().min(0).max(2),track:zod.z.number().int().min(0).default(0),startAt:zod.z.number().min(0),in:zod.z.number().min(0),out:zod.z.number().min(0),speed:zod.z.number().min(.5).max(2).default(1),volume:zod.z.number().min(0).max(10),muted:zod.z.boolean().optional(),locked:zod.z.boolean().optional(),fadeIn:zod.z.number().min(0).default(0),fadeOut:zod.z.number().min(0).default(0)}),Transition=zod.z.object({type:zod.z.enum(["none","fade","slide","wipe","flip","clockWipe","star","circle","rectangle"]).default("none"),duration:zod.z.number().min(0).max(2).default(.4)}),ExportSettings=zod.z.object({fileName:zod.z.string().max(120).optional(),format:zod.z.enum(["mp4","mov","mxf"]).default("mp4"),width:zod.z.number().int().min(2).max(8192).optional(),height:zod.z.number().int().min(2).max(8192).optional(),frameRate:zod.z.number().int().min(12).max(120).default(30),videoBitrateKbps:zod.z.number().int().min(100).max(5e4).optional(),audioBitrateKbps:zod.z.number().int().min(32).max(1024).optional(),audioCodec:zod.z.enum(["aac","mp3"]).default("aac")}).optional(),DEFAULT_FILTERS={brightness:0,contrast:0,saturation:0,temperature:0,tint:0,vibrance:0,gamma:0,highlights:0,shadows:0,whites:0,blacks:0,lightSense:0,sharpen:0,clarity:0,grain:0,fade:0,vignette:0},VideoEditState=zod.z.object({clips:zod.z.array(Clip).min(1).max(50),audioClips:zod.z.array(AudioClip).max(8).default([]),canvas:zod.z.object({w:zod.z.number().int().min(2).max(4096),h:zod.z.number().int().min(2).max(4096)}),crop:zod.z.object({x:zod.z.number().min(0),y:zod.z.number().min(0),width:zod.z.number().positive(),height:zod.z.number().positive()}).optional(),scale:zod.z.object({width:zod.z.number().positive(),height:zod.z.number().positive(),fit:zod.z.enum(["contain","cover","force"]),backgroundColor:zod.z.string().max(32).optional()}).optional(),rotation:zod.z.number().min(-180).max(180).default(0),flipX:zod.z.boolean().default(!1),flipY:zod.z.boolean().default(!1),filters:zod.z.object(FilterCommon).default(DEFAULT_FILTERS),filterPreset:zod.z.string().max(32).optional(),overlays:zod.z.array(Overlay).max(200).optional(),transitions:zod.z.array(Transition).max(49).default([]),keepAudio:zod.z.boolean().default(!0),poster:zod.z.object({time:zod.z.number().min(0),src:zod.z.string().optional(),useAsVideoCover:zod.z.boolean().optional(),preview:zod.z.string().optional()}).optional(),exportSettings:ExportSettings}).superRefine((t,e)=>{t.clips.forEach((t,i)=>{t.out<=t.in&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:`clips[${i}].out 必须大于 in`,path:["clips",i,"out"]})}),t.audioClips?.forEach((t,i)=>{t.out<=t.in&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:`audioClips[${i}].out 必须大于 in`,path:["audioClips",i,"out"]})}),t.canvas.w%2==0&&t.canvas.h%2==0||e.addIssue({code:zod.z.ZodIssueCode.custom,message:"canvas 宽高必须为偶数",path:["canvas"]}),null!=t.exportSettings?.width&&t.exportSettings.width%2!=0&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"exportSettings.width must be even",path:["exportSettings","width"]}),null!=t.exportSettings?.height&&t.exportSettings.height%2!=0&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"exportSettings.height must be even",path:["exportSettings","height"]})});function defaultVideoEditState(){return{clips:[],audioClips:[],canvas:{w:2,h:2},rotation:0,flipX:!1,flipY:!1,filters:DEFAULT_FILTERS,transitions:[],keepAudio:!0}}var MAX_DEPTH=100;function createHistory(t){return{past:[],present:t,future:[]}}function pushHistory(t,e){if(e===t.present)return t;const i=[...t.past,t.present];return i.length>MAX_DEPTH&&i.shift(),{past:i,present:e,future:[]}}function replacePresent(t,e){return e===t.present?t:{...t,present:e}}function canUndo(t){return t.past.length>0}function canRedo(t){return t.future.length>0}function undo(t){return canUndo(t)?{past:t.past.slice(0,-1),present:t.past[t.past.length-1],future:[t.present,...t.future]}:t}function redo(t){if(!canRedo(t))return t;const[e,...i]=t.future;return{past:[...t.past,t.present],present:e,future:i}}var MIN_CLIP=.1;function clipDuration(t){return t.out-t.in}function totalDuration(t){return t.reduce((t,e)=>t+clipDuration(e),0)}function locateOutput(t,e){if(!t.length||e<0)return null;let i=0;for(let o=0;o<t.length;o++){const n=clipDuration(t[o]);if(e<i+n)return{idx:o,srcTime:t[o].in+(e-i)};i+=n}if(Math.abs(e-i)<1e-9||e<=i){const e=t.length-1;return{idx:e,srcTime:t[e].out}}return null}function splitAtOutput(t,e){const i=locateOutput(t,e);if(!i)return t;const o=t[i.idx];return i.srcTime<o.in+MIN_CLIP||i.srcTime>o.out-MIN_CLIP?t:[...t.slice(0,i.idx),{...o,out:i.srcTime},{...o,in:i.srcTime},...t.slice(i.idx+1)]}function removeClip(t,e){return t.length<=1||!t[e]?t:t.filter((t,i)=>i!==e)}function duplicateClip(t,e){const i=t[e];return i?[...t.slice(0,e+1),{...i},...t.slice(e+1)]:t}function reorderClips(t,e,i){if(e===i||!t[e]||i<0||i>=t.length)return t;const o=[...t],[n]=o.splice(e,1);return o.splice(i,0,n),o}function trimClipEdge(t,e,i,o,n){if(!t[e])return t;const r=t.map(t=>({...t}));return"in"===i?r[e].in=Math.min(Math.max(o,0),r[e].out-MIN_CLIP):r[e].out=Math.max(Math.min(o,n),r[e].in+MIN_CLIP),r}function clampAudioClip(t,e,i){const o=Math.max(Math.min(t.out,e),MIN_CLIP),n=Math.min(Math.max(t.in,0),o-MIN_CLIP),r=Math.min(Math.max(t.startAt,0),Math.max(0,i-MIN_CLIP));return{...t,in:n,out:o,startAt:r}}function contentDuration(t,e=[]){const i=totalDuration(t),o=e.reduce((t,e)=>Math.max(t,e.startAt+(e.out-e.in)/Math.max(.01,e.speed??1)),0);return Math.max(i,o)}function usedVideoSrcIndices(t){return[...new Set(t.map(t=>t.srcIdx))].sort((t,e)=>t-e)}function remapSrcIndices(t,e){const i=new Map(e.map((t,e)=>[t,e]));return t.map(t=>({...t,srcIdx:i.get(t.srcIdx)??0}))}function evenize(t){const e=Math.min(Math.max(Math.round(t),2),4096);return e%2==0?e:e-1}var clampRotation=t=>Math.min(Math.max(t,-180),180),VideoEditorEngine=class{constructor(t=defaultVideoEditState()){this.videoSources=[],this.audioSources=[],this.listeners=new Set,this.transientBase=null,this.getSnapshot=()=>this.history.present,this.subscribe=t=>(this.listeners.add(t),()=>this.listeners.delete(t)),this.history=createHistory(t)}getState(){return this.history.present}emit(){const t=this.history.present;for(const e of this.listeners)e(t)}canUndo(){return canUndo(this.history)}canRedo(){return canRedo(this.history)}undo(){this.transientBase=null,this.history=undo(this.history),this.emit()}redo(){this.transientBase=null,this.history=redo(this.history),this.emit()}applyMut(t,e=!1){if(e)null===this.transientBase&&(this.transientBase=this.history.present),this.history=replacePresent(this.history,t(this.transientBase));else{const e=t(this.transientBase??this.history.present),i=this.transientBase?{...this.history,present:this.transientBase}:this.history;this.history=pushHistory(i,e),this.transientBase=null}this.emit()}registerVideoSource(t){const e=this.videoSources.length;this.videoSources.push(t);const i={srcIdx:e,in:0,out:t.duration};return 0===e||0===this.history.present.clips.length?(this.transientBase=null,this.history=createHistory({...defaultVideoEditState(),clips:[i],canvas:{w:evenize(t.width),h:evenize(t.height)}}),this.emit()):this.applyMut(t=>({...t,clips:[...t.clips,i]})),e}registerAudioSource(t){const e=this.audioSources.length;return this.audioSources.push(t),this.applyMut(i=>{const o=i.audioClips.reduce((t,e)=>{const i=Math.max(0,(e.out-e.in)/Math.max(.01,e.speed??1));return Math.max(t,e.startAt+i)},0),n=clampAudioClip({srcIdx:e,track:0,startAt:o,in:0,out:t.duration,speed:1,volume:1,fadeIn:0,fadeOut:0},t.duration,Math.max(totalDuration(i.clips),o+MIN_CLIP));return{...i,audioClips:[...i.audioClips.map(t=>({...t,track:0})),n]}}),e}getVideoSource(t){return this.videoSources[t]}getAudioSource(t){return this.audioSources[t]}addClipFromSource(t){const e=this.videoSources[t];e&&this.applyMut(i=>({...i,clips:[...i.clips,{srcIdx:t,in:0,out:e.duration}]}))}splitAtPlayhead(t){this.applyMut(e=>({...e,clips:splitAtOutput(e.clips,t)}))}removeClip(t){this.applyMut(e=>({...e,clips:removeClip(e.clips,t)}))}duplicateClip(t){this.applyMut(e=>({...e,clips:duplicateClip(e.clips,t)}))}reorderClips(t,e){this.applyMut(i=>({...i,clips:reorderClips(i.clips,t,e)}))}trimClip(t,e,i,o){this.applyMut(o=>{const n=o.clips[t];if(!n)return o;const r=this.videoSources[n.srcIdx]?.duration??n.out;return{...o,clips:trimClipEdge(o.clips,t,e,i,r)}},o?.transient)}moveAudioClip(t,e,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,startAt:e})),i?.transient)}trimAudioClip(t,e,i,o){this.applyMut(o=>this.patchAudio(o,t,t=>{if("in"===e){const e=i-t.in;return{...t,in:i,startAt:t.startAt+e}}return{...t,out:i}}),o?.transient)}setAudioVolume(t,e,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,volume:e}),!1),i?.transient)}removeAudioClip(t){this.applyMut(e=>({...e,audioClips:e.audioClips.filter((e,i)=>i!==t)}))}patchAudio(t,e,i,o=!0){const n=t.audioClips[e];if(!n)return t;let r=i(n);if(o){const e=this.audioSources[n.srcIdx]?.duration??n.out;r=clampAudioClip(r,e,totalDuration(t.clips))}return{...t,audioClips:t.audioClips.map((t,i)=>i===e?r:t)}}setCrop(t,e){this.applyMut(e=>({...e,crop:t}),e?.transient)}clearCrop(){this.applyMut(t=>({...t,crop:void 0}))}setScale(t){this.applyMut(e=>({...e,scale:t}))}clearScale(){this.applyMut(t=>({...t,scale:void 0}))}setRotation(t,e){this.applyMut(e=>({...e,rotation:clampRotation(t)}),e?.transient)}rotateBy(t){this.applyMut(e=>{let i=e.rotation+t;return i>180&&(i-=360),i<-180&&(i+=360),{...e,rotation:clampRotation(i)}})}flipX(){this.applyMut(t=>({...t,flipX:!t.flipX}))}flipY(){this.applyMut(t=>({...t,flipY:!t.flipY}))}setFilter(t,e,i){this.applyMut(i=>({...i,filters:{...i.filters,[t]:e}}),i?.transient)}setFilters(t,e){this.applyMut(e=>({...e,filters:{...e.filters,...t}}),e?.transient)}setFilterPreset(t){this.applyMut(e=>({...e,filterPreset:t}))}addOverlay(t){this.applyMut(e=>({...e,overlays:[...e.overlays??[],t]}))}updateOverlay(t,e,i){this.applyMut(i=>{const o=i.overlays??[];return o[t]?{...i,overlays:o.map((i,o)=>o===t?{...i,...e}:i)}:i},i?.transient)}removeOverlay(t){this.applyMut(e=>({...e,overlays:(e.overlays??[]).filter((e,i)=>i!==t)}))}patch(t,e){e?.transient?(null===this.transientBase&&(this.transientBase=this.history.present),this.history=replacePresent(this.history,{...this.transientBase,...t}),this.emit()):this.commit(t)}commit(t){const e=t?{...this.history.present,...t}:this.history.present,i=this.transientBase;this.transientBase=null,this.history=pushHistory(i?{...this.history,present:i}:this.history,e),this.emit()}setKeepAudio(t){this.applyMut(e=>({...e,keepAudio:t}))}setPoster(t){this.applyMut(e=>({...e,poster:{time:Math.max(0,t)}}))}totalDuration(){return totalDuration(this.history.present.clips)}contentDuration(){const t=this.history.present;return contentDuration(t.clips,t.audioClips)}locate(t){return locateOutput(this.history.present.clips,t)}usedVideoSources(){return usedVideoSrcIndices(this.history.present.clips)}getExportPlan(){const t=this.history.present,e=usedVideoSrcIndices(t.clips),i=t.audioClips.filter(t=>!t.muted),o=[...new Set(i.map(t=>t.srcIdx))].sort((t,e)=>t-e),n=new Map(o.map((t,e)=>[t,e]));return{state:{...t,clips:remapSrcIndices(t.clips,e),audioClips:i.map(t=>({...t,srcIdx:n.get(t.srcIdx)??0}))},videoSrcOrder:e,audioSrcOrder:o}}validate(){return VideoEditState.safeParse(this.getExportPlan().state)}reset(t=defaultVideoEditState()){this.transientBase=null,this.history=createHistory(t),this.emit()}};exports.VideoEditorEngine=VideoEditorEngine;
|