@bylqwjc/media-editor-server 1.0.24 → 1.0.26
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 +9 -3
- package/core/dist/browser.js +1 -1
- package/core/dist/{chunk-T5QIAKTR.js → chunk-7PSQLYXL.js} +1 -1
- package/core/dist/chunk-FAFKY4LX.js +1 -0
- package/core/dist/engine.cjs +1 -1
- package/core/dist/engine.d.ts +648 -549
- package/core/dist/engine.js +1 -1
- package/core/dist/filerobot.cjs +1 -1
- package/core/dist/filerobot.js +1 -1
- package/core/dist/index.cjs +1 -1
- package/core/dist/index.d.ts +2 -2
- package/core/dist/index.js +1 -1
- package/core/dist/{state-D7Of7b_y.d.ts → state-D2oM5s1a.d.ts} +10 -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-BEalyBz9.d.ts → handler-BiOIAlrh.d.ts} +8 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/core/dist/chunk-KO6CX4IJ.js +0 -1
package/core/dist/browser.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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&&("undefined"!=typeof File&&n instanceof File?r.append(`video_${o}`,n,n.name||`video_${o}.mp4`):"url"in n&&"string"==typeof n.url&&n.url&&(r.append(`videoUrl_${o}`,n.url),n.name&&r.append(`videoName_${o}`,n.name),n.type&&r.append(`videoType_${o}`,n.type),null!=n.size&&r.append(`videoSize_${o}`,String(n.size))))}),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);(await Promise.all(a.map(e=>renderOverlaysToPng([e],i.w,i.h)))).forEach((e,t)=>{e&&r.append(`textOverlay_${t}`,e,`textOverlay_${t}.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),bitrateMode:zod.z.enum(["auto","custom"]).optional(),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),u=r.crop??{x:0,y:0,width:m.w,height:m.h},c=r.scale?.fit??"force",{src:h,dst:z}=fitRects({width:u.width,height:u.height},l,c);"contain"===c&&(d.fillStyle=normalizeScaleBackgroundColor(r.scale?.backgroundColor),d.fillRect(0,0,e.width,e.height)),d.filter=buildFilterCss(r.filters,r.filterPreset),d.save(),"contain"===c&&(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(-(u.x+h.x),-(u.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-D2oM5s1a.js';
|
|
2
2
|
import { VideoEditorEngine } from './engine.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
@@ -58,11 +58,17 @@ declare function translateOverlay(o: OverlayT, dx: number, dy: number): OverlayT
|
|
|
58
58
|
* 触碰 DOM(overlay → canvas PNG),故归 @media-editor/core/browser,React/Vue 共用。
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
|
+
type VideoExportSource = File | {
|
|
62
|
+
url: string;
|
|
63
|
+
name?: string;
|
|
64
|
+
type?: string;
|
|
65
|
+
size?: number;
|
|
66
|
+
};
|
|
61
67
|
/**
|
|
62
68
|
* @param videoFiles 以「原始 srcIdx」为下标的视频 File 数组(引擎按 videoSrcOrder 取并重排)
|
|
63
69
|
* @param audioFiles 同上(音频)
|
|
64
70
|
*/
|
|
65
|
-
declare function buildVideoExportFormData(engine: VideoEditorEngine, videoFiles: ReadonlyArray<
|
|
71
|
+
declare function buildVideoExportFormData(engine: VideoEditorEngine, videoFiles: ReadonlyArray<VideoExportSource | undefined>, audioFiles?: ReadonlyArray<File | undefined>): Promise<FormData>;
|
|
66
72
|
|
|
67
73
|
/**
|
|
68
74
|
* 帧合成器(框架无关 canvas)—— 把「源帧 → 输出画布 + 完整效果链 + overlays」绘到 canvas。
|
|
@@ -108,4 +114,4 @@ interface FullscreenToggleOptions {
|
|
|
108
114
|
}
|
|
109
115
|
declare function createFullscreenToggle(host: HTMLElement, options?: FullscreenToggleOptions): FullscreenToggle;
|
|
110
116
|
|
|
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 };
|
|
117
|
+
export { type FrameSource, type FullscreenToggle, type FullscreenToggleOptions, type VideoExportSource, 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{overlayLayerRenderOrder as e,isOverlayHidden as t,isDrawableOverlay as r,outputSize as n,renderOverlaysToPng as a,isOverlayActiveAt as
|
|
1
|
+
import{overlayLayerRenderOrder as e,isOverlayHidden as t,isDrawableOverlay as r,outputSize as n,renderOverlaysToPng as a,isOverlayActiveAt as i,drawOverlay as o,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-7PSQLYXL.js";async function m(i,o,s=[]){const l=i.getExportPlan(),c=new FormData;l.videoSrcOrder.forEach((e,t)=>{const r=o[e];r&&("undefined"!=typeof File&&r instanceof File?c.append(`video_${t}`,r,r.name||`video_${t}.mp4`):"url"in r&&"string"==typeof r.url&&r.url&&(c.append(`videoUrl_${t}`,r.url),r.name&&c.append(`videoName_${t}`,r.name),r.type&&c.append(`videoType_${t}`,r.type),null!=r.size&&c.append(`videoSize_${t}`,String(r.size))))}),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);(await Promise.all(h.map(e=>a([e],m.w,m.h)))).forEach((e,t)=>{e&&c.append(`textOverlay_${t}`,e,`textOverlay_${t}.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 i=Math.max(0,Math.round(r.x*n)),o=Math.max(0,Math.round(r.y*n)),s=Math.min(t.width-i,Math.max(1,Math.round(r.w*n))),l=Math.min(t.height-o,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,i,o,s,l,0,0,s,l),e.save(),e.filter=c({...h,...r},r.filterPreset),e.drawImage(d,i,o,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||i(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)):o(r,d,s));r.setTransform(1,0,0,1,0,0)}}function p(e,t,r,a,i,o=1,h,m=!0){const f=n(a,i);e.width=Math.max(2,Math.round(f.w*o)),e.height=Math.max(2,Math.round(f.h*o));const p=e.getContext("2d");if(!p)return;if(Boolean(i.__mePreviewVideoHidden)){p.fillStyle="#000000",p.fillRect(0,0,e.width,e.height);const t=Number.isFinite(i.__mePreviewTimelineTime)?Number(i.__mePreviewTimelineTime):void 0;return void(m&&i.overlays?.length&&v(p,e,i.overlays,h,t,o))}const g=s(a.w,a.h,i.rotation),y=i.crop??{x:0,y:0,width:g.w,height:g.h},w=i.scale?.fit??"force",{src:x,dst:b}=l({width:y.width,height:y.height},f,w);"contain"===w&&(p.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}(i.scale?.backgroundColor),p.fillRect(0,0,e.width,e.height)),p.filter=c(i.filters,i.filterPreset),p.save(),"contain"===w&&(p.beginPath(),p.rect(o*b.x,o*b.y,o*b.width,o*b.height),p.clip()),p.translate(o*b.x,o*b.y),p.scale(o*b.width/x.width,o*b.height/x.height),p.translate(-(y.x+x.x),-(y.y+x.y)),p.translate(g.w/2,g.h/2),p.rotate(i.rotation*d),p.scale(i.flipX?-1:1,i.flipY?-1:1);const T=l({width:r.w,height:r.h},{w:a.w,h:a.h},"cover");p.drawImage(t,T.src.x,T.src.y,T.src.width,T.src.height,-a.w/2,-a.h/2,a.w,a.h),p.restore(),p.filter="none";const O=Number.isFinite(i.__mePreviewTimelineTime)?Number(i.__mePreviewTimelineTime):void 0;m&&i.overlays?.length&&v(p,e,i.overlays,h,O,o)}function g(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,i=e.videoHeight||9,o=Math.min(r,a),s=Math.max(1,Math.round(o*i/a)),l=document.createElement("canvas");l.width=o,l.height=s;const c=l.getContext("2d");if(!c)return[];const d=[];for(let r=0;r<t;r++)await g(e,n*(r+.5)/t),c.drawImage(e,0,0,o,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 i=()=>a(),o=()=>{const t=document.fullscreenElement===e?document.exitFullscreen?.():e.requestFullscreen?.();t?.catch?.(()=>{})};return n.addEventListener("click",o),document.addEventListener("fullscreenchange",i),{button:n,dispose:()=>{document.removeEventListener("fullscreenchange",i),n.removeEventListener("click",o),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,p as drawVideoFrame,y as generateThumbnails};
|
|
@@ -1 +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};
|
|
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),bitrateMode:e.enum(["auto","custom"]).optional(),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 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.exportPrepare":"正在准备素材…","msg.exportUpload":"正在上传素材…","msg.exportEncode":"正在编码视频…","msg.exportDownload":"正在接收结果…","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.exportPrepare":"Preparing media…","msg.exportUpload":"Uploading media…","msg.exportEncode":"Encoding video…","msg.exportDownload":"Receiving result…","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.exportPrepare":"Preparando medios…","msg.exportUpload":"Subiendo medios…","msg.exportEncode":"Codificando video…","msg.exportDownload":"Recibiendo resultado…","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 m=d();function u(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 v=u();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,v as IMAGE_PLATFORM_PRESETS,s as IMAGE_RATIO_PRESETS,m as VIDEO_PLATFORM_RATIO_PRESETS,c as VIDEO_RATIO_PRESETS,h as VIDEO_SIZE_PRESETS,u as buildImagePlatformPresets,d as buildVideoPlatformRatioPresets,f as buildVideoSizePresets,b as compensateAnnotationRotation,n as parseRatio,i as tEditor,t as toHant};
|
package/core/dist/engine.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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),bitrateMode:zod.z.enum(["auto","custom"]).optional(),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;
|