Update app-backup.py
Browse files- app-backup.py +81 -10
app-backup.py
CHANGED
|
@@ -208,7 +208,7 @@ Simple Video Editor
|
|
| 208 |
</div>
|
| 209 |
</div>
|
| 210 |
<script>
|
| 211 |
-
var S={{mediaLibrary:[],timelineClips:[],selectedClipId:null,isPlaying:false,isMuted:false,currentTime:0,totalDuration:0,zoom:1,pps:80,undoStack:[],animId:null}};
|
| 212 |
function gid(){{return Date.now().toString(36)+Math.random().toString(36).substr(2)}}
|
| 213 |
function fmt(s){{if(!s||isNaN(s))s=0;var m=Math.floor(s/60),sec=Math.floor(s%60),ms=Math.floor((s%1)*100);return(m<10?'0':'')+m+':'+(sec<10?'0':'')+sec+'.'+(ms<10?'0':'')+ms}}
|
| 214 |
function upStat(msg){{var e=document.getElementById('statusBar');if(e)e.textContent=msg+' | ๋ฏธ๋์ด: '+S.mediaLibrary.length+'๊ฐ | ํด๋ฆฝ: '+S.timelineClips.length+'๊ฐ'}}
|
|
@@ -342,12 +342,13 @@ upPH();upPrev();S.animId=requestAnimationFrame(anim);
|
|
| 342 |
}}
|
| 343 |
S.animId=requestAnimationFrame(anim);
|
| 344 |
}}
|
| 345 |
-
function stopPB(){{if(S.animId){{cancelAnimationFrame(S.animId);S.animId=null}}var v=document.querySelector('#previewContainer video');if(v&&!v.paused)v.pause()}}
|
| 346 |
function upPH(){{var p=document.getElementById('playhead');if(p)p.style.left=(70+S.currentTime*S.pps*S.zoom)+'px';document.getElementById('currentTimeDisplay').textContent=fmt(S.currentTime)}}
|
| 347 |
function upPrev(){{
|
| 348 |
var ct=document.getElementById('previewContainer');if(!ct)return;
|
| 349 |
var cur=S.timelineClips.filter(function(c){{var ce=c.start+(c.te-c.ts);return S.currentTime>=c.start&&S.currentTime<ce}});
|
| 350 |
var vc=cur.find(function(c){{return c.type==='video'||c.type==='image'}});
|
|
|
|
| 351 |
if(vc){{
|
| 352 |
var ct2=S.currentTime-vc.start+vc.ts;
|
| 353 |
if(vc.type==='image'){{if(!ct.querySelector('img[data-cid="'+vc.id+'"]'))ct.innerHTML='<img src="'+vc.url+'" data-cid="'+vc.id+'">'}}
|
|
@@ -360,9 +361,36 @@ else if(!S.isPlaying&&!v.paused)v.pause();
|
|
| 360 |
v.volume=S.isMuted?0:vc.vol;v.muted=S.isMuted;
|
| 361 |
}}
|
| 362 |
}}else{{
|
| 363 |
-
var ha=
|
| 364 |
if(!ct.querySelector('.preview-placeholder'))ct.innerHTML='<div class="preview-placeholder"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"><rect x="2" y="2" width="20" height="20" rx="2"/><polygon points="10 8 16 12 10 16 10 8"/></svg><p>'+(ha?'๐ต ์ค๋์ค ์ฌ์ ์ค':'ํ์๋ผ์ธ์ ๋ฏธ๋์ด๋ฅผ ์ถ๊ฐํ์ธ์')+'</p></div>';
|
| 365 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
}}
|
| 367 |
function editorSkipStart(){{S.currentTime=0;upPH();upPrev()}}
|
| 368 |
function editorSkipEnd(){{S.currentTime=S.totalDuration;upPH();upPrev()}}
|
|
@@ -373,6 +401,7 @@ S.isMuted=!S.isMuted;var ic=document.getElementById('volumeIcon');
|
|
| 373 |
if(S.isMuted)ic.innerHTML='<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/>';
|
| 374 |
else ic.innerHTML='<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/>';
|
| 375 |
var v=document.querySelector('#previewContainer video');if(v)v.muted=S.isMuted;
|
|
|
|
| 376 |
}}
|
| 377 |
function editorSetZoom(v){{S.zoom=parseFloat(v);renderTL();upPH()}}
|
| 378 |
function editorTimelineClick(e){{
|
|
@@ -389,14 +418,56 @@ function editorExport(){{
|
|
| 389 |
if(S.timelineClips.length===0){{alert('ํ์๋ผ์ธ์ ํด๋ฆฝ์ ์ถ๊ฐํด์ฃผ์ธ์.');return}}
|
| 390 |
document.getElementById('exportModal').style.display='flex';
|
| 391 |
document.getElementById('exportProgress').style.width='0%';
|
| 392 |
-
document.getElementById('exportStatus').textContent='
|
| 393 |
var p=0,iv=setInterval(function(){{
|
| 394 |
-
p+=
|
| 395 |
-
if(p===30)document.getElementById('exportStatus').textContent='ํด๋ฆฝ
|
| 396 |
-
if(p===60)document.getElementById('exportStatus').textContent='
|
| 397 |
-
if(p=
|
| 398 |
-
|
| 399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
}}
|
| 401 |
function editorCancelExport(){{document.getElementById('exportModal').style.display='none';document.getElementById('cancelExportBtn').textContent='์ทจ์'}}
|
| 402 |
document.addEventListener('keydown',function(e){{
|
|
|
|
| 208 |
</div>
|
| 209 |
</div>
|
| 210 |
<script>
|
| 211 |
+
var S={{mediaLibrary:[],timelineClips:[],selectedClipId:null,isPlaying:false,isMuted:false,currentTime:0,totalDuration:0,zoom:1,pps:80,undoStack:[],animId:null,audioElements:{{}}}};
|
| 212 |
function gid(){{return Date.now().toString(36)+Math.random().toString(36).substr(2)}}
|
| 213 |
function fmt(s){{if(!s||isNaN(s))s=0;var m=Math.floor(s/60),sec=Math.floor(s%60),ms=Math.floor((s%1)*100);return(m<10?'0':'')+m+':'+(sec<10?'0':'')+sec+'.'+(ms<10?'0':'')+ms}}
|
| 214 |
function upStat(msg){{var e=document.getElementById('statusBar');if(e)e.textContent=msg+' | ๋ฏธ๋์ด: '+S.mediaLibrary.length+'๊ฐ | ํด๋ฆฝ: '+S.timelineClips.length+'๊ฐ'}}
|
|
|
|
| 342 |
}}
|
| 343 |
S.animId=requestAnimationFrame(anim);
|
| 344 |
}}
|
| 345 |
+
function stopPB(){{if(S.animId){{cancelAnimationFrame(S.animId);S.animId=null}}var v=document.querySelector('#previewContainer video');if(v&&!v.paused)v.pause();if(S.audioElements)Object.keys(S.audioElements).forEach(function(id){{var au=S.audioElements[id];if(au&&!au.paused)au.pause()}})}}
|
| 346 |
function upPH(){{var p=document.getElementById('playhead');if(p)p.style.left=(70+S.currentTime*S.pps*S.zoom)+'px';document.getElementById('currentTimeDisplay').textContent=fmt(S.currentTime)}}
|
| 347 |
function upPrev(){{
|
| 348 |
var ct=document.getElementById('previewContainer');if(!ct)return;
|
| 349 |
var cur=S.timelineClips.filter(function(c){{var ce=c.start+(c.te-c.ts);return S.currentTime>=c.start&&S.currentTime<ce}});
|
| 350 |
var vc=cur.find(function(c){{return c.type==='video'||c.type==='image'}});
|
| 351 |
+
var ac=cur.filter(function(c){{return c.type==='audio'}});
|
| 352 |
if(vc){{
|
| 353 |
var ct2=S.currentTime-vc.start+vc.ts;
|
| 354 |
if(vc.type==='image'){{if(!ct.querySelector('img[data-cid="'+vc.id+'"]'))ct.innerHTML='<img src="'+vc.url+'" data-cid="'+vc.id+'">'}}
|
|
|
|
| 361 |
v.volume=S.isMuted?0:vc.vol;v.muted=S.isMuted;
|
| 362 |
}}
|
| 363 |
}}else{{
|
| 364 |
+
var ha=ac.length>0;
|
| 365 |
if(!ct.querySelector('.preview-placeholder'))ct.innerHTML='<div class="preview-placeholder"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"><rect x="2" y="2" width="20" height="20" rx="2"/><polygon points="10 8 16 12 10 16 10 8"/></svg><p>'+(ha?'๐ต ์ค๋์ค ์ฌ์ ์ค':'ํ์๋ผ์ธ์ ๋ฏธ๋์ด๋ฅผ ์ถ๊ฐํ์ธ์')+'</p></div>';
|
| 366 |
}}
|
| 367 |
+
handleAudio(ac);
|
| 368 |
+
}}
|
| 369 |
+
function handleAudio(audioClips){{
|
| 370 |
+
if(!S.audioElements)S.audioElements={{}};
|
| 371 |
+
var activeIds={{}};
|
| 372 |
+
audioClips.forEach(function(c){{
|
| 373 |
+
activeIds[c.id]=true;
|
| 374 |
+
var at=S.currentTime-c.start+c.ts;
|
| 375 |
+
var au=S.audioElements[c.id];
|
| 376 |
+
if(!au){{
|
| 377 |
+
au=document.createElement('audio');
|
| 378 |
+
au.src=c.url;
|
| 379 |
+
au.preload='auto';
|
| 380 |
+
S.audioElements[c.id]=au;
|
| 381 |
+
}}
|
| 382 |
+
if(Math.abs(au.currentTime-at)>0.3)au.currentTime=at;
|
| 383 |
+
au.volume=S.isMuted?0:c.vol;
|
| 384 |
+
au.muted=S.isMuted;
|
| 385 |
+
if(S.isPlaying&&au.paused)au.play().catch(function(){{}});
|
| 386 |
+
else if(!S.isPlaying&&!au.paused)au.pause();
|
| 387 |
+
}});
|
| 388 |
+
Object.keys(S.audioElements).forEach(function(id){{
|
| 389 |
+
if(!activeIds[id]){{
|
| 390 |
+
var au=S.audioElements[id];
|
| 391 |
+
if(au&&!au.paused)au.pause();
|
| 392 |
+
}}
|
| 393 |
+
}});
|
| 394 |
}}
|
| 395 |
function editorSkipStart(){{S.currentTime=0;upPH();upPrev()}}
|
| 396 |
function editorSkipEnd(){{S.currentTime=S.totalDuration;upPH();upPrev()}}
|
|
|
|
| 401 |
if(S.isMuted)ic.innerHTML='<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/>';
|
| 402 |
else ic.innerHTML='<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/>';
|
| 403 |
var v=document.querySelector('#previewContainer video');if(v)v.muted=S.isMuted;
|
| 404 |
+
if(S.audioElements)Object.keys(S.audioElements).forEach(function(id){{var au=S.audioElements[id];if(au)au.muted=S.isMuted}});
|
| 405 |
}}
|
| 406 |
function editorSetZoom(v){{S.zoom=parseFloat(v);renderTL();upPH()}}
|
| 407 |
function editorTimelineClick(e){{
|
|
|
|
| 418 |
if(S.timelineClips.length===0){{alert('ํ์๋ผ์ธ์ ํด๋ฆฝ์ ์ถ๊ฐํด์ฃผ์ธ์.');return}}
|
| 419 |
document.getElementById('exportModal').style.display='flex';
|
| 420 |
document.getElementById('exportProgress').style.width='0%';
|
| 421 |
+
document.getElementById('exportStatus').textContent='ํ๋ก์ ํธ ์ ๋ณด ์ค๋น ์ค...';
|
| 422 |
var p=0,iv=setInterval(function(){{
|
| 423 |
+
p+=5;document.getElementById('exportProgress').style.width=p+'%';
|
| 424 |
+
if(p===30)document.getElementById('exportStatus').textContent='ํด๋ฆฝ ์ ๋ณด ์์ง ์ค...';
|
| 425 |
+
if(p===60)document.getElementById('exportStatus').textContent='ํ์ผ ์์ฑ ์ค...';
|
| 426 |
+
if(p>=100){{
|
| 427 |
+
clearInterval(iv);
|
| 428 |
+
document.getElementById('exportStatus').textContent='โ
์๋ฃ! ๋ค์ด๋ก๋๋ฅผ ์์ํฉ๋๋ค.';
|
| 429 |
+
document.getElementById('cancelExportBtn').textContent='๋ซ๊ธฐ';
|
| 430 |
+
setTimeout(function(){{downloadProject()}},500);
|
| 431 |
+
}}
|
| 432 |
+
}},30);
|
| 433 |
+
}}
|
| 434 |
+
function downloadProject(){{
|
| 435 |
+
var project={{
|
| 436 |
+
version:'1.0',
|
| 437 |
+
duration:S.totalDuration,
|
| 438 |
+
clips:S.timelineClips.map(function(c){{
|
| 439 |
+
return {{id:c.id,name:c.name,type:c.type,track:c.track,start:c.start,duration:c.dur,trimStart:c.ts,trimEnd:c.te,volume:c.vol}};
|
| 440 |
+
}}),
|
| 441 |
+
media:S.mediaLibrary.map(function(m){{
|
| 442 |
+
return {{id:m.id,name:m.name,type:m.type,duration:m.duration}};
|
| 443 |
+
}})
|
| 444 |
+
}};
|
| 445 |
+
var json=JSON.stringify(project,null,2);
|
| 446 |
+
var blob=new Blob([json],{{type:'application/json'}});
|
| 447 |
+
var url=URL.createObjectURL(blob);
|
| 448 |
+
var a=document.createElement('a');
|
| 449 |
+
a.href=url;
|
| 450 |
+
a.download='video_project_'+Date.now()+'.json';
|
| 451 |
+
document.body.appendChild(a);
|
| 452 |
+
a.click();
|
| 453 |
+
document.body.removeChild(a);
|
| 454 |
+
URL.revokeObjectURL(url);
|
| 455 |
+
if(S.timelineClips.length===1){{
|
| 456 |
+
var clip=S.timelineClips[0];
|
| 457 |
+
var media=S.mediaLibrary.find(function(m){{return m.id===clip.mid}});
|
| 458 |
+
if(media&&(media.type==='video'||media.type==='audio')){{
|
| 459 |
+
setTimeout(function(){{
|
| 460 |
+
if(confirm('์๋ณธ ๋ฏธ๋์ด ํ์ผ๋ ๋ค์ด๋ก๋ํ์๊ฒ ์ต๋๊น?')){{
|
| 461 |
+
var a2=document.createElement('a');
|
| 462 |
+
a2.href=media.url;
|
| 463 |
+
a2.download=media.name;
|
| 464 |
+
document.body.appendChild(a2);
|
| 465 |
+
a2.click();
|
| 466 |
+
document.body.removeChild(a2);
|
| 467 |
+
}}
|
| 468 |
+
}},1000);
|
| 469 |
+
}}
|
| 470 |
+
}}
|
| 471 |
}}
|
| 472 |
function editorCancelExport(){{document.getElementById('exportModal').style.display='none';document.getElementById('cancelExportBtn').textContent='์ทจ์'}}
|
| 473 |
document.addEventListener('keydown',function(e){{
|