MiniCut Studio

Editor de vídeo ligero inspirado en las funciones básicas de CapCut.

Selecciona un vídeo para comenzar.

Edición

Texto sobre el vídeo

Exporta en WebM dentro del navegador. La compatibilidad depende del dispositivo.

✂️ Línea de tiempo y clips

Añade fragmentos del vídeo cargado arriba, córtalos, cópialos, pégalos, elimínalos y cambia su orden.

Carga un vídeo en el editor superior y añade el primer clip.

Este complemento trabaja con fragmentos del mismo vídeo cargado en el editor superior. La exportación mantiene los filtros, la rotación y el texto del editor base. El resultado se genera como WebM y puede no incluir audio en algunos navegadores móviles.

🖼️ Superposición de imagen y vídeo

Añade una imagen o un segundo vídeo sobre la previsualización del editor. Puedes moverlo, redimensionarlo, cambiar su transparencia y definir cuándo aparece.

Imagen superpuesta

Vídeo superpuesto

Las capas aparecerán directamente sobre el escenario del editor superior.
Añade una imagen o un segundo vídeo.

Este bloque necesita estar pegado debajo de MiniCut Studio. La exportación visual del editor base no incluirá automáticamente estas capas; para incluirlas en el archivo final habrá que usar el futuro bloque de exportación multipista.

🎵 Música y narración por voz

Añade una pista musical y graba una narración. Ambas se sincronizan con el vídeo principal.

🎵 Música

🎤 Narración

Añade música o graba una narración.

Este bloque sincroniza la música y la voz durante la previsualización. Para integrarlas de forma definitiva en el vídeo exportado se utilizará el próximo bloque de exportación multipista.

✍️ Texto, subtítulos y texto a voz

Escribe o importa un guion, organízalo por capítulos, conviértelo en voz y utilízalo como subtítulos sobre el vídeo.

Palabras 0
Caracteres 0
Lectura estimada 0 min

📖 Capítulos

🎙 Texto a voz

💬 Subtítulos automáticos desde el texto

Los subtítulos aparecerán aquí.
Editor preparado.

La voz se reproduce con las voces instaladas en el navegador. Esta función no crea directamente un archivo MP3 o WAV. El texto y los capítulos se guardan en este navegador.

🎞️ Transiciones y animaciones

Añade transiciones en momentos concretos del vídeo y previsualízalas sobre el editor principal.

Vista previa

🎬
Añade la primera transición.

Las transiciones se aplican durante la previsualización del vídeo principal. Para integrarlas definitivamente en el archivo exportado se necesitará el futuro bloque de exportación multipista.

🎬

MiniCut AI Studio

Una plataforma modular para edición de vídeo, audiolibros, podcasts, narraciones y creación de contenido con inteligencia artificial.

Módulos terminados 5
Módulos previstos 11+
Áreas de trabajo 5
Arquitectura Modular

🎬 Fase 1 — Editor de vídeo

En desarrollo
✅ Editor base
✅ Línea de tiempo
✅ Superposición de imágenes y vídeos
✅ Música y narración
✅ Texto, capítulos y subtítulos
🔜 Transiciones entre clips
🔜 Efectos y animaciones
🔜 Chroma key
🔜 Cámara lenta y curvas de velocidad
🔜 Exportación multipista

📖 Fase 2 — Audiolibros

Planificado
Editor de capítulos
Corrector ortográfico
Texto a voz
Voces diferentes para personajes
Música de fondo automática
Portadas para audiolibros
Exportación a audio y vídeo

🤖 Fase 3 — Inteligencia artificial

Futuro
Generación automática de subtítulos
Detección y eliminación de silencios
Reducción de ruido
Traducción de texto y subtítulos
Doblaje de vídeos
Voces personalizadas con autorización
Creación automática de miniaturas

📱 Fase 4 — Redes sociales

Futuro
Formatos para TikTok
Formatos para YouTube
Formatos para Instagram
Shorts y Reels
Portadas y miniaturas
Preparación para publicación directa

🎙️ Fase 5 — Creador de contenido

Visión
Podcasts
Audiolibros
Cursos
Presentaciones narradas
Historias infantiles
Documentales

🧩 Arquitectura modular

⚙️ Núcleo
🎞️ Timeline
🎥 Vídeo
🎵 Audio
💬 Subtítulos
✍️ Texto
🤖 IA
📤 Exportación
📱 Redes sociales
📖 Audiolibros
🔌 Plugins

🚀 Objetivo del proyecto

MiniCut AI Studio no pretende ser únicamente una copia de CapCut. El objetivo es construir una herramienta propia que combine edición de vídeo, creación de audiolibros, narración, podcasts, subtítulos y herramientas de IA dentro de una misma plataforma web modular.

🎬

MiniCut AI Studio

Panel modular e interactivo para organizar el editor de vídeo, audiolibros, podcasts, narraciones y futuras herramientas de IA.

Funciones totales 0
Terminadas 0
Próximas 0
Progreso 0%
🎬

Fase 1 — Editor de vídeo

En desarrollo
Editor base
Línea de tiempo
Superposición de imágenes y vídeos
Música y narración
Texto, capítulos y subtítulos
🔜 Transiciones entre clips
🔜 Efectos y animaciones
🔜 Chroma key
🔜 Cámara lenta y curvas de velocidad
🔜 Exportación multipista

🧩 Arquitectura modular

⚙️ Núcleo
🎞️ Timeline
🎥 Vídeo
🎵 Audio
💬 Subtítulos
✍️ Texto
🤖 IA
📤 Exportación
📱 Redes sociales
📖 Audiolibros
🔌 Plugins

🚀 Objetivo del proyecto

Crear una herramienta propia que combine edición de vídeo, audiolibros, podcasts, subtítulos y creación de contenido, manteniendo cada función separada en módulos para evitar que una ampliación rompa las anteriores.

Panel preparado. Todos los botones de esta sección son interactivos.

MiniCut AI Studio

Editor unificado de vídeo, audio, capas, subtítulos, texto a voz y exportación WebM.
Carga un vídeo para comenzar.

🎥 Ajustes de vídeo

✂️ Línea de tiempo

🖼️ Capas

🎵 Música y voz

✍️ Texto, voz y subtítulos

📤 Exportación

Exporta clips, texto y capas visuales en WebM. La música y la voz se mezclan cuando el navegador permite capturar audio.

Los vídeos largos o con muchas capas pueden tardar.
';return}clips.forEach((c,i)=>{const d=document.createElement("div");d.className="clip"+(i===selectedClip?" selected":"");d.innerHTML=`${i+1}. ${escapeHTML(c.name)}${fmt(c.start)} → ${fmt(c.end)}`;d.onclick=()=>{selectedClip=i;video.currentTime=c.start;renderTimeline()};box.appendChild(d)})} $("mcuAddImage").onclick=()=>{ const f=$("mcuImageFile").files[0];if(!f)return status.textContent="Selecciona una imagen."; if(imageURL)URL.revokeObjectURL(imageURL);imageURL=URL.createObjectURL(f);if(imageLayer)imageLayer.remove(); imageLayer=document.createElement("img");imageLayer.src=imageURL;imageLayer.className="overlayLayer";imageLayer.dataset.kind="image";stage.appendChild(imageLayer);enableDrag(imageLayer);syncLayers(); }; $("mcuRemoveImage").onclick=()=>{if(imageLayer)imageLayer.remove();imageLayer=null;if(imageURL)URL.revokeObjectURL(imageURL);imageURL=""}; $("mcuAddOverlayVideo").onclick=()=>{ const f=$("mcuOverlayVideoFile").files[0];if(!f)return status.textContent="Selecciona un segundo vídeo."; if(overlayVideoURL)URL.revokeObjectURL(overlayVideoURL);overlayVideoURL=URL.createObjectURL(f);if(overlayVideo)overlayVideo.remove(); overlayVideo=document.createElement("video");overlayVideo.src=overlayVideoURL;overlayVideo.muted=true;overlayVideo.playsInline=true;overlayVideo.className="overlayLayer";overlayVideo.dataset.kind="video";stage.appendChild(overlayVideo);enableDrag(overlayVideo);overlayVideo.onloadedmetadata=()=>{syncLayers();syncOverlayVideo()}; }; $("mcuRemoveOverlayVideo").onclick=()=>{if(overlayVideo){overlayVideo.pause();overlayVideo.remove()}overlayVideo=null;if(overlayVideoURL)URL.revokeObjectURL(overlayVideoURL);overlayVideoURL=""}; function syncLayers(){ if(imageLayer)applyLayer(imageLayer,"mcuImage"); if(overlayVideo)applyLayer(overlayVideo,"mcuOverlayVideo"); updateLayersVisibility(); } function applyLayer(el,prefix){ el.style.width=$(prefix+"Scale").value+"%";el.style.opacity=$(prefix+"Opacity").value;el.style.left=$(prefix+"X").value+"%";el.style.top=$(prefix+"Y").value+"%"; } function updateLayersVisibility(){ const t=video.currentTime||0; if(imageLayer)imageLayer.style.display=(t>=+$("mcuImageStart").value&&t<=+$("mcuImageEnd").value)?"block":"none"; if(overlayVideo){const vis=t>=+$("mcuOverlayVideoStart").value&&t<=+$("mcuOverlayVideoEnd").value;overlayVideo.style.display=vis?"block":"none";if(vis)syncOverlayVideo();else overlayVideo.pause()} } function syncOverlayVideo(){if(!overlayVideo||!overlayVideo.duration)return;const start=+$("mcuOverlayVideoStart").value,t=video.currentTime;if(t.25)overlayVideo.currentTime=local;overlayVideo.playbackRate=video.playbackRate||1;if(!video.paused)overlayVideo.play().catch(()=>{});else overlayVideo.pause()} function enableDrag(el){ el.addEventListener("pointerdown",e=>{dragging=el;const r=el.getBoundingClientRect();dragOffsetX=e.clientX-r.left-r.width/2;dragOffsetY=e.clientY-r.top-r.height/2;el.setPointerCapture(e.pointerId)}); el.addEventListener("pointermove",e=>{if(dragging!==el)return;const r=stage.getBoundingClientRect();let x=(e.clientX-r.left-dragOffsetX)/r.width*100,y=(e.clientY-r.top-dragOffsetY)/r.height*100;x=Math.max(0,Math.min(100,x));y=Math.max(0,Math.min(100,y));el.style.left=x+"%";el.style.top=y+"%";const p=el.dataset.kind==="image"?"mcuImage":"mcuOverlayVideo";$(p+"X").value=x;$(p+"Y").value=y}); el.addEventListener("pointerup",e=>{dragging=null;try{el.releasePointerCapture(e.pointerId)}catch(_){}}); } $("mcuAddMusic").onclick=()=>{const f=$("mcuMusicFile").files[0];if(!f)return;if(musicURL)URL.revokeObjectURL(musicURL);musicURL=URL.createObjectURL(f);music=new Audio(musicURL);music.preload="auto";status.textContent="Música añadida."}; $("mcuRemoveMusic").onclick=()=>{if(music)music.pause();music=null;if(musicURL)URL.revokeObjectURL(musicURL);musicURL=""}; $("mcuStartVoice").onclick=startVoice; $("mcuStopVoice").onclick=stopVoice; async function startVoice(){ if(!navigator.mediaDevices||!window.MediaRecorder)return status.textContent="Grabación no disponible."; try{ recorderStream=await navigator.mediaDevices.getUserMedia({audio:true});recorderChunks=[]; mediaRecorder=new MediaRecorder(recorderStream);mediaRecorder.ondataavailable=e=>{if(e.data.size)recorderChunks.push(e.data)}; mediaRecorder.onstop=()=>{voiceBlob=new Blob(recorderChunks,{type:mediaRecorder.mimeType||"audio/webm"});if(voiceURL)URL.revokeObjectURL(voiceURL);voiceURL=URL.createObjectURL(voiceBlob);voice=new Audio(voiceURL);$("mcuVoicePreview").src=voiceURL;$("mcuVoicePreview").style.display="block"}; mediaRecorder.start(250);$("mcuStartVoice").disabled=true;$("mcuStopVoice").disabled=false;startMeter(recorderStream);status.textContent="Grabando voz…"; }catch(e){status.textContent="No se pudo activar el micrófono."} } function stopVoice(){if(mediaRecorder&&mediaRecorder.state!=="inactive")mediaRecorder.stop();if(recorderStream)recorderStream.getTracks().forEach(t=>t.stop());recorderStream=null;$("mcuStartVoice").disabled=false;$("mcuStopVoice").disabled=true;stopMeter()} function startMeter(stream){const AC=window.AudioContext||window.webkitAudioContext;if(!AC)return;audioContext=new AC();analyser=audioContext.createAnalyser();analyser.fftSize=1024;audioContext.createMediaStreamSource(stream).connect(analyser);const data=new Uint8Array(analyser.fftSize);const draw=()=>{if(!analyser)return;analyser.getByteTimeDomainData(data);let s=0;for(let i=0;i=s&&t<=e){const local=music.duration?(t-s)%music.duration:0;if(Math.abs(music.currentTime-local)>.25)music.currentTime=local;if(!video.paused)music.play().catch(()=>{})}else music.pause()} if(voice&&voice.duration){const s=+$("mcuVoiceStart").value,e=s+voice.duration;voice.volume=+$("mcuVoiceVolume").value;if(t>=s&&t<=e){const local=Math.min(t-s,voice.duration-.03);if(Math.abs(voice.currentTime-local)>.25)voice.currentTime=local;if(!video.paused)voice.play().catch(()=>{})}else voice.pause()} } function pauseExternalAudio(){if(music)music.pause();if(voice)voice.pause();if(overlayVideo)overlayVideo.pause()} function loadVoices(){if(!speechSynthesis)return;const vs=speechSynthesis.getVoices();$("mcuVoiceSelect").innerHTML="";vs.forEach((v,i)=>{const o=document.createElement("option");o.value=i;o.textContent=v.name+" — "+v.lang;$("mcuVoiceSelect").appendChild(o)})} loadVoices();if("speechSynthesis" in window)speechSynthesis.onvoiceschanged=loadVoices; $("mcuSpeak").onclick=()=>{if(!("speechSynthesis" in window))return;const text=$("mcuText").value.trim();if(!text)return;const u=new SpeechSynthesisUtterance(text),vs=speechSynthesis.getVoices(),i=+$("mcuVoiceSelect").value;if(vs[i])u.voice=vs[i];u.rate=+$("mcuSpeechRate").value;u.pitch=+$("mcuSpeechPitch").value;speechSynthesis.cancel();speechSynthesis.speak(u)}; $("mcuPauseSpeech").onclick=()=>speechSynthesis.pause(); $("mcuResumeSpeech").onclick=()=>speechSynthesis.resume(); $("mcuStopSpeech").onclick=()=>speechSynthesis.cancel(); $("mcuGenerateSubtitles").onclick=()=>{ const parts=($("mcuText").value.match(/[^.!?]+[.!?]+|[^.!?]+$/g)||[]).map(s=>s.trim()).filter(Boolean),start=+$("mcuSubtitleStart").value||0,d=+$("mcuSubtitleDuration").value||4; subtitles=parts.map((text,i)=>({text,start:start+i*d,end:start+(i+1)*d}));status.textContent=subtitles.length+" subtítulos generados."; }; function updateSubtitle(){const t=video.currentTime||0,current=subtitles.find(s=>t>=s.start&&tmixed.addTrack(t))}catch(_){} const mime=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm"].find(m=>MediaRecorder.isTypeSupported(m))||""; const rec=new MediaRecorder(mixed,mime?{mimeType:mime}:undefined),chunks=[];rec.ondataavailable=e=>{if(e.data.size)chunks.push(e.data)}; rec.onstop=()=>{const b=new Blob(chunks,{type:mime||"video/webm"}),a=document.createElement("a");a.href=URL.createObjectURL(b);a.download="minicut-ai-studio.webm";a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);exporting=false;status.textContent="Exportación terminada."}; const exportClips=clips.length?clips:[{start:+$("mcuTrimStart").value||0,end:+$("mcuTrimEnd").value||video.duration}]; rec.start(250); for(const c of exportClips){video.pause();video.currentTime=c.start;await new Promise(r=>setTimeout(r,180));await video.play();await new Promise(resolve=>{const draw=()=>{drawFrame(dims.w,dims.h);progress.style.width=Math.min(100,(video.currentTime-c.start)/(c.end-c.start)*100)+"%";if(video.currentTime>=c.end||video.ended){video.pause();return resolve()}requestAnimationFrame(draw)};draw()})} rec.stop(); } function exportDims(){const a=$("mcuAspect").value;if(a==="9:16")return{w:720,h:1280};if(a==="1:1")return{w:900,h:900};if(a==="16:9")return{w:1280,h:720};const s=Math.min(1,1280/Math.max(video.videoWidth,video.videoHeight));return{w:Math.round(video.videoWidth*s/2)*2,h:Math.round(video.videoHeight*s/2)*2}} function drawFrame(w,h){ ctx.save();ctx.fillStyle="#000";ctx.fillRect(0,0,w,h);ctx.filter=`brightness(${$("mcuBrightness").value}%) contrast(${$("mcuContrast").value}%) saturate(${$("mcuSaturation").value}%)`; const deg=+$("mcuRotation").value,rot=deg*Math.PI/180;ctx.translate(w/2,h/2);ctx.rotate(rot);const turned=deg%180!==0,bw=turned?h:w,bh=turned?w:h,s=Math.min(bw/video.videoWidth,bh/video.videoHeight),dw=video.videoWidth*s,dh=video.videoHeight*s;ctx.drawImage(video,-dw/2,-dh/2,dw,dh);ctx.restore(); drawLayerToCanvas(imageLayer,w,h,+$("mcuImageStart").value,+$("mcuImageEnd").value,"mcuImage"); drawLayerToCanvas(overlayVideo,w,h,+$("mcuOverlayVideoStart").value,+$("mcuOverlayVideoEnd").value,"mcuOverlayVideo"); const text=overlayText.textContent.trim();if(text){const size=+$("mcuTextSize").value,y=h*(parseFloat(overlayText.style.top)||15)/100;ctx.save();ctx.font=`800 ${size}px Arial`;ctx.textAlign="center";ctx.textBaseline="middle";ctx.lineWidth=Math.max(2,size*.08);ctx.strokeStyle="rgba(0,0,0,.8)";ctx.strokeText(text,w/2,y,w*.9);ctx.fillStyle=$("mcuTextColor").value;ctx.fillText(text,w/2,y,w*.9);ctx.restore()} } function drawLayerToCanvas(el,w,h,start,end,prefix){const t=video.currentTime;if(!el||tend)return;const scale=+$(prefix+"Scale").value/100,opacity=+$(prefix+"Opacity").value,x=w*+$(prefix+"X").value/100,y=h*+$(prefix+"Y").value/100;const naturalW=el.videoWidth||el.naturalWidth||300,naturalH=el.videoHeight||el.naturalHeight||200,dw=w*scale,dh=dw*(naturalH/naturalW);ctx.save();ctx.globalAlpha=opacity;try{ctx.drawImage(el,x-dw/2,y-dh/2,dw,dh)}catch(_){}ctx.restore()} $("mcuResetAll").onclick=()=>{if(!confirm("¿Reiniciar todo el proyecto?"))return;location.reload()}; function fmt(s){const m=Math.floor(s/60),r=(s%60).toFixed(1);return m+":"+(+r<10?"0":"")+r} function escapeHTML(s){return String(s).replace(/[&<>"']/g,c=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]))} renderTimeline();applyPreview(); })();