`).map((C)=>C.trim()).filter(Boolean),E=[],F={cuda:"nvenc",qsv:"qsv",vaapi:"vaapi",videotoolbox:"videotoolbox",v4l2m2m:"v4l2",dxva2:"amf"};for(let C of D){let B=F[C];if(B)E.push({accelerator:B})}return E}async function l(u,D,E){let C=`
${G}`))}})})}import{spawn as SF}from"node:child_process";async function t(u){return new Promise((D,E)=>{let F=SF("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]),C="";F.stdout.on("data",(B)=>{C+=B.toString()}),F.on("error",(B)=>{E(Error(`ffprobeerror:${B.message}`))}),F.on("close",(B)=>{if(B!==0){E(Error(`ffprobefailedwithexitcode${B}`));return}try{let A=JSON.parse(C),Z=A.streams.find((_)=>_.codec_type==="video"),J=A.streams.find((_)=>_.codec_type==="audio"),G=A.format;if(!Z){E(Error("No video stream found in input file"));return}let X=30;if(Z.r_frame_rate){let[_,W]=Z.r_frame_rate.split("/").map(Number);if(_&&W&&W!==0)X=_/W}let Y=parseFloat(Z.duration||G.duration||"0"),$=A.streams.find((_)=>_.codec_type==="audio"&&_.bit_rate),N=$?.bit_rate?Math.round(parseInt($.bit_rate)/1000):void 0,K=Z.bit_rate?Math.round(parseInt(Z.bit_rate)/1000):void 0;D({width:Z.width,height:Z.height,duration:Y,fps:X,codec:Z.codec_name,hasAudio:Boolean(J),audioBitrate:N,videoBitrate:K})}catch(A){E(Error(`Failedtoparseffprobeoutput:${A}`))}})})}function JD(u,D=256){if(!u)return`${D}k`;let E=Math.min(u,D);if(E<=64)return"64k";if(E<=96)return"96k";if(E<=128)return"128k";if(E<=192)return"192k";return"256k"}function KD(u){let D=Math.floor(u/3600),E=Math.floor(u%3600/60),F=u%60;return`${String(D).padStart(2,"0")}:${String(E).padStart(2,"0")}:${F.toFixed(3).padStart(6,"0")}`}import{mkdir as TF,access as bF,constants as yF}from"node:fs/promises";async function d(u){try{await bF(u,yF.F_OK)}catch{await TF(u,{recursive:!0})}}function hF(u,D){let E=u*D;if(E<=230400)return 0.08;if(E<=409920)return 0.075;if(E<=921600)return 0.07;if(E<=2073600)return 0.065;if(E<=3686400)return 0.06;return 0.055}function v(u,D,E=30,F){let C=hF(u,D),B=Math.round(u*D*E*C/1000);if(F&&B>F)B=F;return`${B}k`}var VD=[{name:"360p",width:640,height:360,videoBitrate:v(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:v(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:v(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:v(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:v(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:v(3840,2160,30),audioBitrate:"256k"}];function CD(u,D,E=30,F){let C=[],B=VD.filter((A)=>{return A.width<=u&&A.height<=D});for(let A of B)C.push({...A,videoBitrate:v(A.width,A.height,30,F),fps:30});return C}function fF(u,D,E){return{...u,name:`${u.name}-${D}`,videoBitrate:v(u.width,u.height,D,E),fps:D}}function Fu(u){let E=u.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!E)return null;let F=E[1]+"p",C=E[2]?parseInt(E[2]):30;return{resolution:F,fps:C}}function Eu(u,D=30,E){let F=VD.find((C)=>C.name===u);if(!F)return null;if(D===30)return{...F,videoBitrate:v(F.width,F.height,30,E),fps:30};return fF(F,D,E)}function gF(u,D,E,F){let C=Fu(u);if(!C)return{error:`Invalidprofileformat:${u}.Useformatlike:360,720@60,1080-60`};let B=Eu(C.resolution,C.fps);if(!B)return{error:`Unknownresolution:${C.resolution}.Available:360,480,720,1080,1440,2160`};if(B.width>D||B.height>E)return{error:`Sourceresolution(${D}x${E})islowerthan${u}(${B.width}x${B.height})`};let A=120,Z=C.fps,J;if(C.fps>F)Z=Math.min(F,A),J=`Requested${C.fps}FPSin${u},butsourceis${F}FPS.Using${Z}FPSinstead`;else if(C.fps>A)Z=A,J=`Requested${C.fps}FPSin${u}exceedsmaximum${A}FPS.Using${Z}FPSinstead`;return J?{warning:J,adjustedFps:Z}:{}}function XD(u,D,E,F,C){let B=[],A=[],Z=[];for(let J of u){let G=gF(J,D,E,F);if(G.error){A.push(G.error);continue}if(G.warning)Z.push(G.warning);let X=Fu(J);if(!X)continue;let Y=G.adjustedFps!==void 0?G.adjustedFps:X.fps,$=Eu(X.resolution,Y,C);if($)B.push($)}return{profiles:B,errors:A,warnings:Z}}import{join as g}from"node:path";import{readdir as mF,unlink as Cu,rmdir as cF,writeFile as Bu}from"node:fs/promises";async function Au(u,D,E="00:00:00"){let F=g(D,"po
`;for(let F of u){let C=D?"avc1.4D4020,mp4a.40.2":"avc1.4D4020";if(E+=`#EXT-X-STREAM-INF:BANDWIDTH=${F.bandwidth},CODECS="${C}",RESOLUTION=${F.resolution},FRAME-RATE=${F.fps}`,D)E+=',AUDIO="audio"';E+=`
`,"utf-8")}catch(QD){}try{await _u(U,{recursive:!0,force:!0})}catch(QD){console.warn(`Warning:Failedtocleanuptempdirectory:${U}`)}}}async function rF(u,D,E,F,C,B,A,Z,J,G,X,Y,$,N,K,_,W){if(!await a())throw Error("FFmpeg is not installed or not in PATH");if(!await i())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let U=(z,x,zD,HD)=>{if(W)W({stage:z,percent:x,message:zD,currentProfile:HD})};U("analyzing",0,"Analyzing input video...");let k=await t(u),q=k.hasAudio,V=J&&J!=="auto"?J:"auto",L=await r(),y=await o(),{selected:P,h264Encoder:QD,av1Encoder:UF,warnings:nD}=oF(L,V,A);if(nD.length>0)for(let z of nD)console.warn(`⚠️${z}`);let{selected:ZD}=tF(y,G||"auto"),WF=L.some((z)=>z.av1Encoder),c=A;if(A==="dual"&&!WF)console.warn("⚠️ AV1 hardware encoder not detected. Switching to H.264 only."),c="h264";let R;if(B&&B.length>0){let z=XD(B,k.width,k.height,k.fps,k.videoBitrate);if(z.errors.length>0){console.warn(`
❌Profileerrors:`);for(let x of z.errors)console.warn(`-${x}`);console.warn("")}if(z.warnings.length>0){console.warn(`
⚠️Profilewarnings:`);for(let x of z.warnings)console.warn(`-${x}`);console.warn("")}if(R=z.profiles,R.length===0)throw Error("No valid profiles found in custom list. Check errors above.")}else if(C)R=C;else R=CD(k.width,k.height,k.fps,k.videoBitrate);if(R.length===0)throw Error("No suitable profiles found for input video resolution");let kF=Nu(u,Qu(u)),FD=YD(D,kF);try{await _u(FD,{recursive:!0,force:!0})}catch(z){}await d(FD);let h=[];if(c==="h264"||c==="dual"){let z=QD||"libx264",x=ku(z,"h264");h.push({type:"h264",codec:z,preset:x})}if(c==="av1"||c==="dual"){let z=UF||"libsvtav1",x=ku(z,"av1");h.push({type:"av1",codec:z,preset:x})}let NF=h.map((z)=>z.type.toUpperCase()).join(" + "),QF=P==="cpu"?"CPU":P.toUpperCase();U("analyzing",20,`Using${NF}encoding(${QF},decoder${ZD.toUpperCase()})`,void 0);let _F=P==="cpu"?2:3,_D=new Map;for(let z=0;z<h.length;z++){let{type:x,codec:zD,preset:HD}=h[z],oD=z/h.length,qF=1/h.length;U("encoding",25+oD*40,`Stage1:Encoding${x.toUpperCase()}(${R.length}profiles)...`);let xF=x==="h264"?X?.h264:X?.av1,IF=await Ju(u,E,R,zD,HD,k.duration,F,k.audioBitrate,_,_F,x,xF,void 0,ZD==="cpu"?void 0:ZD,(ED,tD)=>{let f8=R.findIndex((VF)=>VF.name===ED),eD=25+oD*40,Du=tD/100*(40*qF/R.length);if(U("encoding",eD+Du,`Encoding${x.toUpperCase()}${ED}...`,`${x}-${ED}`),W)W({stage:"encoding",percent:eD+Du,currentProfile:`${x}-${ED}`,profilePercent:tD,message:`Encoding${x.toUpperCase()}${ED}...`})});_D.set(x,IF)}U("encoding",65,"Stage 1 complete: All codecs and profiles encoded"),U("encoding",70,"Stage 2: Creating segments and manifests...");let{manifestPath:zF,hlsManifestPath:HF}=await Wu(_D,FD,R,F,c,Z,q),sD=[];for(let z of _D.values())sD.push(...Array.from(z.values()));U("encoding",80,"Stage 2 complete: All formats packaged");let aD,iD;if(Y){U("thumbnails",80,"Generating thumbnail sprites...");let z={width:$.width||160,height:$.height||90,interval:$.interval||1,columns:$.columns||10},x=await Zu(u,FD,k.duration,z);aD=x.spritePath,iD=x.vttPath,U("thumbnails",90,"Thumbnails generated")}let rD;if(N)U("thumbnails",92,"Generating poster image..."),rD=await Au(u,FD,K),U("thumbnails",95,"Poster generated");return U("manifest",95,"Finalizing..."),U("complete",100,"Conversion complete!"),{manifestPath:zF,hlsManifestPath:HF,videoPaths:sD,thumbnailSpritePath:aD,thumbnailVttPath:iD,posterPath:rD,duration:k.duration,profiles:R,usedNvenc:h.some((z)=>z.codec.includes("nvenc")),selectedAccelerator:P,selectedDecoder:ZD,codecType:c,format:Z}}var e={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60,cpu:1};function oF(u,D,E){let F=E==="h264"||E==="dual",C=E==="av1"||E==="dual",B=[],A=new Set(["nvenc","qsv","amf"]),Z=u.filter((U)=>F&&U.h264Encoder||C&&U.av1Encoder),J=Z.filter((U)=>A.has(U.accelerator)),G=(U)=>Z.find((k)=>k.accelerator===U),X;if(D!=="auto"){if(D==="cpu")X=void 0;else if(!A.has(D))B.push(`Ускоритель"${D}"поканеподдерживается,используюCPU`);else if(X=G(D),!X)throw Error(`Аппаратныйускоритель"${D}"недоступенвсистеме`)}else if(X=(J.length>0?J:[]).sort((k,q)=>(e[q.accelerator]||0)-(e[k.accelerator]||0))[0],!X&&Z.length>0)B.push("Доступен аппаратный ускоритель, но он пока не поддерживается пайплайном, использую CPU");let $=(J.length>0?J:[]).sort((U,k)=>(e[k.accelerator]||0)-(e[U.accelerator]||0)),N=(U)=>{let k=U==="h264"?X?.h264Encoder:X?.av1Encoder;if(k)return{encoder:k,accel:X?.accelerator};let q=$.find((V)=>U==="h264"?V.h264Encoder:V.av1Encoder);if(q){if(D!=="auto"&&X)B.push(`Выбранныйускоритель"${X.accelerator}"неподдерживает${U.toUpperCase()},использую${q.accelerator}`);return{encoder:U==="h264"?q.h264Encoder:q.av1Encoder,accel:q.accelerator}}if(D!=="auto"&&D!=="cpu")B.push(`Ускоритель"${D}"неподдерживает${U.toUpperCase()},используюCPU`);return{encoder:void 0,accel:"cpu"}},K=F?N("h264"):{encoder:void 0,accel:X?.accelerator},_=C?N("av1"):{encoder
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(" -f, --format Streaming format: dash, hls, or both (default: both)"),console.error(" -p, --poster Poster timecode (e.g., 00:00:05 or 10)"),console.error(" -e, --encoder <type> Hardware encoder: auto|nvenc|qsv|amf|vaapi|videotoolbox|v4l2|cpu (default: auto)"),console.error(" -d, --decoder <type> Hardware decoder: auto|nvenc|qsv|amf|vaapi|videotoolbox|v4l2|cpu (default: auto)"),console.error(`
`);var XF=await a(),YF=await i(),pD=await r(),GF=pD.some((u)=>u.av1Encoder),ND=await o(),BF={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60},AF=pD.slice().sort((u,D)=>(BF[D.accelerator]||0)-(BF[u.accelerator]||0))[0];console.log(`FFmpeg:${XF?"✅":"❌"}`);console.log(`MP4Box:${YF?"✅":"❌"}`);var O8=Array.from(new Set(pD.map((u)=>u.accelerator.toUpperCase()))),AD=AF?AF.accelerator.toUpperCase():void 0,ZF=O8.filter((u)=>u!==AD),R8=AD?`✅${AD}${ZF.length>0?` (${ZF.join(", ")})`:""}`:"❌";console.log(`Hardware:${R8}`);if(ND.length>0){let u=Array.from(new Set(ND.map((D)=>D.accelerator.toUpperCase())));console.log(`Decoders:${u.join(", ")}`)}console.log("");if(!XF)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!YF)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);if((j==="av1"||j==="dual")&&!GF){if(j==="av1")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.
`);else if(j==="dual")console.warn("⚠️ AV1 hardware encoder not detected. Using H.264 only (disable AV1)."),j="h264"}if((DD==="hls"||DD==="both")&&j==="av1")console.error("❌ Error: HLS format requires H.264 codec for Safari/iOS compatibility."),console.error(`Pleaseuse--codech264or--codecdualwith--formathls