${B}`))})})}async function uD(u){return new Promise((D,F)=>{let C=S("MP4Box",u),E="",A="";C.stdout.on("data",(B)=>{E+=B.toString()}),C.stderr.on("data",(B)=>{A+=B.toString()}),C.on("error",(B)=>{F(Error(`MP4Boxerror:${B.message}`))}),C.on("close",(B)=>{if(B===0)D();else F(Error(`MP4Boxfailedwithexitcode${B}
${A||E}`))})})}import{spawn as fu}from"node:child_process";async function P(u){return new Promise((D,F)=>{let C=fu("ffprobe",["-v","error","-show_entries","stream=width,height,duration,r_frame_rate,codec_name,codec_type,bit_rate","-show_entries","format=duration","-of","json",u]),E="";C.stdout.on("data",(A)=>{E+=A.toString()}),C.on("error",(A)=>{F(Error(`ffprobeerror:${A.message}`))}),C.on("close",(A)=>{if(A!==0){F(Error(`ffprobefailedwithexitcode${A}`));return}try{let B=JSON.parse(E),q=B.streams.find((X)=>X.codec_type==="video"),Y=B.streams.find((X)=>X.codec_type==="audio"&&X.bit_rate),K=B.format;if(!q){F(Error("No video stream found in input file"));return}let Q=30;if(q.r_frame_rate){let[X,J]=q.r_frame_rate.split("/").map(Number);if(X&&J&&J!==0)Q=X/J}let L=parseFloat(q.duration||K.duration||"0"),G=Y?.bit_rate?Math.round(parseInt(Y.bit_rate)/1000):void 0,Z=q.bit_rate?Math.round(parseInt(q.bit_rate)/1000):void 0;D({width:q.width,height:q.height,duration:L,fps:Q,codec:q.codec_name,audioBitrate:G,videoBitrate:Z})}catch(B){F(Error(`Failedtoparseffprobeoutput:${B}`))}})})}function n(u,D=256){if(!u)return`${D}k`;let F=Math.min(u,D);if(F<=64)return"64k";if(F<=96)return"96k";if(F<=128)return"128k";if(F<=192)return"192k";return"256k"}function p(u){let D=Math.floor(u/3600),F=Math.floor(u%3600/60),C=u%60;return`${String(D).padStart(2,"0")}:${String(F).padStart(2,"0")}:${C.toFixed(3).padStart(6,"0")}`}import{mkdir as gu,access as mu,constants as cu}from"node:fs/promises";async function f(u){try{await mu(u,cu.F_OK)}catch{await gu(u,{recursive:!0})}}function lu(u,D){let F=u*D;if(F<=230400)return 0.08;if(F<=409920)return 0.075;if(F<=921600)return 0.07;if(F<=2073600)return 0.065;if(F<=3686400)return 0.06;return 0.055}function M(u,D,F=30,C){let E=lu(u,D),A=Math.round(u*D*F*E/1000);if(C&&A>C)A=C;return`${A}k`}var FD=[{name:"360p",width:640,height:360,videoBitrate:M(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:M(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:M(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:M(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:M(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:M(3840,2160,30),audioBitrate:"256k"}];function CD(u,D,F=30,C){let E=[],A=FD.filter((B)=>{return B.width<=u&&B.height<=D});for(let B of A)E.push({...B,videoBitrate:M(B.width,B.height,30,C)});if(F>=45)for(let B of A)E.push(a(B,60,C));if(F>=75)for(let B of A)E.push(a(B,90,C));if(F>=95)for(let B of A)E.push(a(B,120,C));return E}function a(u,D,F){return{...u,name:`${u.name}-${D}`,videoBitrate:M(u.width,u.height,D,F)}}function MD(u){let F=u.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!F)return null;let C=F[1]+"p",E=F[2]?parseInt(F[2]):30;return{resolution:C,fps:E}}function ND(u,D=30,F){let C=FD.find((E)=>E.name===u);if(!C)return null;if(D===30)return{...C,videoBitrate:M(C.width,C.height,30,F)};return a(C,D,F)}function du(u,D,F,C){let E=MD(u);if(!E)return`Invalidprofileformat:${u}.Useformatlike:360,720@60,1080-60`;let A=ND(E.resolution,E.fps);if(!A)return`Unknownresolution:${E.resolution}.Available:360,480,720,1080,1440,2160`;if(A.width>D||A.height>F)return`Sourceresolution(${D}x${F})islowerthan${u}(${A.width}x${A.height})`;if(E.fps>C)return`SourceFPS(${C})islowerthanrequested${E.fps}FPSin${u}`;return null}function jD(u,D,F,C,E){let A=[],B=[];for(let q of u){let Y=du(q,D,F,C);if(Y){B.push(Y);continue}let K=MD(q);if(!K)continue;let Q=ND(K.resolution,K.fps,E);if(Q)A.push(Q)}return{profiles:A,errors:B}}import{join as j}from"node:path";import{readdir as nu,unlink as wD,rmdir as pu,writeFile as OD}from"node:fs/promises";async function yD(u,D,F="00:00:01"){let C=j(D,"poster.jpg"),E=/^\d+(\.\d+)?$/.test(F)?F:F;return await w(["-ss",E,"-i",u,"-vframes","1","-q:v","2","-y",C]),C}async function SD(u,D,F,C){let{width:E,height:A,interval:B,columns:q}=C,Y=j(D,".thumbnails_temp");await f(Y),await OD(j(Y,".keep"),"");let K=j(Y,"thumb_%0
`}return B}import{join as su}from"node:path";async function TD(u,D,F,C,E,A,B,q,Y,K,Q,L){let G=su(D,`video_${K}_${F.name}.mp4`),Z=["-y","-i",u,"-c:v",C];if(C==="h264_nvenc")Z.push("-rc:v","vbr"),Z.push("-preset",E),Z.push("-2pass","0");else if(C==="av1_nvenc")Z.push("-rc:v","vbr"),Z.push("-preset",E),Z.push("-2pass","0");else if(C==="av1_qsv")Z.push("-preset",E),Z.push("-global_quality","23");else if(C==="av1_amf")Z.push("-quality","balanced"),Z.push("-rc","vbr_latency");else if(C==="libsvtav1")Z.push("-preset",E),Z.push("-svtav1-params","tune=0:enable-overlays=1");else Z.push("-preset",E);let X=K==="av1"?0.6:1,J=Math.round(parseInt(F.videoBitrate)*X),W=`${J}k`;Z.push("-b:v",W,"-maxrate",W,"-bufsize",`${J*2}k`);let I=Math.round(q*B);Z.push("-g",String(I),"-keyint_min",String(I),"-sc_threshold","0");let U=[`scale=${F.width}:${F.height}`];if(Q){if(Q.deinterlace)U.push("yadif");if(Q.denoise)U.push("hqdn3d");if(Q.customFilters)U.push(...Q.customFilters)}Z.push("-vf",U.join(","));let N=parseInt(F.audioBitrate)||256,V=n(Y,N);if(Z.push("-c:a","aac","-b:a",V),Q?.audioNormalize)Z.push("-af","loudnorm");return Z.push("-f","mp4",G),await w(Z,L,A),G}async function bD(u,D,F,C,E,A,B,q,Y,K,Q,L,G,Z){let X=new Map;if(K&&F.length>1)for(let J=0;J<F.length;J+=Q){let W=F.slice(J,J+Q),I=W.map((N)=>TD(u,D,N,C,E,A,B,q,Y,L,G,(V)=>{if(Z)Z(N.name,V)}));(await Promise.all(I)).forEach((N,V)=>{let x=W[V];X.set(x.name,N)})}else for(let J of F){let W=await TD(u,D,J,C,E,A,B,q,Y,L,G,(I)=>{if(Z)Z(J.name,I)});X.set(J.name,W)}return X}import{join as O}from"node:path";async function vD(u,D,F,C,E){let A=O(D,"manifest.mpd"),B=["-dash",String(C*1000),"-frag",String(C*1000),"-rap","-segment-timeline","-segment-name","$RepresentationID$_$Number$","-out",A],q=!0;for(let[Y,K]of u.entries())for(let Q of F){let L=K.get(Q.name);if(!L)throw Error(`MP4filenotfoundforprofile:${Q.name},codec:${Y}`);let G=E==="dual"?`${Q.name}-${Y}`:Q.name;if(B.push(`${L}#video:id=${G}`),q)B.push(`${L}#audio:id=audio`),q=!1}return await uD(B),await ru(D,F,E),await iu(A,F,E),A}async function ru(u,D,F){let{readdir:C,rename:E,mkdir:A}=await import("node:fs/promises"),B=[];if(F==="h264"||F==="dual")B.push("h264");if(F==="av1"||F==="dual")B.push("av1");let q=[];for(let Q of B)for(let L of D){let G=F==="dual"?`${L.name}-${Q}`:L.name;q.push(G);let Z=O(u,G);await A(Z,{recursive:!0})}let Y=O(u,"audio");await A(Y,{recursive:!0});let K=await C(u);for(let Q of K){if(Q==="manifest.mpd")continue;if(Q.startsWith("audio_")||Q==="audio_init.m4s"){let L=O(u,Q),G=O(Y,Q);await E(L,G);continue}for(let L of q)if(Q.startsWith(`${L}_`)){let G=O(u,Q),Z=O(u,L,Q);await E(G,Z);break}}}async function iu(u,D,F){let{readFile:C,writeFile:E}=await import("node:fs/promises"),A=await C(u,"utf-8");A=A.replace(/media="\$RepresentationID\$_\$Number\$\.m4s"/g,'media="$RepresentationID$/$RepresentationID$_$Number$.m4s"'),A=A.replace(/initialization="\$RepresentationID\$_\.mp4"/g,'initialization="$RepresentationID$/$RepresentationID$_.mp4"'),await E(u,A,"utf-8")}async function ED(u){let{input:D,outputDir:F,segmentDuration:C=2,profiles:E,customProfiles:A,codec:B="dual",useNvenc:q,generateThumbnails:Y=!0,thumbnailConfig:K={},generatePoster:Q=!0,posterTimecode:L="00:00:01",parallel:G=!0,onProgress:Z}=u,X=hD("/tmp",`dash-converter-${eu()}`);await f(X);try{return await DF(D,F,X,C,E,A,B,q,Y,K,Q,L,G,Z)}finally{try{await PD(X,{recursive:!0,force:!0})}catch(J){console.warn(`Warning:Failedtocleanuptempdirectory:${X}`)}}}async function DF(u,D,F,C,E,A,B,q,Y,K,Q,L,G,Z){if(!await T())throw Error("FFmpeg is not installed or not in PATH");if(!await b())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let X=(R,_,m,e)=>{if(Z)Z({stage:R,percent:_,message:m,currentProfile:e})};X("analyzing",0,"Analyzing input video...");let J=await P(u),W=q!==!1?await v():!1,I=q===!0?!0:q===!1?!1:W;if(q===!0&&!W)throw Error("NVENC requested but not available. Check NVIDIA drivers and GPU support.");let U;if(A&&A.length>0){let R=jD(A,J.width,J.height,J.fps,J.videoBitrate);if(R.errors.length>0){console.warn(`
⚠️Profilewarnings:`);for(let _ of R.errors)console.warn(`-${_}`);console.warn("")}if(U=R.profiles,U.length===0)throw Error("No valid profiles found in custom list. Check warnings above.")}else if(E)U=E;else U=CD(J.width,J.height,J.fps,J.videoBitrate);if(U.length===0)throw Error("No suitable profiles found for input video resolution");let N=ou(u,tu(u)),V=hD(D,N);try{await PD(V,{recursive:!0,force:!0})}catch(R){}await f(V);let x=[];if(B==="h264"||B==="dual"){let R=I?"h264_nvenc":"libx264",_=I?"p4":"medium";x.push({type:"h264",codec:R,preset:_})}if(B==="av1"||B==="dual"){let R=await h(),_=R.available?R.encoder:"libsvtav1",m=R.available?_==="av1_nvenc"?"p4":"medium":"8";x.push({type:"av1",codec:_,preset:m})}let Nu=x.map((R)=>R.type.toUpperCase()).join(" + ");X("analyzing",20,`Using${Nu}encoding(${I?"GPU":"CPU"})`,void 0);let ju=I?3:2,t=new Map;for(let R=0;R<x.length;R++){let{type:_,codec:m,preset:e}=x[R],HD=R/x.length,Ou=1/x.length;X("encoding",25+HD*40,`Stage1:Encoding${_.toUpperCase()}(${U.length}profiles)...`);let yu=await bD(u,F,U,m,e,J.duration,C,J.fps||25,J.audioBitrate,G,ju,_,void 0,(c,WD)=>{let yF=U.findIndex((Su)=>Su.name===c),VD=25+HD*40,zD=WD/100*(40*Ou/U.length);if(X("encoding",VD+zD,`Encoding${_.toUpperCase()}${c}...`,`${_}-${c}`),Z)Z({stage:"encoding",percent:VD+zD,currentProfile:`${_}-${c}`,profilePercent:WD,message:`Encoding${_.toUpperCase()}${c}...`})});t.set(_,yu)}X("encoding",65,"Stage 1 complete: All codecs and profiles encoded"),X("encoding",70,"Stage 2: Creating DASH with MP4Box...");let wu=await vD(t,V,U,C,B),UD=[];for(let R of t.values())UD.push(...Array.from(R.values()));X("encoding",80,"Stage 2 complete: DASH created");let kD,_D;if(Y){X("thumbnails",80,"Generating thumbnail sprites...");let R={width:K.width||160,height:K.height||90,interval:K.interval||1,columns:K.columns||10},_=await SD(u,V,J.duration,R);kD=_.spritePath,_D=_.vttPath,X("thumbnails",90,"Thumbnails generated")}let ID;if(Q)X("thumbnails",92,"Generating poster image..."),ID=await yD(u,V,L),X("thumbnails",95,"Poster generated");return X("manifest",95,"Finalizing manifest..."),X("complete",100,"Conversion complete!"),{manifestPath:wu,videoPaths:UD,thumbnailSpritePath:kD,thumbnailVttPath:_D,posterPath:ID,duration:J.duration,profiles:U,usedNvenc:I,codecType:B}}var GD=DD(Wu(),1);import{statSync as jF}from"node:fs";var H=process.argv.slice(2),i,o,g="dual",RD=[];for(let u=0;u<H.length;u++)if(H[u]==="-r"||H[u]==="--resolutions"){let D=[];for(let C=u+1;C<H.length;C++){if(H[C].startsWith("-"))break;D.push(H[C]),u=C}i=D.join(",").split(/[,\s]+/).map((C)=>C.trim()).filter((C)=>C.length>0)}else if(H[u]==="-p"||H[u]==="--poster")o=H[u+1],u++;else if(H[u]==="-c"||H[u]==="--codec"){let D=H[u+1];if(D==="av1"||D==="h264"||D==="dual")g=D;else console.error(`❌Invalidcodec:${D}.Validoptions:av1,h264,dual`),process.exit(1);u++}else if(!H[u].startsWith("-"))RD.push(H[u]);var d=RD[0],Vu=RD[1]||".";if(!d)console.error("❌ Usage: dvc-cli <input-video> [output-dir] [-r resolutions] [-c codec] [-p poster-timecode]"),console.error(`
Options:`),console.error(" -r, --resolutions Video resolutions (e.g., 360,480,720 or 720@60,1080@60)"),console.error(" -c, --codec Video codec: av1, h264, or dual (default: dual)"),console.error(" -p, --poster Poster timecode (e.g., 00:00:05 or 10)"),console.error(`
`);var zu=await T(),xu=await v(),$D=await h(),Mu=await b();console.log(`FFmpeg:${zu?"✅":"❌"}`);console.log(`NVENC(H.264):${xu?"✅ (GPU acceleration)":"⚠️ (CPU only)"}`);if($D.available)console.log(`AV1Encoder:✅${$D.encoder}(GPUacceleration)`);else console.log("AV1 Encoder: ⚠️ (not available, will use CPU fallback)");console.log(`MP4Box:${Mu?"✅":"❌"}
`);if(!zu)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!Mu)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);if((g==="av1"||g==="dual")&&!$D.available)console.error("⚠️ Warning: AV1 encoding requested but no hardware AV1 encoder found."),console.error(" CPU-based AV1 encoding (libsvtav1) will be VERY slow."),console.error(`Considerusing--codech264forfasterencoding.
`);console.log(`\uD83D\uDCCAAnalyzingvideo...
`);var z=await P(d),wF=jF(d),OF=(wF.size/1048576).toFixed(2);console.log("\uD83D\uDCF9 Video Information:");console.log(`File:${d}`);console.log(`Size:${OF}MB`);console.log(`Resolution:${z.width}x${z.height}`);console.log(`FPS:${z.fps.toFixed(2)}`);console.log(`Duration:${Math.floor(z.duration/60)}m${Math.floor(z.duration%60)}s`);console.log(`Codec:${z.codec}`);if(z.videoBitrate)console.log(`VideoBitrate:${(z.videoBitrate/1000).toFixed(2)}Mbps`);if(z.audioBitrate)console.log(`AudioBitrate:${z.audioBitrate}kbps`);console.log(`
\uD83D\uDCC1Output:${Vu}`);console.log(`\uD83C\uDFACCodec:${g}${g==="dual"?" (AV1 + H.264 for maximum compatibility)":""}`);if(i)console.log(`\uD83C\uDFAFCustomprofiles:${i.join(", ")}`);if(o)console.log(`\uD83D\uDDBC️Postertimecode:${o}`);console.log(`