diff --git a/server/app.py b/server/app.py index 05237cf..8db4cc9 100644 --- a/server/app.py +++ b/server/app.py @@ -221,6 +221,11 @@ async def stream(job_id: str) -> StreamingResponse: return try: if job.get("paste_state"): # ๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ(์ƒˆ ํ๋ฆ„) โ€” ์ด๋ฏธ ๋ถ„์„๋œ ์ƒํƒœ๋กœ ๋“œ๋ž˜ํ”„ํŠธ๋งŒ + # paste_draft ๋Š” manifest ๋ฅผ ๋‚ด์ง€ ์•Š๋Š”๋‹ค(analyze ์ชฝ์ด ์ด๋ฏธ ๋ƒˆ๋˜ ์Šคํ…๋“ค๊ณผ + # ๋ณ„๊ฐœ ์ŠคํŠธ๋ฆผ์ด๋ผ ์—ฌ๊ธฐ์„œ ์ƒˆ๋กœ ๋‚ด์•ผ ํ•จ) โ€” ์•ˆ ๋‚ด๋ฉด step ์ด๋ฒคํŠธ๋งŒ ํ™€๋กœ ์™€์„œ + # ํ™”๋ฉด์— ์ง„ํ–‰ ํ‘œ์‹œ๊ฐ€ ์•„์˜ˆ ์•ˆ ๋œฌ๋‹ค. + yield _sse({"type": "manifest", + "steps": [{"id": "draft", "label": "ํ…œํ”Œ๋ฆฟ ๋“œ๋ž˜ํ”„ํŠธ ์ƒ์„ฑ"}]}) stream_iter = paste_draft( job["paste_state"], video_scale=job.get("video_scale", 1.0), @@ -726,11 +731,15 @@ async def paste_stream(aid: str) -> StreamingResponse: return payload = a["payload"] warnings: list[str] = [] - yield _sse({"type": "manifest", "steps": pipeline_paste_steps(True) + + # draft ์Šคํ…์€ ์ด ๋‹จ๊ณ„(analyze)์—์„œ ์•ˆ ๋ˆ๋‹ค โ€” /paste/build ๋•Œ ๋ณ„๋„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ + # ์—ฌ๊ธฐ manifest ์— ๋„ฃ์œผ๋ฉด ์˜์›ํžˆ start ๊ฐ€ ์•ˆ ์™€ ํ™”๋ฉด์— ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋ฉˆ์ถฐ ๋ณด์ธ๋‹ค. + yield _sse({"type": "manifest", "steps": + [s for s in pipeline_paste_steps(True) if s["id"] != "draft"] + [{"id": "comments", "label": "๋Œ“๊ธ€ ์ˆ˜์ง‘ (h-lab)"}, {"id": "recommend", "label": "์ปท๋ณ„ ๋Œ“๊ธ€ ์ถ”์ฒœ"}]}) com_task = asyncio.create_task( asyncio.to_thread(hlab.fetch_comments, payload["url"])) + yield _sse({"type": "step", "id": "comments", "status": "start"}) state = None try: async for ev in paste_analyze(payload, "paste_" + aid, @@ -767,12 +776,21 @@ async def paste_stream(aid: str) -> StreamingResponse: # orig = ์›๋ณธ ์˜์ƒ ์‹œ๊ฐ(โญ ๋ถ„:์ดˆ ๋งค์นญ์šฉ). ์„ž์œผ๋ฉด ์นด๋“œ๊ฐ€ ํ†ต์งธ๋กœ ์–ด๊ธ‹๋‚œ๋‹ค. places = state["card_places"] orig = [(s, e) for s, e, _, _ in state["cuts"]] - cuts, need, ai_failed = await asyncio.to_thread( - recommend.cuts_from_state, places, orig, state["bottom_caps"], comments) - if ai_failed: - warnings.append("AI ์ถ”์ฒœ ์‹คํŒจ(Gemini ์‘๋‹ต ์—†์Œ) โ€” ๋ถ„:์ดˆยท์ž๋ง‰๋‹จ์–ดยท์ข‹์•„์š”๋กœ ๋ฐฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค") + # ์˜ˆ์ƒ ๋ฐ– ์˜ˆ์™ธ๊ฐ€ ๋‚˜๋ฉด(๊ฐ์‹ธ์ง€ ์•Š์•˜์„ ๋•Œ) SSE ๊ฐ€ error ์ด๋ฒคํŠธ๋„ ์—†์ด ๋Š๊ธฐ๊ณ  + # PSTATES ๋„ ์•ˆ ๋‚จ์•„ build ๊ฐ€ 404 ๋‚œ๋‹ค โ€” ์ถ”์ฒœ ์‹คํŒจ๊ฐ€ ๊ฒ€ํ†  ํ™”๋ฉด ์ž์ฒด๋ฅผ ๋ง‰์œผ๋ฉด ์•ˆ ๋œ๋‹ค. + try: + cuts, need, ai_failed = await asyncio.to_thread( + recommend.cuts_from_state, places, orig, state["bottom_caps"], comments) + if ai_failed: + warnings.append("AI ์ถ”์ฒœ ์‹คํŒจ(Gemini ์‘๋‹ต ์—†์Œ) โ€” ๋ถ„:์ดˆยท์ž๋ง‰๋‹จ์–ดยท์ข‹์•„์š”๋กœ ๋ฐฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค") + except Exception as exc: # noqa: BLE001 + # cuts=None(๋นˆ ๋ฆฌ์ŠคํŠธ ์•„๋‹˜)์ด์–ด์•ผ ํ™”๋ฉด์ด "์ปท 0๊ฐœ"๋กœ ๋น„์ง€ ์•Š๊ณ  โญ/โž• ํด๋ฐฑ + # ํ™”๋ฉด(์ž๋™/๊ตฌ๊ฐ„ ํƒญ๊ณผ ๋™์ผํ•œ hl.cuts ์—†์Œ ๊ฒฝ๋กœ)์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค. + cuts, need = None, max(1, int(state["timeline_dur"] // 3)) + warnings.append(f"์ปท๋ณ„ ์ถ”์ฒœ ์‹คํŒจ โ€” ์ปท ์ •๋ณด ์—†์ด ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค ({type(exc).__name__}: {exc})") yield _sse({"type": "step", "id": "recommend", "status": "done", - "detail": f"{len(cuts)}์ปท ยท ์นด๋“œ {need}์žฅ"}) + "detail": (f"{len(cuts)}์ปท ยท ์นด๋“œ {need}์žฅ" if cuts is not None + else f"ํด๋ฐฑ ยท ์นด๋“œ {need}์žฅ")}) PSTATES[aid] = {"state": state, "places": places, "orig": orig, "payload": payload} no_ts = [c for c in comments if not c["times"]] @@ -800,6 +818,7 @@ async def paste_build( bg_white: str = Form(""), cards_fixed: str = Form(""), asr_bottom: str = Form("1"), + comments_dir: str = Form(""), ) -> JSONResponse: """๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ(์ƒˆ ํ๋ฆ„) 3๋‹จ๊ณ„ โ€” ๋ณด๊ด€ํ•œ ์ƒํƒœ๋กœ ๋“œ๋ž˜ํ”„ํŠธ๋งŒ ๋งŒ๋“ ๋‹ค(๋‹ค์šด๋กœ๋“œยท๋ฐ›์•„์“ฐ๊ธฐ ๋‹ค์‹œ ์•ˆ ํ•จ).""" st = PSTATES.get(aid) @@ -830,7 +849,9 @@ async def paste_build( sig = (aid + "|" + card_cuts + "|" + video_scale + "|" + flip + "|" + scene + "|" + bg_white + "|" + cards_fixed + "|" + asr_bottom + "|" + str(len(cards))) h = hashlib.sha1(sig.encode()).hexdigest()[:12] - cdir = "" + # ์นด๋“œ๊ฐ€ ์˜ค๋ฉด ํด๋” ์ง€์ •๋ณด๋‹ค ์šฐ์„ (/youtube ์™€ ๊ฐ™์€ ๊ทœ์น™). ์นด๋“œ๋ฅผ ํ•˜๋‚˜๋„ ์•ˆ ๊ณจ๋ž์œผ๋ฉด + # ํ™”๋ฉด์—์„œ ๋„˜์–ด์˜จ ํด๋” ๊ฒฝ๋กœ๋ฅผ ๊ทธ๋Œ€๋กœ ์จ์„œ ์˜ˆ์ „(ํด๋” ์ง€์ •) ๋™์ž‘์œผ๋กœ ํ•˜์œ„ํ˜ธํ™˜ํ•œ๋‹ค. + cdir = comments_dir.strip() if cards: cdir = os.path.join(COMMENTS_DIR, h) if os.path.isdir(cdir): # ์žฌ๋นŒ๋“œ ์‹œ ์ด์ „ ์นด๋“œ ์ž”์žฌ ์ œ๊ฑฐ diff --git a/server/static/auto.js b/server/static/auto.js index 729cda1..8899c56 100644 --- a/server/static/auto.js +++ b/server/static/auto.js @@ -21,8 +21,10 @@ function timeAgo(iso){ function esc(s){const d=document.createElement("div");d.textContent=String(s==null?"":s);return d.innerHTML;} function fmtT(sec){const m=Math.floor(sec/60),s=Math.floor(sec%60);return m+":"+String(s).padStart(2,"0");} let YT_HL=null; // ์œ ํŠœ๋ธŒ ๊ตฌ๊ฐ„ ํƒญ์˜ ๊ฐ€์ƒ ํ•˜์ด๋ผ์ดํŠธ {id:"yt", need} +let PASTE_HL=null; // ๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ์˜ ๊ฐ€์ƒ ํ•˜์ด๋ผ์ดํŠธ {id:"paste", need, cuts, paste:{cuts}} function hlById(id){ if(id==="yt") return YT_HL; + if(id==="paste") return PASTE_HL; return A.highlights.find(h=>h.id===id); } @@ -910,6 +912,148 @@ window.ytCC={ }, }; +/* โ”€โ”€ ๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ: ๋ถ„์„ โ†’ ๊ฒ€ํ†  โ†’ ์ƒ์„ฑ โ”€โ”€ + ์ž๋™ ํƒญ๊ณผ ๊ฐ™์€ ํ๋ฆ„(analyzeโ†’SSEโ†’onResultโ†’build)์ด์ง€๋งŒ ํŽธ์ง‘์•ˆ์ด ํ•˜๋‚˜๋ฟ์ด๋ผ + ID ํƒญ์ด ์—†๋‹ค โ€” ํŒจ๋„ ํ•˜๋‚˜(panelId="paste")๋งŒ renderCutPanel ๋กœ ๊ทธ๋ฆฐ๋‹ค. */ +let PASTE_AID=null; +function pasteLog(m){ + const d=document.createElement("div"); + d.style.cssText="font-family:var(--mono);font-size:12px;color:var(--muted2);margin-top:4px;white-space:pre-wrap;"; + d.textContent=m;$("#pasteLog").appendChild(d); +} +function renderPSteps(steps){ + $("#pasteSteps").innerHTML=steps.map(s=> + '
'+ + '
'+esc(s.label)+'
'+ + '
').join(""); + $("#pasteSteps").style.display="block"; +} +function updatePStep(ev){ + const el=$("#pst-"+ev.id);if(!el)return; + if(ev.status==="start"){el.classList.add("active");} + else if(ev.status==="done"){el.classList.remove("active");el.classList.add("done"); + if(ev.detail){const d=el.querySelector(".sdetail");d.hidden=false;d.textContent=ev.detail;}} +} +function pasteDone(){$("#pasteGo").disabled=false;$("#pasteGo").textContent="๋Œ“๊ธ€ ๋งค์นญ ์‹œ์ž‘";} +function pasteFail(m){pasteLog("โš ๏ธ "+m);pasteDone();} + +/* ์ปท๋ณ„ ์ถ”์ฒœ ๊ฒฐ๊ณผ๋ฅผ renderCutPanel ๋กœ ๊ทธ๋ฆฐ๋‹ค. hlbox-paste ๋Š” wrapOfยทclearSearchยท + expandAllCutsยทrefreshSel ์ด ์ „๋ถ€ "#hlbox-"+panelId ๋กœ ์ฐพ์œผ๋ฏ€๋กœ id๋ฅผ ์ •ํ™•ํžˆ ๋งž์ถฐ์•ผ ํ•œ๋‹ค + (yt ํƒญ์˜ #hlbox-yt ์™€ ๋™์ผํ•œ ๋ฐฉ์‹). */ +function onPasteResult(ev){ + byIdx={};(ev.comments||[]).forEach(c=>{byIdx[c.idx]=c;}); + (ev.warnings||[]).forEach(w=>pasteLog("โš ๏ธ "+w)); + PASTE_HL={id:"paste",need:ev.need,cuts:ev.cuts,paste:{cuts:ev.cutRanges}}; + sel["paste"]=[];selCut["paste"]={}; + // ์ปท๋ณ„ ์ถ”์ฒœ ์‹คํŒจ ์‹œ(ev.cuts=null) ์ž๋™ ํƒญ ํด๋ฐฑ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋งค์นญ ๋Œ“๊ธ€๋กœ ์ž๋™ ์„ ํƒ + if(ev.cuts){ + ev.cuts.forEach(cu=>{ + for(const p of (cu.picks||[])) + if(byIdx[p.idx]!==undefined&&!sel["paste"].includes(p.idx)){ + sel["paste"].push(p.idx);selCut["paste"][p.idx]=cu.i; + } + }); + }else{ + sel["paste"]=(ev.matched||[]).slice(0,ev.need).filter(i=>byIdx[i]!==undefined); + } + const area=$("#pasteReview");area.innerHTML=""; + const box=document.createElement("div"); + box.className="hlbox show";box.id="hlbox-paste"; + box.innerHTML='
์ปท '+(ev.cuts||[]).length+"๊ฐœ ยท ์ด "+ + (ev.total!=null?ev.total:0)+"์ดˆ ยท ์นด๋“œ "+ev.need+"์žฅ ํ•„์š” ยท "+ + '
'+ + '
'; + renderCutPanel(box,"paste", + {cuts:ev.cuts,matched:ev.matched,candidates:ev.candidates,cutRanges:ev.cutRanges}, + {unit:"์ปท"}); + area.appendChild(box); + refreshSel("paste"); + $("#pasteBuild").style.display="block"; +} + +function pasteAnalyze(){ + const txt=$("#pjson").value.trim(); + if(!txt){alert("ํŽธ์ง‘์•ˆ JSON์„ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”.");return;} + const btn=$("#pasteGo"); + btn.disabled=true;btn.textContent="๋ถ„์„ ์ค‘โ€ฆ"; + $("#pasteReview").innerHTML="";$("#pasteSummary").style.display="none"; + $("#pasteBuild").style.display="none";$("#pasteLog").innerHTML=""; + $("#pasteBoard").style.display="none";$("#pasteBoard").innerHTML=""; + const fd=new FormData();fd.append("data",txt); + fetch("/paste/analyze",{method:"POST",body:fd}).then(r=>r.json()).then(res=>{ + if(res.error){pasteFail(res.error);return;} + PASTE_AID=res.analysis_id; + const es=new EventSource("/paste/stream/"+PASTE_AID); + es.onmessage=(m)=>{ + const ev=JSON.parse(m.data); + if(ev.type==="manifest") renderPSteps(ev.steps); + else if(ev.type==="step") updatePStep(ev); + else if(ev.type==="log") pasteLog(ev.msg); + else if(ev.type==="result"){es.close();onPasteResult(ev);pasteDone();} + else if(ev.type==="error"){es.close();pasteFail(ev.message);} + }; + es.onerror=()=>{es.close();pasteFail("์—ฐ๊ฒฐ์ด ๋Š๊ฒผ์Šต๋‹ˆ๋‹ค.");}; + }).catch(e=>pasteFail("์š”์ฒญ ์‹คํŒจ: "+e)); +} + +/* โ”€โ”€ ์ƒ์„ฑ โ€” ์ž๋™ ํƒญ buildAll์˜ ์บก์ฒ˜ ๋ฃจํ”„๋ฅผ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ฅธ๋‹ค(์บก์ฒ˜ ํ•จ์ • 3์ข… ๋ฐฉ์–ด ํฌํ•จ). โ”€โ”€ + ์นด๋“œ๋ฅผ ํ•˜๋‚˜๋„ ๋ชป ๋ณด๋‚ด๋ฉด(๊ณ ๋ฅด์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์บก์ฒ˜ ์ „๋ถ€ ์‹คํŒจ) ์˜ˆ์ „์ฒ˜๋Ÿผ ํด๋” ์ง€์ •์œผ๋กœ + ํ•˜์œ„ํ˜ธํ™˜ํ•œ๋‹ค โ€” comments_dir ํ•„๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋„˜๊ธด๋‹ค. */ +async function pasteBuildAll(){ + if(!PASTE_AID) return; + const btn=$("#pasteBuild"); + btn.disabled=true; + $("#pasteBoard").innerHTML='
'+ + '๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐโณ ๋Œ€๊ธฐ'+ + '
'; + $("#pasteBoard").style.display="block"; + $("#pasteBoard").scrollIntoView({behavior:"smooth",block:"nearest"}); + clearSearch("paste"); // ๊ฒ€์ƒ‰ ์ค‘์ด๋ฉด ์นด๋“œ๊ฐ€ DOM์—์„œ ๋น ์ ธ ์บก์ฒ˜๊ฐ€ ๋ˆ„๋ฝ๋จ + expandAllCuts("paste"); // ์ ‘ํžŒ ์ปท ์„น์…˜์˜ ์นด๋“œ๋Š” ๋นˆ ์ด๋ฏธ์ง€๋กœ ์บก์ฒ˜๋œ๋‹ค + const pbox=$("#hlbox-paste"); + if(pbox) pbox.classList.remove("selonly"); // ๋ฐฐ์ • ์•ˆ ๋œ ์Œ๋‘ฅ์ด๊ฐ€ ์ˆจ๋Š” ๊ฒƒ ๋ฐฉ์ง€ + await nextFrame(); + boardSet("paste","๐Ÿ”„ ์ง„ํ–‰","","active"); + try{ + const fd=new FormData(); + fd.append("aid",PASTE_AID); + fd.append("video_scale",$("#vscale").value||"144"); + fd.append("flip",$("#flip").checked?"1":"0"); + fd.append("scene",$("#scene").checked?"1":"0"); + fd.append("bg_white",$("#bgwhite").checked?"1":"0"); + fd.append("asr_bottom",$("#asrbottom").checked?"1":"0"); + const cmap=selCut["paste"]||{}; + const selList=sel["paste"]||[]; + let n=0; const sentCuts=[]; + for(const idx of selList){ + const ci=cmap[idx]; + const w=wrapOf("paste",idx,ci); + if(!w) continue; + if(PASTE_HL.cuts&&ci===undefined) continue; // ์ปท ์†Œ์† ๋ชจ๋ฅด๋Š” ์นด๋“œ๋Š” ๊ฑด๋„ˆ๋œ€ + boardSet("paste",null,"์นด๋“œ ์บก์ฒ˜ ์ค‘โ€ฆ "+(++n)+"/"+selList.length,"active"); + try{ + const blob=await captureCard(w); + // โš  append ์™€ push ๋Š” ๋ฐ˜๋“œ์‹œ ์Œ์œผ๋กœ โ€” ํ•˜๋‚˜๋งŒ ๋Œ๋ฉด ์นด๋“œ๊ฐ€ ํ†ต์งธ๋กœ ์—‰๋šฑํ•œ ์ปท์— ๋ถ™๋Š”๋‹ค + fd.append("cards",blob,String(n).padStart(3,"0")+".png"); + sentCuts.push(ci); + }catch(e){n--;boardSet("paste",null,"์นด๋“œ 1์žฅ ์บก์ฒ˜ ์‹คํŒจ(๊ฑด๋„ˆ๋œ€)","active");} + } + if(PASTE_HL.cuts) fd.append("card_cuts",JSON.stringify(sentCuts)); + if(n===0) fd.append("comments_dir",$("#cdir").value.trim()); // ์นด๋“œ ์—†์Œ โ†’ ํด๋” ์ง€์ • ํ•˜์œ„ํ˜ธํ™˜ + boardSet("paste",null,"๋นŒ๋“œ ์š”์ฒญ ์ค‘โ€ฆ","active"); + const res=await(await fetch("/paste/build",{method:"POST",body:fd})).json(); + if(res.error) throw new Error(res.error); + const r=await streamJob(res.job_id,"paste"); + boardSet("paste","โœ… ์™„๋ฃŒ",(r&&r.draft_name)?r.draft_name:"",""); + const s=$("#pasteSummary");s.style.display="block"; + s.textContent="์™„๋ฃŒ โ€” CapCut ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก์—์„œ ๋“œ๋ž˜ํ”„ํŠธ๋ฅผ ์—ฌ์„ธ์š”."; + if($("#autoopen")&&$("#autoopen").checked) fetch("/open-capcut",{method:"POST"}); + }catch(e){ + boardSet("paste","โŒ ์‹คํŒจ",String(e.message||e),"err"); + } + btn.disabled=false;btn.textContent="๋‹ค์‹œ ๋งŒ๋“ค๊ธฐ"; +} + /* โ”€โ”€ โš™ ์ง€์นจยท๋ชจ๋ธ ์„ค์ • โ”€โ”€ */ async function loadPrompts(){ try{ @@ -945,5 +1089,7 @@ document.addEventListener("DOMContentLoaded",()=>{ $("#pSave").addEventListener("click",()=>savePrompts(false)); $("#pReset").addEventListener("click",()=>savePrompts(true)); if($("#ytccBtn")) $("#ytccBtn").addEventListener("click",ytMatch); + if($("#pasteGo")) $("#pasteGo").addEventListener("click",pasteAnalyze); + if($("#pasteBuild")) $("#pasteBuild").addEventListener("click",pasteBuildAll); }); })(); diff --git a/server/static/index.html b/server/static/index.html index dc48226..109b1de 100644 --- a/server/static/index.html +++ b/server/static/index.html @@ -162,7 +162,7 @@ .comment-card.mosaic .cc-avatar{filter:blur(6px);} .comment-card.mosaic .cc-author{filter:blur(5px);} /* ๊ฒ€ํ†  ํ™”๋ฉด โ€” ๋ณธ๋ฌธ 600px ์œ ์ง€, ๊ฒ€ํ†  ์˜์—ญ๋งŒ ์™€์ด๋“œ ๋ธŒ๋ ˆ์ดํฌ์•„์›ƒ(๋Œ“๊ธ€ ์นด๋“œ 3~4์—ด) */ - #autoReview,#autoSummary,#ytccArea{--rw:min(1240px,calc(100vw - 40px)); + #autoReview,#autoSummary,#ytccArea,#pasteReview,#pasteSummary{--rw:min(1240px,calc(100vw - 40px)); width:var(--rw);margin-left:calc((100% - var(--rw))/2);} /* ID ํƒญ ๋ฐ” โ€” ์Šคํฌ๋กคํ•ด๋„ ์œ„์— ๋ถ™์–ด ์žˆ์Œ */ .idtabs{position:sticky;top:0;z-index:40;display:flex;gap:6px;flex-wrap:wrap; @@ -393,8 +393,16 @@ style="width:100%;box-sizing:border-box;background:var(--surf2);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:11px;font-family:var(--mono);font-size:12.5px;line-height:1.5;resize:vertical;" placeholder='{ "url": "https://www.youtube.com/watch?v=โ€ฆ", "title_top": "์„œ๋ธŒ์ œ๋ชฉ", "title_main": "๋ฉ”์ธ์ œ๋ชฉ", "channel": "@์ฑ„๋„", "cuts": [ {"start":"0:01.0","end":"0:03.5","bottom":"ํ•˜๋‹จ ์ž๋ง‰\n๋‘ ์ค„","effect":"๊ด‘์†ํ•˜๊ฐ•"}, {"start":"2:33.5","end":"2:36.5","bottom":"๋‹ค์Œ ์ปท ์ž๋ง‰","effect":"๊ณตํฌ์˜ํ†ต๊ณ„"} ] }'> -
ํ•œ URL์˜ ์—ฌ๋Ÿฌ ์ปท + ์ž๋ง‰์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(๋ฌด์Œ์ปทยท๋ฐ›์•„์“ฐ๊ธฐ ์—†์Œ). ์ปท์€ ์ˆœ์„œ๋Œ€๋กœ ์ด์–ด๋ถ™๊ณ , ๋ฐฐ์น˜ ์‹œ๊ฐ„์€ ์ž๋™ ๊ณ„์‚ฐ๋ผ์š”. bottom=ํ•˜๋‹จ์ž๋ง‰, effect=์ค‘์•™ ํšจ๊ณผ์ž๋ง‰(ํ•˜๋‹จ ๋ฐ”๋กœ ์œ„).
+
ํ•œ URL์˜ ์—ฌ๋Ÿฌ ์ปท + ์ž๋ง‰์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ปท์€ ์ˆœ์„œ๋Œ€๋กœ ์ด์–ด๋ถ™๊ณ , ๋ฐฐ์น˜ ์‹œ๊ฐ„์€ ์ž๋™ ๊ณ„์‚ฐ๋ผ์š”. bottom=ํ•˜๋‹จ์ž๋ง‰, effect=์ค‘์•™ ํšจ๊ณผ์ž๋ง‰(ํ•˜๋‹จ ๋ฐ”๋กœ ์œ„). ๋ฌด์Œ ์ œ๊ฑฐยท๋ฐ›์•„์“ฐ๊ธฐ(Whisper)๋Š” ๋Œ“๊ธ€ ๋งค์นญ์„ ์œ„ํ•ด ํ•ญ์ƒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
+ + +
+
+
+ + + @@ -500,7 +508,7 @@ ๋ฐฐ๊ฒฝ ํฐ์ƒ‰ (์œ„์•„๋ž˜ ๋ ยท๋นˆ ๊ณณ์„ ํฐ์ƒ‰์œผ๋กœ) -
+
@@ -575,7 +583,9 @@ function setMode(m){ $("#commonFields").style.display="grid"; $("#titleGroup").style.display=(m==="paste"||m==="auto")?"none":"block"; $("#cdirField").style.display=m==="auto"?"none":"block"; - $("#run").style.display=m==="auto"?"none":"block"; // ์ž๋™ ํƒญ์€ ์ž์ฒด ๋ฒ„ํŠผ ์‚ฌ์šฉ + $("#run").style.display=(m==="auto"||m==="paste")?"none":"block"; // ์ž๋™ยท๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ์€ ์ž์ฒด ๋ฒ„ํŠผ ์‚ฌ์šฉ + // ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ์€ ๋Œ“๊ธ€ ๋งค์นญ์„ ์œ„ํ•ด ๋ฌด์Œ ์ œ๊ฑฐ๊ฐ€ ํ•ญ์ƒ ์ผœ์ง„๋‹ค โ€” ๋Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉด ์•ˆ ๋จ + $("#rmsilenceField").style.display=m==="paste"?"none":"block"; } $("#tab-file").addEventListener("click",()=>setMode("file")); $("#tab-yt").addEventListener("click",()=>setMode("yt")); @@ -611,7 +621,8 @@ yt:`

โ–ถ ์œ ํŠœ๋ธŒ ๊ตฌ๊ฐ„ ํƒญ ์‚ฌ์šฉ๋ฒ•

paste:`

๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ ์‚ฌ์šฉ๋ฒ•

  1. LLM(AI Studio ๋“ฑ)์—๊ฒŒ ์•„๋ž˜ ํ˜•์‹์˜ JSON ํ•˜๋‚˜๋ฅผ ๋ฐ›์•„ ๋ถ™์—ฌ๋„ฃ๊ธฐ
  2. -
  3. ํŽธ์ง‘ ์‹œ์ž‘ โ†’ ์ปท ์ •๋ฐ€ ๋‹ค์šด๋กœ๋“œยท๋ณ‘ํ•ฉ โ†’ ์ž๋ง‰ โ†’ CapCut
  4. +
  5. ๋Œ“๊ธ€ ๋งค์นญ ์‹œ์ž‘ โ†’ ์ปท ์ •๋ฐ€ ๋‹ค์šด๋กœ๋“œยท๋ณ‘ํ•ฉ โ†’ ๋ฌด์Œ ์ œ๊ฑฐ โ†’ ๋ฐ›์•„์“ฐ๊ธฐ โ†’ h-lab ๋Œ“๊ธ€ ๋งค์นญ
  6. +
  7. ์ปท๋งˆ๋‹ค ์ถ”์ฒœ๋œ ๋Œ“๊ธ€ ์นด๋“œ๋ฅผ ํ™•์ธยท์„ ํƒํ•˜๊ณ  ์„ ํƒํ•œ ์นด๋“œ๋กœ ๋“œ๋ž˜ํ”„ํŠธ ๋งŒ๋“ค๊ธฐ
{
  "url": "https://www.youtube.com/watch?v=์‹ค์ œID",
@@ -625,10 +636,11 @@ paste:`

๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ ์‚ฌ์šฉ๋ฒ•

  • url์€ ์‹ค์ œ ์˜์ƒ ์ฃผ์†Œ โ€” LLM์ด ์ง€์–ด๋‚ธ ID๋Š” ์‹คํŒจ
  • ๋ฐฐ์น˜ ์‹œ๊ฐ„์€ ๋„ฃ์ง€ ๋งˆ์„ธ์š” โ€” ์ปท ์ˆœ์„œ๋Œ€๋กœ ์ž๋™ ๊ณ„์‚ฐ
  • +
  • ๋ฌด์Œ ์ œ๊ฑฐยท๋ฐ›์•„์“ฐ๊ธฐ(Whisper)๋Š” ๋Œ“๊ธ€ ๋งค์นญ์„ ์œ„ํ•ด ํ•ญ์ƒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค(๋Œ ์ˆ˜ ์—†์Œ)
  • ํ•˜๋‹จ ์ž๋ง‰ ์ž๋™ ์ƒ์„ฑ(Whisper) ์ผœ์ง: bottom ๋ฌด์‹œ, ์‹ค์ œ ๋ง ํƒ€์ด๋ฐ ์ž๋ง‰ ์ƒ์„ฑ(์ถ”์ฒœ)
  • -
  • ๋„๋ฉด: bottom ์‚ฌ์šฉ, \\n ์€ ์‹œ๊ฐ„ ๋ฐ˜์”ฉ ๋‚˜๋ˆ  ์œ—์ค„โ†’์•„๋žซ์ค„
  • -
  • effect: ์ค‘์•™ ๋…น์ƒ‰ ํšจ๊ณผ์ž๋ง‰ ยท ๋Œ“๊ธ€ ์นด๋“œ: ํด๋” ์ง€์ • ์‹œ 3์ดˆ๋งˆ๋‹ค 1์žฅ
  • -
  • ๋ฌด์Œ ์ œ๊ฑฐ ์ผœ๋ฉด ์ปท ์•ˆ์˜ ๋ฌด์Œ๊นŒ์ง€ ์ปท(์ž๋ง‰ ์ž๋™ ๋ณด์ •)
  • +
  • ๋„๋ฉด(๋“œ๋ž˜ํ”„ํŠธ ๋งŒ๋“ค๊ธฐ ๋‹จ๊ณ„): bottom ์‚ฌ์šฉ, \\n ์€ ์‹œ๊ฐ„ ๋ฐ˜์”ฉ ๋‚˜๋ˆ  ์œ—์ค„โ†’์•„๋žซ์ค„
  • +
  • effect: ์ค‘์•™ ๋…น์ƒ‰ ํšจ๊ณผ์ž๋ง‰
  • +
  • ๋Œ“๊ธ€ ์นด๋“œ: ์ปท๋ณ„ ์ถ”์ฒœ์—์„œ ์นด๋“œ๋ฅผ ํ•˜๋‚˜๋„ ์•ˆ ๊ณ ๋ฅด๋ฉด ์˜ˆ์ „์ฒ˜๋Ÿผ ๋Œ“๊ธ€ ์นด๋“œ ํด๋” ์ง€์ •์œผ๋กœ ๋™์ž‘(3์ดˆ๋งˆ๋‹ค 1์žฅ)
ํ—ค๋”์˜ โœจ AI Studio์—์„œ JSON ์ƒ์„ฑ, ๐Ÿ’ฌ ๋Œ“๊ธ€ ์นด๋“œ์—์„œ ์นด๋“œ ์ €์žฅ.
`}; const overlay=$("#helpOverlay"); @@ -756,22 +768,7 @@ runBtn.addEventListener("click",async()=>{ catch(e){return fail("์š”์ฒญ ์‹คํŒจ: "+e);} if(res&&res.error){return fail(res.error);} } - if(mode==="paste"){ - const txt=$("#pjson").value.trim(); - if(!txt){addLog("ํŽธ์ง‘์•ˆ JSON์„ ๋ถ™์—ฌ๋„ฃ์œผ์„ธ์š”.");return;} - runBtn.disabled=true;runBtn.textContent="์ฒ˜๋ฆฌ ์ค‘โ€ฆ"; - const fd=new FormData();fd.append("data",txt); - fd.append("video_scale",$("#vscale").value||"144"); - fd.append("flip",$("#flip").checked?"1":"0"); - fd.append("scene",$("#scene").checked?"1":"0"); - fd.append("comments_dir",$("#cdir").value.trim()); - fd.append("bg_white",$("#bgwhite").checked?"1":"0"); - fd.append("remove_silence",$("#rmsilence").checked?"1":"0"); - fd.append("asr_bottom",$("#asrbottom").checked?"1":"0"); - try{res=await(await fetch("/paste",{method:"POST",body:fd})).json();} - catch(e){return fail("์š”์ฒญ ์‹คํŒจ: "+e);} - if(res&&res.error){return fail(res.error);} - } + // ๐Ÿ“‹ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํƒญ์€ ์ž์ฒด ๋ฒ„ํŠผ(#pasteGo โ†’ #pasteBuild, auto.js)์œผ๋กœ ๋„๋ฏ€๋กœ ์—ฌ๊ธฐ ์•ˆ ์˜ด. runBtn.textContent="์ฒ˜๋ฆฌ ์ค‘โ€ฆ"; runStream(res.job_id); });