From b7e264d56fd2f8b7e1fa5d85a8372f4ff5bd2088 Mon Sep 17 00:00:00 2001 From: "S.Gromov" Date: Tue, 20 Jan 2026 14:52:59 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20readme=20=D0=BF=D0=BE=D0=B4=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=BE=D0=BF=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 ++++-------- README_RU.md | 13 ++------- bin/cli.js | 61 ++++++++++++++++++++--------------------- src/cli.ts | 64 ++++++++++++++++++------------------------- src/core/converter.ts | 32 ++++++++-------------- src/index.ts | 2 -- src/types/index.ts | 18 +++--------- 7 files changed, 81 insertions(+), 126 deletions(-) diff --git a/README.md b/README.md index 7a43243..d1e6915 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 🇷🇺 Russian README: https://gromlab.ru/vod/create-vod/src/branch/master/README_RU.md -CLI tool to convert videos to DASH and HLS with hardware acceleration (NVENC / Intel QSV / AMD AMF / VAAPI), adaptive streaming, and automatic thumbnails/poster. +CLI tool to convert videos to DASH and HLS with hardware acceleration (NVENC / Intel QSV / AMD AMF / VAAPI), adaptive streaming, and automatic thumbnails/poster. Formats are always DASH + HLS. **Features:** - ⚡ Hardware acceleration: auto-detect encoder/decoder (NVENC / Intel QSV / AMD AMF / VAAPI / CPU) @@ -34,12 +34,12 @@ sudo apt install ffmpeg gpac brew install ffmpeg gpac ``` -**Output:** A folder `video/` in the current directory with segments under `{profile}-{codec}/`, DASH/HLS manifests in the root, poster, and thumbnail sprite/VTT. +**Output:** A folder `video/` in the current directory with segments under `{profile}-{codec}/`, DASH/HLS manifests in the root, poster, and thumbnail sprite/VTT (both DASH and HLS are always generated). ## CLI Usage ```bash -create-vod [output-dir] [-r resolutions] [-c codec] [-f format] [-p poster-timecode] +create-vod [output-dir] [-r resolutions] [-c codec] [-p poster-timecode] ``` ### Main arguments @@ -54,8 +54,7 @@ create-vod [output-dir] [-r resolutions] [-c codec] [-f format] [- | Option | Description | Values / Format | Default | Example | |--------|----------------------------|----------------------------|----------|---------------------------------| | `-r, --resolutions` | Quality profiles | `360`, `720@60`, `1080-60` | auto | `-r 720,1080,1440@60` | -| `-c, --codec` | Video codec | `h264`, `av1` | auto (h264 + AV1 if HW) | `-c h264` | -| `-f, --format` | Streaming format | `dash`, `hls` | auto (dash + hls) | `-f dash` | +| `-c, --codec` | Video codec(s) | `h264`, `av1` (comma/space separated) | `h264` | `-c h264,av1` | | `-p, --poster` | Poster timecode | `HH:MM:SS` or seconds | `00:00:00` | `-p 00:00:05` or `-p 10` | | `-e, --encoder` | Video encoder | `auto`, `nvenc`, `qsv`, `amf`, `vaapi`, `videotoolbox`, `v4l2`, `cpu` | `auto` | `-e nvenc` | | `-d, --decoder` | Video decoder (hwaccel) | `auto`, `nvenc`, `qsv`, `vaapi`, `videotoolbox`, `v4l2`, `cpu` | `auto` | `-d cpu` | @@ -63,7 +62,7 @@ create-vod [output-dir] [-r resolutions] [-c codec] [-f format] [- ### Examples ```bash -# Default (DASH + HLS, auto codec, auto profiles) +# Default (DASH + HLS, auto profiles) create-vod video.mp4 # Custom output directory @@ -75,12 +74,6 @@ create-vod video.mp4 -r 720,1080,1440 # High FPS create-vod video.mp4 -r 720@60,1080@60 -# DASH only -create-vod video.mp4 -f dash - -# HLS only (Safari/iOS) -create-vod video.mp4 -f hls -c h264 - # Poster from 5th second create-vod video.mp4 -p 5 diff --git a/README_RU.md b/README_RU.md index d3fa20c..8de4d4f 100644 --- a/README_RU.md +++ b/README_RU.md @@ -2,7 +2,7 @@ 🇺🇸 English README: https://gromlab.ru/vod/create-vod/src/branch/master/README.md -CLI инструмент для конвертации видео в форматы DASH и HLS с поддержкой аппаратного ускорения (NVENC / Intel QSV / AMD AMF / VAAPI), адаптивным стримингом и автоматической генерацией превью. +CLI инструмент для конвертации видео в форматы DASH и HLS с поддержкой аппаратного ускорения (NVENC / Intel QSV / AMD AMF / VAAPI), адаптивным стримингом и автоматической генерацией превью. Форматы всегда DASH + HLS. **Возможности:** - ⚡ Аппаратное ускорение: NVENC / Intel QSV / AMD AMF / VAAPI (автовыбор по приоритету) @@ -39,7 +39,7 @@ brew install ffmpeg gpac ## Параметры CLI ```bash -create-vod [output-dir] [-r resolutions] [-c codec] [-f format] [-p poster-timecode] +create-vod [output-dir] [-r resolutions] [-c codec] [-p poster-timecode] ``` ### Основные параметры @@ -54,8 +54,7 @@ create-vod [output-dir] [-r resolutions] [-c codec] [-f format] [- | Ключ | Описание | Значения / формат | По умолчанию | Пример | |------|----------|-------------------|--------------|--------| | `-r, --resolutions` | Выбор профилей качества | `360`, `720@60`, `1080-60` | авто | `-r 720,1080,1440@60` | -| `-c, --codec` | Видео кодек | `h264`, `av1` | авто (h264 + AV1 при наличии HW) | `-c h264` | -| `-f, --format` | Формат стриминга | `dash`, `hls` | авто (dash + hls) | `-f dash` | +| `-c, --codec` | Видео кодек(и) | `h264`, `av1` (через пробел или запятую) | `h264` | `-c h264,av1` | | `-p, --poster` | Таймкод для постера | `HH:MM:SS` или секунды | `00:00:00` | `-p 00:00:05` или `-p 10` | | `-e, --encoder` | Видео энкодер | `auto`, `nvenc`, `qsv`, `amf`, `vaapi`, `videotoolbox`, `v4l2`, `cpu` | `auto` | `-e nvenc` | | `-d, --decoder` | Видео декодер (hwaccel) | `auto`, `nvenc`, `qsv`, `vaapi`, `videotoolbox`, `v4l2`, `cpu` | `auto` | `-d cpu` | @@ -75,12 +74,6 @@ create-vod video.mp4 -r 720,1080,1440 # Высокий FPS для игровых стримов create-vod video.mp4 -r 720@60,1080@60 -# Только DASH формат -create-vod video.mp4 -f dash - -# Только HLS для Safari/iOS -create-vod video.mp4 -f hls -c h264 - # Постер с 5-й секунды create-vod video.mp4 -p 5 diff --git a/bin/cli.js b/bin/cli.js index 46fe7a4..761e8cd 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,43 +1,43 @@ #!/usr/bin/env node -import{createRequire as nF}from"node:module";var pF=Object.create;var{getPrototypeOf:cF,defineProperty:$u,getOwnPropertyNames:lF}=Object;var dF=Object.prototype.hasOwnProperty;var UD=(D,u,F)=>{F=D!=null?pF(cF(D)):{};let E=u||!D||!D.__esModule?$u(F,"default",{value:D,enumerable:!0}):F;for(let C of lF(D))if(!dF.call(E,C))$u(E,C,{get:()=>D[C],enumerable:!0});return E};var V=(D,u)=>()=>(u||D((u={exports:{}}).exports,u),u.exports);var i=nF(import.meta.url);var Ru=V((e3,Ou)=>{class Lu{constructor(D,u,F){this.etaBufferLength=D||100,this.valueBuffer=[F],this.timeBuffer=[u],this.eta="0"}update(D,u,F){this.valueBuffer.push(u),this.timeBuffer.push(D),this.calculate(F-u)}getTime(){return this.eta}calculate(D){let u=this.valueBuffer.length,F=Math.min(this.etaBufferLength,u),E=this.valueBuffer[u-1]-this.valueBuffer[u-F],C=this.timeBuffer[u-1]-this.timeBuffer[u-F],A=E/C;this.valueBuffer=this.valueBuffer.slice(-this.etaBufferLength),this.timeBuffer=this.timeBuffer.slice(-this.etaBufferLength);let B=Math.ceil(D/A/1000);if(isNaN(B))this.eta="NULL";else if(!isFinite(B))this.eta="INF";else if(B>1e7)this.eta="INF";else if(B<0)this.eta=0;else this.eta=B}}Ou.exports=Lu});var hD=V((D2,Tu)=>{var d=i("readline");class ju{constructor(D){this.stream=D,this.linewrap=!0,this.dy=0}cursorSave(){if(!this.stream.isTTY)return;this.stream.write("\x1B7")}cursorRestore(){if(!this.stream.isTTY)return;this.stream.write("\x1B8")}cursor(D){if(!this.stream.isTTY)return;if(D)this.stream.write("\x1B[?25h");else this.stream.write("\x1B[?25l")}cursorTo(D=null,u=null){if(!this.stream.isTTY)return;d.cursorTo(this.stream,D,u)}cursorRelative(D=null,u=null){if(!this.stream.isTTY)return;this.dy=this.dy+u,d.moveCursor(this.stream,D,u)}cursorRelativeReset(){if(!this.stream.isTTY)return;d.moveCursor(this.stream,0,-this.dy),d.cursorTo(this.stream,0,null),this.dy=0}clearRight(){if(!this.stream.isTTY)return;d.clearLine(this.stream,1)}clearLine(){if(!this.stream.isTTY)return;d.clearLine(this.stream,0)}clearBottom(){if(!this.stream.isTTY)return;d.clearScreenDown(this.stream)}newline(){this.stream.write(` -`),this.dy++}write(D,u=!1){if(this.linewrap===!0&&u===!1)this.stream.write(D.substr(0,this.getWidth()));else this.stream.write(D)}lineWrapping(D){if(!this.stream.isTTY)return;if(this.linewrap=D,D)this.stream.write("\x1B[?7h");else this.stream.write("\x1B[?7l")}isTTY(){return this.stream.isTTY===!0}getWidth(){return this.stream.columns||(this.stream.isTTY?80:200)}}Tu.exports=ju});var yu=V((u2,wu)=>{wu.exports=({onlyFirst:D=!1}={})=>{let u=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(u,D?void 0:"g")}});var bu=V((F2,Su)=>{var W8=yu();Su.exports=(D)=>typeof D==="string"?D.replace(W8(),""):D});var Pu=V((E2,fD)=>{var vu=(D)=>{if(Number.isNaN(D))return!1;if(D>=4352&&(D<=4447||D===9001||D===9002||11904<=D&&D<=12871&&D!==12351||12880<=D&&D<=19903||19968<=D&&D<=42182||43360<=D&&D<=43388||44032<=D&&D<=55203||63744<=D&&D<=64255||65040<=D&&D<=65049||65072<=D&&D<=65131||65281<=D&&D<=65376||65504<=D&&D<=65510||110592<=D&&D<=110593||127488<=D&&D<=127569||131072<=D&&D<=262141))return!0;return!1};fD.exports=vu;fD.exports.default=vu});var fu=V((C2,hu)=>{hu.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var mu=V((B2,gD)=>{var N8=bu(),k8=Pu(),Q8=fu(),gu=(D)=>{if(typeof D!=="string"||D.length===0)return 0;if(D=N8(D),D.length===0)return 0;D=D.replace(Q8()," ");let u=0;for(let F=0;F=127&&E<=159)continue;if(E>=768&&E<=879)continue;if(E>65535)F++;u+=k8(E)?2:1}return u};gD.exports=gu;gD.exports.default=gu});var mD=V((A2,pu)=>{pu.exports=function(u,F,E){if(F.autopadding!==!0)return u;function C(A,B){return(F.autopaddingChar+A).slice(-B)}switch(E){case"percentage":return C(u,3);default:return u}}});var pD=V((Z2,cu)=>{cu.exports=function(u,F){let E=Math.round(u*F.barsize),C=F.barsize-E;return F.barCompleteString.substr(0,E)+F.barGlue+F.barIncompleteString.substr(0,C)}});var cD=V(($2,lu)=>{lu.exports=function(u,F,E){function C(B){if(E)return E*Math.round(B/E);else return B}function A(B){return(F.autopaddingChar+B).slice(-2)}if(u>3600)return A(Math.floor(u/3600))+"h"+A(C(u%3600/60))+"m";else if(u>60)return A(Math.floor(u/60))+"m"+A(C(u%60))+"s";else if(u>10)return A(C(u))+"s";else return A(u)+"s"}});var lD=V((J2,du)=>{var _8=mu(),z8=mD(),q8=pD(),I8=cD();du.exports=function(u,F,E){let C=u.format,A=u.formatTime||I8,B=u.formatValue||z8,$=u.formatBar||q8,K=Math.floor(F.progress*100)+"",X=F.stopTime||Date.now(),U=Math.round((X-F.startTime)/1000),Y=Object.assign({},E,{bar:$(F.progress,u),percentage:B(K,u,"percentage"),total:B(F.total,u,"total"),value:B(F.value,u,"value"),eta:B(F.eta,u,"eta"),eta_formatted:A(F.eta,u,5),duration:B(U,u,"duration"),duration_formatted:A(U,u,1)});C=C.replace(/\{(\w+)\}/g,function(J,_){if(typeof Y[_]<"u")return Y[_];return J});let Z=Math.max(0,F.maxWidth-_8(C)-2),W=Math.floor(Z/2);switch(u.align){case"right":C=Z>0?" ".repeat(Z)+C:C;break;case"center":C=W>0?" ".repeat(W)+C:C;break;case"left":default:break}return C}});var qD=V((K2,nu)=>{function q(D,u){if(typeof D>"u"||D===null)return u;else return D}nu.exports={parse:function(u,F){let E={},C=Object.assign({},F,u);return E.throttleTime=1000/q(C.fps,10),E.stream=q(C.stream,process.stderr),E.terminal=q(C.terminal,null),E.clearOnComplete=q(C.clearOnComplete,!1),E.stopOnComplete=q(C.stopOnComplete,!1),E.barsize=q(C.barsize,40),E.align=q(C.align,"left"),E.hideCursor=q(C.hideCursor,!1),E.linewrap=q(C.linewrap,!1),E.barGlue=q(C.barGlue,""),E.barCompleteChar=q(C.barCompleteChar,"="),E.barIncompleteChar=q(C.barIncompleteChar,"-"),E.format=q(C.format,"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}"),E.formatTime=q(C.formatTime,null),E.formatValue=q(C.formatValue,null),E.formatBar=q(C.formatBar,null),E.etaBufferLength=q(C.etaBuffer,10),E.etaAsynchronousUpdate=q(C.etaAsynchronousUpdate,!1),E.progressCalculationRelative=q(C.progressCalculationRelative,!1),E.synchronousUpdate=q(C.synchronousUpdate,!0),E.noTTYOutput=q(C.noTTYOutput,!1),E.notTTYSchedule=q(C.notTTYSchedule,2000),E.emptyOnZero=q(C.emptyOnZero,!1),E.forceRedraw=q(C.forceRedraw,!1),E.autopadding=q(C.autopadding,!1),E.gracefulExit=q(C.gracefulExit,!1),E},assignDerivedOptions:function(u){return u.barCompleteString=u.barCompleteChar.repeat(u.barsize+1),u.barIncompleteString=u.barIncompleteChar.repeat(u.barsize+1),u.autopaddingChar=u.autopadding?q(u.autopaddingChar," "):"",u}}});var dD=V((X2,au)=>{var su=Ru(),V8=hD(),H8=lD(),x8=qD(),M8=i("events");au.exports=class extends M8{constructor(u){super();this.options=x8.assignDerivedOptions(u),this.terminal=this.options.terminal?this.options.terminal:new V8(this.options.stream),this.value=0,this.startValue=0,this.total=100,this.lastDrawnString=null,this.startTime=null,this.stopTime=null,this.lastRedraw=Date.now(),this.eta=new su(this.options.etaBufferLength,0,0),this.payload={},this.isActive=!1,this.formatter=typeof this.options.format==="function"?this.options.format:H8}render(u=!1){let F={progress:this.getProgress(),eta:this.eta.getTime(),startTime:this.startTime,stopTime:this.stopTime,total:this.total,value:this.value,maxWidth:this.terminal.getWidth()};if(this.options.etaAsynchronousUpdate)this.updateETA();let E=this.formatter(this.options,F,this.payload);if(u||this.options.forceRedraw||this.options.noTTYOutput&&!this.terminal.isTTY()||this.lastDrawnString!=E)this.emit("redraw-pre"),this.terminal.cursorTo(0,null),this.terminal.write(E),this.terminal.clearRight(),this.lastDrawnString=E,this.lastRedraw=Date.now(),this.emit("redraw-post")}start(u,F,E){this.value=F||0,this.total=typeof u<"u"&&u>=0?u:100,this.startValue=F||0,this.payload=E||{},this.startTime=Date.now(),this.stopTime=null,this.lastDrawnString="",this.eta=new su(this.options.etaBufferLength,this.startTime,this.value),this.isActive=!0,this.emit("start",u,F)}stop(){this.isActive=!1,this.stopTime=Date.now(),this.emit("stop",this.total,this.value)}update(u,F={}){if(typeof u==="number")this.value=u,this.eta.update(Date.now(),u,this.total);let E=(typeof u==="object"?u:F)||{};this.emit("update",this.total,this.value);for(let C in E)this.payload[C]=E[C];if(this.value>=this.getTotal()&&this.options.stopOnComplete)this.stop()}getProgress(){let u=this.value/this.total;if(this.options.progressCalculationRelative)u=(this.value-this.startValue)/(this.total-this.startValue);if(isNaN(u))u=this.options&&this.options.emptyOnZero?0:1;return u=Math.min(Math.max(u,0),1),u}increment(u=1,F={}){if(typeof u==="object")this.update(this.value+1,u);else this.update(this.value+u,F)}getTotal(){return this.total}setTotal(u){if(typeof u<"u"&&u>=0)this.total=u}updateETA(){this.eta.update(Date.now(),this.value,this.total)}}});var ru=V((Y2,iu)=>{var L8=dD(),O8=qD();iu.exports=class extends L8{constructor(u,F){super(O8.parse(u,F));if(this.timer=null,this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.options.synchronousUpdate=!1;this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.sigintCallback=null}render(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(super.render(),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline();this.timer=setTimeout(this.render.bind(this),this.schedulingRate)}update(u,F){if(!this.timer)return;if(super.update(u,F),this.options.synchronousUpdate&&this.lastRedraw+this.options.throttleTime*2{var R8=hD(),j8=dD(),T8=qD(),w8=i("events");ou.exports=class extends w8{constructor(u,F){super();this.bars=[],this.options=T8.parse(u,F),this.options.synchronousUpdate=!1,this.terminal=this.options.terminal?this.options.terminal:new R8(this.options.stream),this.timer=null,this.isActive=!1,this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.loggingBuffer=[],this.sigintCallback=null}create(u,F,E,C={}){let A=new j8(Object.assign({},this.options,{terminal:this.terminal},C));if(this.bars.push(A),this.options.noTTYOutput===!1&&this.terminal.isTTY()===!1)return A;if(this.sigintCallback===null&&this.options.gracefulExit)this.sigintCallback=this.stop.bind(this),process.once("SIGINT",this.sigintCallback),process.once("SIGTERM",this.sigintCallback);if(!this.isActive){if(this.options.hideCursor===!0)this.terminal.cursor(!1);if(this.options.linewrap===!1)this.terminal.lineWrapping(!1);this.timer=setTimeout(this.update.bind(this),this.schedulingRate)}return this.isActive=!0,A.start(u,F,E),this.emit("start"),A}remove(u){let F=this.bars.indexOf(u);if(F<0)return!1;return this.bars.splice(F,1),this.update(),this.terminal.newline(),this.terminal.clearBottom(),!0}update(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.emit("update-pre"),this.terminal.cursorRelativeReset(),this.emit("redraw-pre"),this.loggingBuffer.length>0){this.terminal.clearLine();while(this.loggingBuffer.length>0)this.terminal.write(this.loggingBuffer.shift(),!0)}for(let u=0;u0)this.terminal.newline();this.bars[u].render()}if(this.emit("redraw-post"),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline(),this.terminal.newline();if(this.timer=setTimeout(this.update.bind(this),this.schedulingRate),this.emit("update-post"),this.options.stopOnComplete&&!this.bars.find((u)=>u.isActive))this.stop()}stop(){if(clearTimeout(this.timer),this.timer=null,this.sigintCallback)process.removeListener("SIGINT",this.sigintCallback),process.removeListener("SIGTERM",this.sigintCallback),this.sigintCallback=null;if(this.isActive=!1,this.options.hideCursor===!0)this.terminal.cursor(!0);if(this.options.linewrap===!1)this.terminal.lineWrapping(!0);if(this.terminal.cursorRelativeReset(),this.emit("stop-pre-clear"),this.options.clearOnComplete)this.terminal.clearBottom();else{for(let u=0;u0)this.terminal.newline();this.bars[u].render(),this.bars[u].stop()}this.terminal.newline()}this.emit("stop")}log(u){this.loggingBuffer.push(u)}}});var DF=V((U2,eu)=>{eu.exports={format:"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"=",barIncompleteChar:"-"}});var FF=V((W2,uF)=>{uF.exports={format:" {bar} {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var CF=V((N2,EF)=>{EF.exports={format:" \x1B[90m{bar}\x1B[0m {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var AF=V((k2,BF)=>{BF.exports={format:" {bar}■ {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"■",barIncompleteChar:" "}});var $F=V((Q2,ZF)=>{var y8=DF(),S8=FF(),b8=CF(),v8=AF();ZF.exports={legacy:y8,shades_classic:S8,shades_grey:b8,rect:v8}});var XF=V((_2,KF)=>{var JF=ru(),P8=tu(),h8=$F(),f8=lD(),g8=mD(),m8=pD(),p8=cD();KF.exports={Bar:JF,SingleBar:JF,MultiBar:P8,Presets:h8,Format:{Formatter:f8,BarFormat:m8,ValueFormat:g8,TimeFormat:p8}}});import{join as zD,basename as Hu,extname as xu}from"node:path";import{randomUUID as X8}from"node:crypto";import{rm as Mu}from"node:fs/promises";import{spawn as g}from"node:child_process";import{appendFile as sF}from"node:fs/promises";var RD=null;function jD(D){RD=D}async function f(D){if(RD)try{await sF(RD,D,"utf-8")}catch(u){}}async function r(){return new Promise((D)=>{let u=g("ffmpeg",["-version"]);u.on("error",()=>D(!1)),u.on("close",(F)=>D(F===0))})}async function o(){return new Promise((D)=>{let u=g("MP4Box",["-version"]);u.on("error",()=>D(!1)),u.on("close",(F)=>D(F===0))})}async function t(){let D=await new Promise((C)=>{let A=g("ffmpeg",["-hide_banner","-encoders"]),B="";A.stdout.on("data",($)=>{B+=$.toString()}),A.on("error",()=>C("")),A.on("close",()=>C(B))}),u=(C)=>D.includes(C),F=[],E=[{acc:"nvenc",h264:u("h264_nvenc")?"h264_nvenc":void 0,av1:u("av1_nvenc")?"av1_nvenc":void 0},{acc:"qsv",h264:u("h264_qsv")?"h264_qsv":void 0,av1:u("av1_qsv")?"av1_qsv":void 0},{acc:"amf",h264:u("h264_amf")?"h264_amf":void 0,av1:u("av1_amf")?"av1_amf":void 0},{acc:"vaapi",h264:u("h264_vaapi")?"h264_vaapi":void 0,av1:u("av1_vaapi")?"av1_vaapi":void 0},{acc:"videotoolbox",h264:u("h264_videotoolbox")?"h264_videotoolbox":void 0,av1:u("av1_videotoolbox")?"av1_videotoolbox":void 0},{acc:"v4l2",h264:u("h264_v4l2m2m")?"h264_v4l2m2m":void 0,av1:u("av1_v4l2m2m")?"av1_v4l2m2m":void 0}];for(let C of E)if(C.h264||C.av1)F.push({accelerator:C.acc,h264Encoder:C.h264,av1Encoder:C.av1});return F}async function e(){let u=(await new Promise((C)=>{let A=g("ffmpeg",["-hide_banner","-hwaccels"]),B="";A.stdout.on("data",($)=>B+=$.toString()),A.on("error",()=>C("")),A.on("close",()=>C(B))})).split(` -`).map((C)=>C.trim()).filter(Boolean),F=[],E={cuda:"nvenc",qsv:"qsv",vaapi:"vaapi",videotoolbox:"videotoolbox",v4l2m2m:"v4l2",dxva2:"amf"};for(let C of u){let A=E[C];if(A)F.push({accelerator:A})}return F}async function WD(D){let u=["-v","error","-f","lavfi","-i","testsrc=size=320x240:rate=1","-frames:v","1","-an","-c:v",D,"-f","null","-"];return new Promise((F)=>{let E=g("ffmpeg",u);E.on("error",()=>F(!1)),E.on("close",(C)=>F(C===0))})}async function ND(D,u){let F=["-v","error"];if(D==="nvenc")F.push("-hwaccel","cuda","-hwaccel_output_format","cuda");else if(D==="qsv")F.push("-hwaccel","qsv");else if(D==="vaapi")F.push("-hwaccel","vaapi","-vaapi_device","/dev/dri/renderD128");else if(D==="videotoolbox")F.push("-hwaccel","videotoolbox");else if(D==="v4l2")F.push("-hwaccel","v4l2m2m");else if(D==="amf")return!1;return F.push("-i",u,"-frames:v","1","-f","null","-"),new Promise((E)=>{let C=g("ffmpeg",F);C.on("error",()=>E(!1)),C.on("close",(A)=>E(A===0))})}async function c(D,u,F){let C=` +import{createRequire as dF}from"node:module";var mF=Object.create;var{getPrototypeOf:cF,defineProperty:Ju,getOwnPropertyNames:lF}=Object;var pF=Object.prototype.hasOwnProperty;var XD=(D,u,F)=>{F=D!=null?mF(cF(D)):{};let E=u||!D||!D.__esModule?Ju(F,"default",{value:D,enumerable:!0}):F;for(let C of lF(D))if(!pF.call(E,C))Ju(E,C,{get:()=>D[C],enumerable:!0});return E};var H=(D,u)=>()=>(u||D((u={exports:{}}).exports,u),u.exports);var n=dF(import.meta.url);var ju=H((D2,Ru)=>{class Lu{constructor(D,u,F){this.etaBufferLength=D||100,this.valueBuffer=[F],this.timeBuffer=[u],this.eta="0"}update(D,u,F){this.valueBuffer.push(u),this.timeBuffer.push(D),this.calculate(F-u)}getTime(){return this.eta}calculate(D){let u=this.valueBuffer.length,F=Math.min(this.etaBufferLength,u),E=this.valueBuffer[u-1]-this.valueBuffer[u-F],C=this.timeBuffer[u-1]-this.timeBuffer[u-F],A=E/C;this.valueBuffer=this.valueBuffer.slice(-this.etaBufferLength),this.timeBuffer=this.timeBuffer.slice(-this.etaBufferLength);let B=Math.ceil(D/A/1000);if(isNaN(B))this.eta="NULL";else if(!isFinite(B))this.eta="INF";else if(B>1e7)this.eta="INF";else if(B<0)this.eta=0;else this.eta=B}}Ru.exports=Lu});var PD=H((u2,wu)=>{var p=n("readline");class Tu{constructor(D){this.stream=D,this.linewrap=!0,this.dy=0}cursorSave(){if(!this.stream.isTTY)return;this.stream.write("\x1B7")}cursorRestore(){if(!this.stream.isTTY)return;this.stream.write("\x1B8")}cursor(D){if(!this.stream.isTTY)return;if(D)this.stream.write("\x1B[?25h");else this.stream.write("\x1B[?25l")}cursorTo(D=null,u=null){if(!this.stream.isTTY)return;p.cursorTo(this.stream,D,u)}cursorRelative(D=null,u=null){if(!this.stream.isTTY)return;this.dy=this.dy+u,p.moveCursor(this.stream,D,u)}cursorRelativeReset(){if(!this.stream.isTTY)return;p.moveCursor(this.stream,0,-this.dy),p.cursorTo(this.stream,0,null),this.dy=0}clearRight(){if(!this.stream.isTTY)return;p.clearLine(this.stream,1)}clearLine(){if(!this.stream.isTTY)return;p.clearLine(this.stream,0)}clearBottom(){if(!this.stream.isTTY)return;p.clearScreenDown(this.stream)}newline(){this.stream.write(` +`),this.dy++}write(D,u=!1){if(this.linewrap===!0&&u===!1)this.stream.write(D.substr(0,this.getWidth()));else this.stream.write(D)}lineWrapping(D){if(!this.stream.isTTY)return;if(this.linewrap=D,D)this.stream.write("\x1B[?7h");else this.stream.write("\x1B[?7l")}isTTY(){return this.stream.isTTY===!0}getWidth(){return this.stream.columns||(this.stream.isTTY?80:200)}}wu.exports=Tu});var Su=H((F2,yu)=>{yu.exports=({onlyFirst:D=!1}={})=>{let u=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(u,D?void 0:"g")}});var vu=H((E2,bu)=>{var U8=Su();bu.exports=(D)=>typeof D==="string"?D.replace(U8(),""):D});var hu=H((C2,hD)=>{var Pu=(D)=>{if(Number.isNaN(D))return!1;if(D>=4352&&(D<=4447||D===9001||D===9002||11904<=D&&D<=12871&&D!==12351||12880<=D&&D<=19903||19968<=D&&D<=42182||43360<=D&&D<=43388||44032<=D&&D<=55203||63744<=D&&D<=64255||65040<=D&&D<=65049||65072<=D&&D<=65131||65281<=D&&D<=65376||65504<=D&&D<=65510||110592<=D&&D<=110593||127488<=D&&D<=127569||131072<=D&&D<=262141))return!0;return!1};hD.exports=Pu;hD.exports.default=Pu});var gu=H((B2,fu)=>{fu.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var cu=H((A2,fD)=>{var W8=vu(),N8=hu(),k8=gu(),mu=(D)=>{if(typeof D!=="string"||D.length===0)return 0;if(D=W8(D),D.length===0)return 0;D=D.replace(k8()," ");let u=0;for(let F=0;F=127&&E<=159)continue;if(E>=768&&E<=879)continue;if(E>65535)F++;u+=N8(E)?2:1}return u};fD.exports=mu;fD.exports.default=mu});var gD=H((Z2,lu)=>{lu.exports=function(u,F,E){if(F.autopadding!==!0)return u;function C(A,B){return(F.autopaddingChar+A).slice(-B)}switch(E){case"percentage":return C(u,3);default:return u}}});var mD=H(($2,pu)=>{pu.exports=function(u,F){let E=Math.round(u*F.barsize),C=F.barsize-E;return F.barCompleteString.substr(0,E)+F.barGlue+F.barIncompleteString.substr(0,C)}});var cD=H((J2,du)=>{du.exports=function(u,F,E){function C(B){if(E)return E*Math.round(B/E);else return B}function A(B){return(F.autopaddingChar+B).slice(-2)}if(u>3600)return A(Math.floor(u/3600))+"h"+A(C(u%3600/60))+"m";else if(u>60)return A(Math.floor(u/60))+"m"+A(C(u%60))+"s";else if(u>10)return A(C(u))+"s";else return A(u)+"s"}});var lD=H((K2,nu)=>{var Q8=cu(),_8=gD(),z8=mD(),q8=cD();nu.exports=function(u,F,E){let C=u.format,A=u.formatTime||q8,B=u.formatValue||_8,$=u.formatBar||z8,K=Math.floor(F.progress*100)+"",X=F.stopTime||Date.now(),U=Math.round((X-F.startTime)/1000),Y=Object.assign({},E,{bar:$(F.progress,u),percentage:B(K,u,"percentage"),total:B(F.total,u,"total"),value:B(F.value,u,"value"),eta:B(F.eta,u,"eta"),eta_formatted:A(F.eta,u,5),duration:B(U,u,"duration"),duration_formatted:A(U,u,1)});C=C.replace(/\{(\w+)\}/g,function(J,Q){if(typeof Y[Q]<"u")return Y[Q];return J});let Z=Math.max(0,F.maxWidth-Q8(C)-2),W=Math.floor(Z/2);switch(u.align){case"right":C=Z>0?" ".repeat(Z)+C:C;break;case"center":C=W>0?" ".repeat(W)+C:C;break;case"left":default:break}return C}});var QD=H((X2,su)=>{function q(D,u){if(typeof D>"u"||D===null)return u;else return D}su.exports={parse:function(u,F){let E={},C=Object.assign({},F,u);return E.throttleTime=1000/q(C.fps,10),E.stream=q(C.stream,process.stderr),E.terminal=q(C.terminal,null),E.clearOnComplete=q(C.clearOnComplete,!1),E.stopOnComplete=q(C.stopOnComplete,!1),E.barsize=q(C.barsize,40),E.align=q(C.align,"left"),E.hideCursor=q(C.hideCursor,!1),E.linewrap=q(C.linewrap,!1),E.barGlue=q(C.barGlue,""),E.barCompleteChar=q(C.barCompleteChar,"="),E.barIncompleteChar=q(C.barIncompleteChar,"-"),E.format=q(C.format,"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}"),E.formatTime=q(C.formatTime,null),E.formatValue=q(C.formatValue,null),E.formatBar=q(C.formatBar,null),E.etaBufferLength=q(C.etaBuffer,10),E.etaAsynchronousUpdate=q(C.etaAsynchronousUpdate,!1),E.progressCalculationRelative=q(C.progressCalculationRelative,!1),E.synchronousUpdate=q(C.synchronousUpdate,!0),E.noTTYOutput=q(C.noTTYOutput,!1),E.notTTYSchedule=q(C.notTTYSchedule,2000),E.emptyOnZero=q(C.emptyOnZero,!1),E.forceRedraw=q(C.forceRedraw,!1),E.autopadding=q(C.autopadding,!1),E.gracefulExit=q(C.gracefulExit,!1),E},assignDerivedOptions:function(u){return u.barCompleteString=u.barCompleteChar.repeat(u.barsize+1),u.barIncompleteString=u.barIncompleteChar.repeat(u.barsize+1),u.autopaddingChar=u.autopadding?q(u.autopaddingChar," "):"",u}}});var pD=H((Y2,iu)=>{var au=ju(),I8=PD(),H8=lD(),V8=QD(),x8=n("events");iu.exports=class extends x8{constructor(u){super();this.options=V8.assignDerivedOptions(u),this.terminal=this.options.terminal?this.options.terminal:new I8(this.options.stream),this.value=0,this.startValue=0,this.total=100,this.lastDrawnString=null,this.startTime=null,this.stopTime=null,this.lastRedraw=Date.now(),this.eta=new au(this.options.etaBufferLength,0,0),this.payload={},this.isActive=!1,this.formatter=typeof this.options.format==="function"?this.options.format:H8}render(u=!1){let F={progress:this.getProgress(),eta:this.eta.getTime(),startTime:this.startTime,stopTime:this.stopTime,total:this.total,value:this.value,maxWidth:this.terminal.getWidth()};if(this.options.etaAsynchronousUpdate)this.updateETA();let E=this.formatter(this.options,F,this.payload);if(u||this.options.forceRedraw||this.options.noTTYOutput&&!this.terminal.isTTY()||this.lastDrawnString!=E)this.emit("redraw-pre"),this.terminal.cursorTo(0,null),this.terminal.write(E),this.terminal.clearRight(),this.lastDrawnString=E,this.lastRedraw=Date.now(),this.emit("redraw-post")}start(u,F,E){this.value=F||0,this.total=typeof u<"u"&&u>=0?u:100,this.startValue=F||0,this.payload=E||{},this.startTime=Date.now(),this.stopTime=null,this.lastDrawnString="",this.eta=new au(this.options.etaBufferLength,this.startTime,this.value),this.isActive=!0,this.emit("start",u,F)}stop(){this.isActive=!1,this.stopTime=Date.now(),this.emit("stop",this.total,this.value)}update(u,F={}){if(typeof u==="number")this.value=u,this.eta.update(Date.now(),u,this.total);let E=(typeof u==="object"?u:F)||{};this.emit("update",this.total,this.value);for(let C in E)this.payload[C]=E[C];if(this.value>=this.getTotal()&&this.options.stopOnComplete)this.stop()}getProgress(){let u=this.value/this.total;if(this.options.progressCalculationRelative)u=(this.value-this.startValue)/(this.total-this.startValue);if(isNaN(u))u=this.options&&this.options.emptyOnZero?0:1;return u=Math.min(Math.max(u,0),1),u}increment(u=1,F={}){if(typeof u==="object")this.update(this.value+1,u);else this.update(this.value+u,F)}getTotal(){return this.total}setTotal(u){if(typeof u<"u"&&u>=0)this.total=u}updateETA(){this.eta.update(Date.now(),this.value,this.total)}}});var ou=H((G2,ru)=>{var M8=pD(),O8=QD();ru.exports=class extends M8{constructor(u,F){super(O8.parse(u,F));if(this.timer=null,this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.options.synchronousUpdate=!1;this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.sigintCallback=null}render(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(super.render(),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline();this.timer=setTimeout(this.render.bind(this),this.schedulingRate)}update(u,F){if(!this.timer)return;if(super.update(u,F),this.options.synchronousUpdate&&this.lastRedraw+this.options.throttleTime*2{var L8=PD(),R8=pD(),j8=QD(),T8=n("events");tu.exports=class extends T8{constructor(u,F){super();this.bars=[],this.options=j8.parse(u,F),this.options.synchronousUpdate=!1,this.terminal=this.options.terminal?this.options.terminal:new L8(this.options.stream),this.timer=null,this.isActive=!1,this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.loggingBuffer=[],this.sigintCallback=null}create(u,F,E,C={}){let A=new R8(Object.assign({},this.options,{terminal:this.terminal},C));if(this.bars.push(A),this.options.noTTYOutput===!1&&this.terminal.isTTY()===!1)return A;if(this.sigintCallback===null&&this.options.gracefulExit)this.sigintCallback=this.stop.bind(this),process.once("SIGINT",this.sigintCallback),process.once("SIGTERM",this.sigintCallback);if(!this.isActive){if(this.options.hideCursor===!0)this.terminal.cursor(!1);if(this.options.linewrap===!1)this.terminal.lineWrapping(!1);this.timer=setTimeout(this.update.bind(this),this.schedulingRate)}return this.isActive=!0,A.start(u,F,E),this.emit("start"),A}remove(u){let F=this.bars.indexOf(u);if(F<0)return!1;return this.bars.splice(F,1),this.update(),this.terminal.newline(),this.terminal.clearBottom(),!0}update(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.emit("update-pre"),this.terminal.cursorRelativeReset(),this.emit("redraw-pre"),this.loggingBuffer.length>0){this.terminal.clearLine();while(this.loggingBuffer.length>0)this.terminal.write(this.loggingBuffer.shift(),!0)}for(let u=0;u0)this.terminal.newline();this.bars[u].render()}if(this.emit("redraw-post"),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline(),this.terminal.newline();if(this.timer=setTimeout(this.update.bind(this),this.schedulingRate),this.emit("update-post"),this.options.stopOnComplete&&!this.bars.find((u)=>u.isActive))this.stop()}stop(){if(clearTimeout(this.timer),this.timer=null,this.sigintCallback)process.removeListener("SIGINT",this.sigintCallback),process.removeListener("SIGTERM",this.sigintCallback),this.sigintCallback=null;if(this.isActive=!1,this.options.hideCursor===!0)this.terminal.cursor(!0);if(this.options.linewrap===!1)this.terminal.lineWrapping(!0);if(this.terminal.cursorRelativeReset(),this.emit("stop-pre-clear"),this.options.clearOnComplete)this.terminal.clearBottom();else{for(let u=0;u0)this.terminal.newline();this.bars[u].render(),this.bars[u].stop()}this.terminal.newline()}this.emit("stop")}log(u){this.loggingBuffer.push(u)}}});var uF=H((W2,DF)=>{DF.exports={format:"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"=",barIncompleteChar:"-"}});var EF=H((N2,FF)=>{FF.exports={format:" {bar} {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var BF=H((k2,CF)=>{CF.exports={format:" \x1B[90m{bar}\x1B[0m {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var ZF=H((Q2,AF)=>{AF.exports={format:" {bar}■ {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"■",barIncompleteChar:" "}});var JF=H((_2,$F)=>{var w8=uF(),y8=EF(),S8=BF(),b8=ZF();$F.exports={legacy:w8,shades_classic:y8,shades_grey:S8,rect:b8}});var YF=H((z2,XF)=>{var KF=ou(),v8=eu(),P8=JF(),h8=lD(),f8=gD(),g8=mD(),m8=cD();XF.exports={Bar:KF,SingleBar:KF,MultiBar:v8,Presets:P8,Format:{Formatter:h8,BarFormat:g8,ValueFormat:f8,TimeFormat:m8}}});import{join as kD,basename as xu,extname as Mu}from"node:path";import{randomUUID as K8}from"node:crypto";import{rm as Ou}from"node:fs/promises";import{spawn as f}from"node:child_process";import{appendFile as nF}from"node:fs/promises";var LD=null;function RD(D){LD=D}async function h(D){if(LD)try{await nF(LD,D,"utf-8")}catch(u){}}async function s(){return new Promise((D)=>{let u=f("ffmpeg",["-version"]);u.on("error",()=>D(!1)),u.on("close",(F)=>D(F===0))})}async function a(){return new Promise((D)=>{let u=f("MP4Box",["-version"]);u.on("error",()=>D(!1)),u.on("close",(F)=>D(F===0))})}async function i(){let D=await new Promise((C)=>{let A=f("ffmpeg",["-hide_banner","-encoders"]),B="";A.stdout.on("data",($)=>{B+=$.toString()}),A.on("error",()=>C("")),A.on("close",()=>C(B))}),u=(C)=>D.includes(C),F=[],E=[{acc:"nvenc",h264:u("h264_nvenc")?"h264_nvenc":void 0,av1:u("av1_nvenc")?"av1_nvenc":void 0},{acc:"qsv",h264:u("h264_qsv")?"h264_qsv":void 0,av1:u("av1_qsv")?"av1_qsv":void 0},{acc:"amf",h264:u("h264_amf")?"h264_amf":void 0,av1:u("av1_amf")?"av1_amf":void 0},{acc:"vaapi",h264:u("h264_vaapi")?"h264_vaapi":void 0,av1:u("av1_vaapi")?"av1_vaapi":void 0},{acc:"videotoolbox",h264:u("h264_videotoolbox")?"h264_videotoolbox":void 0,av1:u("av1_videotoolbox")?"av1_videotoolbox":void 0},{acc:"v4l2",h264:u("h264_v4l2m2m")?"h264_v4l2m2m":void 0,av1:u("av1_v4l2m2m")?"av1_v4l2m2m":void 0}];for(let C of E)if(C.h264||C.av1)F.push({accelerator:C.acc,h264Encoder:C.h264,av1Encoder:C.av1});return F}async function r(){let u=(await new Promise((C)=>{let A=f("ffmpeg",["-hide_banner","-hwaccels"]),B="";A.stdout.on("data",($)=>B+=$.toString()),A.on("error",()=>C("")),A.on("close",()=>C(B))})).split(` +`).map((C)=>C.trim()).filter(Boolean),F=[],E={cuda:"nvenc",qsv:"qsv",vaapi:"vaapi",videotoolbox:"videotoolbox",v4l2m2m:"v4l2",dxva2:"amf"};for(let C of u){let A=E[C];if(A)F.push({accelerator:A})}return F}async function YD(D){let u=["-v","error","-f","lavfi","-i","testsrc=size=320x240:rate=1","-frames:v","1","-an","-c:v",D,"-f","null","-"];return new Promise((F)=>{let E=f("ffmpeg",u);E.on("error",()=>F(!1)),E.on("close",(C)=>F(C===0))})}async function GD(D,u){let F=["-v","error"];if(D==="nvenc")F.push("-hwaccel","cuda","-hwaccel_output_format","cuda");else if(D==="qsv")F.push("-hwaccel","qsv");else if(D==="vaapi")F.push("-hwaccel","vaapi","-vaapi_device","/dev/dri/renderD128");else if(D==="videotoolbox")F.push("-hwaccel","videotoolbox");else if(D==="v4l2")F.push("-hwaccel","v4l2m2m");else if(D==="amf")return!1;return F.push("-i",u,"-frames:v","1","-f","null","-"),new Promise((E)=>{let C=f("ffmpeg",F);C.on("error",()=>E(!1)),C.on("close",(A)=>E(A===0))})}async function c(D,u,F){let C=` === FFmpeg Command [${new Date().toISOString()}] === ffmpeg ${D.join(" ")} -`;return await f(C),new Promise((A,B)=>{let $=g("ffmpeg",D),K="";$.stderr.on("data",(X)=>{let U=X.toString();if(K+=U,u&&F){let Y=U.match(/time=(\d{2}):(\d{2}):(\d{2}\.\d{2})/);if(Y){let Z=parseInt(Y[1]),W=parseInt(Y[2]),J=parseFloat(Y[3]),_=Z*3600+W*60+J,G=Math.min(100,_/F*100);u(G)}}}),$.on("error",(X)=>{f(`ERROR: ${X.message} +`;return await h(C),new Promise((A,B)=>{let $=f("ffmpeg",D),K="";$.stderr.on("data",(X)=>{let U=X.toString();if(K+=U,u&&F){let Y=U.match(/time=(\d{2}):(\d{2}):(\d{2}\.\d{2})/);if(Y){let Z=parseInt(Y[1]),W=parseInt(Y[2]),J=parseFloat(Y[3]),Q=Z*3600+W*60+J,G=Math.min(100,Q/F*100);u(G)}}}),$.on("error",(X)=>{h(`ERROR: ${X.message} `),B(Error(`FFmpeg error: ${X.message}`))}),$.on("close",(X)=>{if(X===0){let Y=K.split(` `).filter((Z)=>Z.trim()).slice(-10).join(` -`);f(`SUCCESS: Exit code ${X} +`);h(`SUCCESS: Exit code ${X} --- Last 10 lines of output --- ${Y} -`),A()}else f(`FAILED: Exit code ${X} +`),A()}else h(`FAILED: Exit code ${X} --- Full error output --- ${K} `),B(Error(`FFmpeg failed with exit code ${X} -${K}`))})})}async function TD(D){let F=` +${K}`))})})}async function jD(D){let F=` === MP4Box Command [${new Date().toISOString()}] === MP4Box ${D.join(" ")} -`;return await f(F),new Promise((E,C)=>{let A=g("MP4Box",D),B="",$="";A.stdout.on("data",(K)=>{B+=K.toString()}),A.stderr.on("data",(K)=>{$+=K.toString()}),A.on("error",(K)=>{f(`ERROR: ${K.message} +`;return await h(F),new Promise((E,C)=>{let A=f("MP4Box",D),B="",$="";A.stdout.on("data",(K)=>{B+=K.toString()}),A.stderr.on("data",(K)=>{$+=K.toString()}),A.on("error",(K)=>{h(`ERROR: ${K.message} `),C(Error(`MP4Box error: ${K.message}`))}),A.on("close",(K)=>{if(K===0){let Y=(B||$).split(` `).filter((Z)=>Z.trim()).slice(-10).join(` -`);f(`SUCCESS: Exit code ${K} +`);h(`SUCCESS: Exit code ${K} --- Last 10 lines of output --- ${Y} -`),E()}else{let X=$||B;f(`FAILED: Exit code ${K} +`),E()}else{let X=$||B;h(`FAILED: Exit code ${K} --- Full error output --- ${X} `),C(Error(`MP4Box failed with exit code ${K} -${X}`))}})})}import{spawn as aF}from"node:child_process";async function DD(D){return new Promise((u,F)=>{let E=aF("ffprobe",["-v","error","-show_entries","stream=width,height,duration,r_frame_rate,codec_name,codec_type,bit_rate","-show_entries","format=duration","-of","json",D]),C="";E.stdout.on("data",(A)=>{C+=A.toString()}),E.on("error",(A)=>{F(Error(`ffprobe error: ${A.message}`))}),E.on("close",(A)=>{if(A!==0){F(Error(`ffprobe failed with exit code ${A}`));return}try{let B=JSON.parse(C),$=B.streams.find((_)=>_.codec_type==="video"),K=B.streams.find((_)=>_.codec_type==="audio"),X=B.format;if(!$){F(Error("No video stream found in input file"));return}let U=30;if($.r_frame_rate){let[_,G]=$.r_frame_rate.split("/").map(Number);if(_&&G&&G!==0)U=_/G}let Y=parseFloat($.duration||X.duration||"0"),Z=B.streams.find((_)=>_.codec_type==="audio"&&_.bit_rate),W=Z?.bit_rate?Math.round(parseInt(Z.bit_rate)/1000):void 0,J=$.bit_rate?Math.round(parseInt($.bit_rate)/1000):void 0;u({width:$.width,height:$.height,duration:Y,fps:U,codec:$.codec_name,hasAudio:Boolean(K),audioBitrate:W,videoBitrate:J})}catch(B){F(Error(`Failed to parse ffprobe output: ${B}`))}})})}function kD(D,u=256){if(!D)return`${u}k`;let F=Math.min(D,u);if(F<=64)return"64k";if(F<=96)return"96k";if(F<=128)return"128k";if(F<=192)return"192k";return"256k"}function QD(D){let u=Math.floor(D/3600),F=Math.floor(D%3600/60),E=D%60;return`${String(u).padStart(2,"0")}:${String(F).padStart(2,"0")}:${E.toFixed(3).padStart(6,"0")}`}import{mkdir as iF,access as rF,constants as oF}from"node:fs/promises";async function l(D){try{await rF(D,oF.F_OK)}catch{await iF(D,{recursive:!0})}}function D8(D,u){let F=D*u;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 b(D,u,F=30,E){let C=D8(D,u),A=Math.round(D*u*F*C/1000);if(E&&A>E)A=E;return`${A}k`}var wD=[{name:"360p",width:640,height:360,videoBitrate:b(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:b(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:b(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:b(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:b(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:b(3840,2160,30),audioBitrate:"256k"}];function JD(D,u,F=30,E){let C=[],A=wD.filter((B)=>{return B.width<=D&&B.height<=u});for(let B of A)C.push({...B,videoBitrate:b(B.width,B.height,30,E),fps:30});return C}function u8(D,u,F){return{...D,name:`${D.name}-${u}`,videoBitrate:b(D.width,D.height,u,F),fps:u}}function Ju(D){let F=D.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!F)return null;let E=F[1]+"p",C=F[2]?parseInt(F[2]):30;return{resolution:E,fps:C}}function Ku(D,u=30,F){let E=wD.find((C)=>C.name===D);if(!E)return null;if(u===30)return{...E,videoBitrate:b(E.width,E.height,30,F),fps:30};return u8(E,u,F)}function F8(D,u,F,E){let C=Ju(D);if(!C)return{error:`Invalid profile format: ${D}. Use format like: 360, 720@60, 1080-60`};let A=Ku(C.resolution,C.fps);if(!A)return{error:`Unknown resolution: ${C.resolution}. Available: 360, 480, 720, 1080, 1440, 2160`};if(A.width>u||A.height>F)return{error:`Source resolution (${u}x${F}) is lower than ${D} (${A.width}x${A.height})`};let B=120,$=C.fps,K;if(C.fps>E)$=Math.min(E,B),K=`Requested ${C.fps} FPS in ${D}, but source is ${E} FPS. Using ${$} FPS instead`;else if(C.fps>B)$=B,K=`Requested ${C.fps} FPS in ${D} exceeds maximum ${B} FPS. Using ${$} FPS instead`;return K?{warning:K,adjustedFps:$}:{}}function _D(D,u,F,E,C){let A=[],B=[],$=[];for(let K of D){let X=F8(K,u,F,E);if(X.error){B.push(X.error);continue}if(X.warning)$.push(X.warning);let U=Ju(K);if(!U)continue;let Y=X.adjustedFps!==void 0?X.adjustedFps:U.fps,Z=Ku(U.resolution,Y,C);if(Z)A.push(Z)}return{profiles:A,errors:B,warnings:$}}import{join as m}from"node:path";import{readdir as E8,unlink as Xu,rmdir as C8,writeFile as Yu}from"node:fs/promises";async function Gu(D,u,F="00:00:00"){let E=m(u,"poster.jpg"),C=/^\d+(\.\d+)?$/.test(F)?F:F;return await c(["-ss",C,"-i",D,"-vframes","1","-q:v","2","-y",E]),E}async function Uu(D,u,F,E){let{width:C,height:A,interval:B,columns:$}=E,K=m(u,".thumbnails_temp");await l(K),await Yu(m(K,".keep"),"");let X=m(K,"thumb_%04d.jpg");await c(["-i",D,"-vf",`fps=1/${B},scale=${C}:${A}`,"-q:v","5",X]);let Y=(await E8(K)).filter((k)=>k.startsWith("thumb_")&&k.endsWith(".jpg")).sort();if(Y.length===0)throw Error("No thumbnails generated");let Z=Y.length,W=Math.ceil(Z/$),J=m(u,"thumbnails.jpg"),_=`tile=${$}x${W}`;await c(["-i",X,"-filter_complex",_,"-q:v","5",J]);let G=m(u,"thumbnails.vtt"),N=B8(Z,B,C,A,$,"thumbnails.jpg");await Yu(G,N);for(let k of Y)await Xu(m(K,k));return await Xu(m(K,".keep")),await C8(K),{spritePath:J,vttPath:G}}function B8(D,u,F,E,C,A){let B=`WEBVTT +${X}`))}})})}import{spawn as sF}from"node:child_process";async function o(D){return new Promise((u,F)=>{let E=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",D]),C="";E.stdout.on("data",(A)=>{C+=A.toString()}),E.on("error",(A)=>{F(Error(`ffprobe error: ${A.message}`))}),E.on("close",(A)=>{if(A!==0){F(Error(`ffprobe failed with exit code ${A}`));return}try{let B=JSON.parse(C),$=B.streams.find((Q)=>Q.codec_type==="video"),K=B.streams.find((Q)=>Q.codec_type==="audio"),X=B.format;if(!$){F(Error("No video stream found in input file"));return}let U=30;if($.r_frame_rate){let[Q,G]=$.r_frame_rate.split("/").map(Number);if(Q&&G&&G!==0)U=Q/G}let Y=parseFloat($.duration||X.duration||"0"),Z=B.streams.find((Q)=>Q.codec_type==="audio"&&Q.bit_rate),W=Z?.bit_rate?Math.round(parseInt(Z.bit_rate)/1000):void 0,J=$.bit_rate?Math.round(parseInt($.bit_rate)/1000):void 0;u({width:$.width,height:$.height,duration:Y,fps:U,codec:$.codec_name,hasAudio:Boolean(K),audioBitrate:W,videoBitrate:J})}catch(B){F(Error(`Failed to parse ffprobe output: ${B}`))}})})}function UD(D,u=256){if(!D)return`${u}k`;let F=Math.min(D,u);if(F<=64)return"64k";if(F<=96)return"96k";if(F<=128)return"128k";if(F<=192)return"192k";return"256k"}function WD(D){let u=Math.floor(D/3600),F=Math.floor(D%3600/60),E=D%60;return`${String(u).padStart(2,"0")}:${String(F).padStart(2,"0")}:${E.toFixed(3).padStart(6,"0")}`}import{mkdir as aF,access as iF,constants as rF}from"node:fs/promises";async function l(D){try{await iF(D,rF.F_OK)}catch{await aF(D,{recursive:!0})}}function eF(D,u){let F=D*u;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 b(D,u,F=30,E){let C=eF(D,u),A=Math.round(D*u*F*C/1000);if(E&&A>E)A=E;return`${A}k`}var TD=[{name:"360p",width:640,height:360,videoBitrate:b(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:b(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:b(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:b(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:b(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:b(3840,2160,30),audioBitrate:"256k"}];function AD(D,u,F=30,E){let C=[],A=TD.filter((B)=>{return B.width<=D&&B.height<=u});for(let B of A)C.push({...B,videoBitrate:b(B.width,B.height,30,E),fps:30});return C}function D8(D,u,F){return{...D,name:`${D.name}-${u}`,videoBitrate:b(D.width,D.height,u,F),fps:u}}function Ku(D){let F=D.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!F)return null;let E=F[1]+"p",C=F[2]?parseInt(F[2]):30;return{resolution:E,fps:C}}function Xu(D,u=30,F){let E=TD.find((C)=>C.name===D);if(!E)return null;if(u===30)return{...E,videoBitrate:b(E.width,E.height,30,F),fps:30};return D8(E,u,F)}function u8(D,u,F,E){let C=Ku(D);if(!C)return{error:`Invalid profile format: ${D}. Use format like: 360, 720@60, 1080-60`};let A=Xu(C.resolution,C.fps);if(!A)return{error:`Unknown resolution: ${C.resolution}. Available: 360, 480, 720, 1080, 1440, 2160`};if(A.width>u||A.height>F)return{error:`Source resolution (${u}x${F}) is lower than ${D} (${A.width}x${A.height})`};let B=120,$=C.fps,K;if(C.fps>E)$=Math.min(E,B),K=`Requested ${C.fps} FPS in ${D}, but source is ${E} FPS. Using ${$} FPS instead`;else if(C.fps>B)$=B,K=`Requested ${C.fps} FPS in ${D} exceeds maximum ${B} FPS. Using ${$} FPS instead`;return K?{warning:K,adjustedFps:$}:{}}function ND(D,u,F,E,C){let A=[],B=[],$=[];for(let K of D){let X=u8(K,u,F,E);if(X.error){B.push(X.error);continue}if(X.warning)$.push(X.warning);let U=Ku(K);if(!U)continue;let Y=X.adjustedFps!==void 0?X.adjustedFps:U.fps,Z=Xu(U.resolution,Y,C);if(Z)A.push(Z)}return{profiles:A,errors:B,warnings:$}}import{join as g}from"node:path";import{readdir as F8,unlink as Yu,rmdir as E8,writeFile as Gu}from"node:fs/promises";async function Uu(D,u,F="00:00:00"){let E=g(u,"poster.jpg"),C=/^\d+(\.\d+)?$/.test(F)?F:F;return await c(["-ss",C,"-i",D,"-vframes","1","-q:v","2","-y",E]),E}async function Wu(D,u,F,E){let{width:C,height:A,interval:B,columns:$}=E,K=g(u,".thumbnails_temp");await l(K),await Gu(g(K,".keep"),"");let X=g(K,"thumb_%04d.jpg");await c(["-i",D,"-vf",`fps=1/${B},scale=${C}:${A}`,"-q:v","5",X]);let Y=(await F8(K)).filter((k)=>k.startsWith("thumb_")&&k.endsWith(".jpg")).sort();if(Y.length===0)throw Error("No thumbnails generated");let Z=Y.length,W=Math.ceil(Z/$),J=g(u,"thumbnails.jpg"),Q=`tile=${$}x${W}`;await c(["-i",X,"-filter_complex",Q,"-q:v","5",J]);let G=g(u,"thumbnails.vtt"),N=C8(Z,B,C,A,$,"thumbnails.jpg");await Gu(G,N);for(let k of Y)await Yu(g(K,k));return await Yu(g(K,".keep")),await E8(K),{spritePath:J,vttPath:G}}function C8(D,u,F,E,C,A){let B=`WEBVTT -`;for(let $=0;$ ${QD(X)} +`;for(let $=0;$ ${WD(X)} `,B+=`${A}#xywh=${Z},${W},${F},${E} -`}return B}import{join as A8}from"node:path";function Z8(D,u,F){if(F)if(u==="h264")return 32;else return 42;else if(u==="h264"){if(D<=360)return 25;if(D<=480)return 24;if(D<=720)return 23;if(D<=1080)return 22;if(D<=1440)return 21;return 20}else{if(D<=360)return 40;if(D<=480)return 38;if(D<=720)return 35;if(D<=1080)return 32;if(D<=1440)return 30;return 28}}async function Wu(D,u,F,E,C,A,B,$,K,X,U,Y,Z){let W=A8(u,`video_${K}_${F.name}.mp4`),J=["-y"];if(Y){if(Y==="nvenc")J.push("-hwaccel","cuda","-hwaccel_output_format","cuda");else if(Y==="qsv")J.push("-hwaccel","qsv");else if(Y==="vaapi")J.push("-hwaccel","vaapi");else if(Y==="videotoolbox")J.push("-hwaccel","videotoolbox");else if(Y==="v4l2")J.push("-hwaccel","v4l2")}J.push("-i",D,"-c:v",E);let _=E.includes("nvenc")||E.includes("qsv")||E.includes("amf")||E.includes("vaapi")||E.includes("videotoolbox")||E.includes("v4l2"),G;if(_&&X?.cq!==void 0)G=X.cq;else if(!_&&X?.crf!==void 0)G=X.crf;else G=Z8(F.height,K,_);if(E==="h264_nvenc")J.push("-rc:v","vbr"),J.push("-cq",String(G)),J.push("-preset",C),J.push("-2pass","0");else if(E==="av1_nvenc")J.push("-rc:v","vbr"),J.push("-cq",String(G)),J.push("-preset",C),J.push("-2pass","0");else if(E==="av1_qsv")J.push("-preset",C),J.push("-global_quality",String(G));else if(E==="h264_qsv")J.push("-preset",C),J.push("-global_quality",String(G));else if(E==="av1_amf")J.push("-quality","balanced"),J.push("-rc","cqp"),J.push("-qp_i",String(G)),J.push("-qp_p",String(G));else if(E==="h264_amf")J.push("-quality","balanced"),J.push("-rc","cqp"),J.push("-qp_i",String(G)),J.push("-qp_p",String(G));else if(E==="libsvtav1")J.push("-crf",String(G)),J.push("-preset",C),J.push("-svtav1-params","tune=0:enable-overlays=1");else if(E==="libx264")J.push("-crf",String(G)),J.push("-preset",C);else J.push("-preset",C);let N=K==="av1"?0.6:1,k=Math.round(parseInt(F.videoBitrate)*N*1.5);J.push("-maxrate",`${k}k`),J.push("-bufsize",`${k*2}k`);let x=F.fps||30,L=Math.round(x*B);J.push("-g",String(L),"-keyint_min",String(L),"-sc_threshold","0");let M=[];if(Y==="nvenc")M.push(`scale_cuda=${F.width}:${F.height}`);else M.push(`scale=${F.width}:${F.height}`);if(U){if(U.deinterlace)M.push("yadif");if(U.denoise)M.push("hqdn3d");if(U.customFilters)M.push(...U.customFilters)}J.push("-vf",M.join(","));let S=parseInt(F.audioBitrate)||256,s=kD($,S);if(J.push("-c:a","aac","-b:a",s),U?.audioNormalize)J.push("-af","loudnorm");return J.push("-f","mp4",W),await c(J,Z,A),W}async function Nu(D,u,F,E,C,A,B,$,K,X,U,Y,Z,W,J){let _=new Map;if(K&&F.length>1)for(let G=0;GWu(D,u,L,E,C,A,B,$,U,Y,Z,W,(M)=>{if(J)J(L.name,M)}));(await Promise.all(k)).forEach((L,M)=>{let S=N[M];_.set(S.name,L)})}else for(let G of F){let N=await Wu(D,u,G,E,C,A,B,$,U,Y,Z,W,(k)=>{if(J)J(G.name,k)});_.set(G.name,N)}return _}import{join as O}from"node:path";import{readdir as qu,rename as v3,mkdir as P3,writeFile as vD}from"node:fs/promises";import{readFile as yD,writeFile as SD}from"node:fs/promises";async function ku(D){let u=await yD(D,"utf-8");u=u.replace(/\/\/>/g,"/>"),u=u.replace(/\/\s+\/>/g,"/>"),u=u.replace(/(]+)\s+\/>/g,"$1/>"),u=u.replace(/]+)\/>\s*<\/Representation>/g,""),u=u.replace(/]+)\/>\s*(]*\/>)/g,` +`}return B}import{join as B8}from"node:path";function A8(D,u,F){if(F)if(u==="h264")return 32;else return 42;else if(u==="h264"){if(D<=360)return 25;if(D<=480)return 24;if(D<=720)return 23;if(D<=1080)return 22;if(D<=1440)return 21;return 20}else{if(D<=360)return 40;if(D<=480)return 38;if(D<=720)return 35;if(D<=1080)return 32;if(D<=1440)return 30;return 28}}async function Nu(D,u,F,E,C,A,B,$,K,X,U,Y,Z){let W=B8(u,`video_${K}_${F.name}.mp4`),J=["-y"];if(Y){if(Y==="nvenc")J.push("-hwaccel","cuda","-hwaccel_output_format","cuda");else if(Y==="qsv")J.push("-hwaccel","qsv");else if(Y==="vaapi")J.push("-hwaccel","vaapi");else if(Y==="videotoolbox")J.push("-hwaccel","videotoolbox");else if(Y==="v4l2")J.push("-hwaccel","v4l2")}J.push("-i",D,"-c:v",E);let Q=E.includes("nvenc")||E.includes("qsv")||E.includes("amf")||E.includes("vaapi")||E.includes("videotoolbox")||E.includes("v4l2"),G;if(Q&&X?.cq!==void 0)G=X.cq;else if(!Q&&X?.crf!==void 0)G=X.crf;else G=A8(F.height,K,Q);if(E==="h264_nvenc")J.push("-rc:v","vbr"),J.push("-cq",String(G)),J.push("-preset",C),J.push("-2pass","0");else if(E==="av1_nvenc")J.push("-rc:v","vbr"),J.push("-cq",String(G)),J.push("-preset",C),J.push("-2pass","0");else if(E==="av1_qsv")J.push("-preset",C),J.push("-global_quality",String(G));else if(E==="h264_qsv")J.push("-preset",C),J.push("-global_quality",String(G));else if(E==="av1_amf")J.push("-quality","balanced"),J.push("-rc","cqp"),J.push("-qp_i",String(G)),J.push("-qp_p",String(G));else if(E==="h264_amf")J.push("-quality","balanced"),J.push("-rc","cqp"),J.push("-qp_i",String(G)),J.push("-qp_p",String(G));else if(E==="libsvtav1")J.push("-crf",String(G)),J.push("-preset",C),J.push("-svtav1-params","tune=0:enable-overlays=1");else if(E==="libx264")J.push("-crf",String(G)),J.push("-preset",C);else J.push("-preset",C);let N=K==="av1"?0.6:1,k=Math.round(parseInt(F.videoBitrate)*N*1.5);J.push("-maxrate",`${k}k`),J.push("-bufsize",`${k*2}k`);let x=F.fps||30,O=Math.round(x*B);J.push("-g",String(O),"-keyint_min",String(O),"-sc_threshold","0");let M=[];if(Y==="nvenc")M.push(`scale_cuda=${F.width}:${F.height}`);else M.push(`scale=${F.width}:${F.height}`);if(U){if(U.deinterlace)M.push("yadif");if(U.denoise)M.push("hqdn3d");if(U.customFilters)M.push(...U.customFilters)}J.push("-vf",M.join(","));let S=parseInt(F.audioBitrate)||256,ED=UD($,S);if(J.push("-c:a","aac","-b:a",ED),U?.audioNormalize)J.push("-af","loudnorm");return J.push("-f","mp4",W),await c(J,Z,A),W}async function ku(D,u,F,E,C,A,B,$,K,X,U,Y,Z,W,J){let Q=new Map;if(K&&F.length>1)for(let G=0;GNu(D,u,O,E,C,A,B,$,U,Y,Z,W,(M)=>{if(J)J(O.name,M)}));(await Promise.all(k)).forEach((O,M)=>{let S=N[M];Q.set(S.name,O)})}else for(let G of F){let N=await Nu(D,u,G,E,C,A,B,$,U,Y,Z,W,(k)=>{if(J)J(G.name,k)});Q.set(G.name,N)}return Q}import{join as L}from"node:path";import{readdir as Iu,rename as P3,mkdir as h3,writeFile as bD}from"node:fs/promises";import{readFile as wD,writeFile as yD}from"node:fs/promises";async function Qu(D){let u=await wD(D,"utf-8");u=u.replace(/\/\/>/g,"/>"),u=u.replace(/\/\s+\/>/g,"/>"),u=u.replace(/(]+)\s+\/>/g,"$1/>"),u=u.replace(/]+)\/>\s*<\/Representation>/g,""),u=u.replace(/]+)\/>\s*(]*\/>)/g,` $2 `),u=u.replace(/]+)>\s*(?=<(?:Representation|\/AdaptationSet))/g,` -`),await SD(D,u,"utf-8")}async function Qu(D){let u=await yD(D,"utf-8");u=u.replace(/media="\$RepresentationID\$_\$Number\$\.m4s"/g,'media="$RepresentationID$/$RepresentationID$_$Number$.m4s"'),u=u.replace(/initialization="\$RepresentationID\$_\.mp4"/g,'initialization="$RepresentationID$/$RepresentationID$_.mp4"'),await SD(D,u,"utf-8")}async function _u(D){let F=(await yD(D,"utf-8")).split(` -`),E=[],C=0;while(C")){let Z=F[C];if(Z.includes(""))Y=!1}else if(Z.includes("0&&U.length>0)E.push(A),K.forEach((Z)=>E.push(Z)),X.forEach((Z)=>E.push(Z)),E.push(" "),E.push(A),K.forEach((Z)=>E.push(Z)),U.forEach((Z)=>E.push(Z)),E.push(" ");else{E.push(A);for(let Z=B+1;Z")){let Z=F[C];if(Z.includes(""))Y=!1}else if(Z.includes("0&&U.length>0)E.push(A),K.forEach((Z)=>E.push(Z)),X.forEach((Z)=>E.push(Z)),E.push(" "),E.push(A),K.forEach((Z)=>E.push(Z)),U.forEach((Z)=>E.push(Z)),E.push(" ");else{E.push(A);for(let Z=B+1;Z1,K=["-dash",String(E*1000),"-frag",String(E*1000),"-rap","-segment-timeline","-segment-name","$RepresentationID$_$Number$","-out",B],X=!0;for(let[U,Y]of D.entries())for(let Z of F){let W=Y.get(Z.name);if(!W)throw Error(`MP4 file not found for profile: ${Z.name}, codec: ${U}`);let J=$?`${Z.name}-${U}`:Z.name;if(K.push(`${W}#video:id=${J}`),X&&A)K.push(`${W}#audio:id=audio`),X=!1}if(await TD(K),await J8(u,F,C,A),await Qu(B),$)await _u(B);return await ku(B),B}async function J8(D,u,F,E){let{readdir:C,rename:A,mkdir:B}=await import("node:fs/promises"),$=F.length>1,K=[];for(let Y of F)for(let Z of u){let W=$?`${Z.name}-${Y}`:Z.name;K.push(W);let J=O(D,W);await B(J,{recursive:!0})}let X=O(D,"audio");if(E)await B(X,{recursive:!0});let U=await C(D);for(let Y of U){if(Y==="manifest.mpd")continue;if(E&&(Y.startsWith("audio_")||Y==="audio_init.m4s")){let Z=O(D,Y),W=O(X,Y);await A(Z,W);continue}for(let Z of K)if(Y.startsWith(`${Z}_`)){let W=O(D,Y),J=O(D,Z,Y);await A(W,J);break}}}async function Iu(D,u,F,E,C,A,B){let $,K,X=A.length>0,U=A.includes("dash"),Y=A.includes("hls");if(X){if($=await $8(D,u,F,E,C,B),!U)$=void 0}if(Y)K=await K8(u,F,E,C.length>1,B);return{manifestPath:$,hlsManifestPath:K}}async function K8(D,u,F,E,C){let A=O(D,"master.m3u8"),B=[];for(let U of u){let Y=E?`${U.name}-h264`:U.name,Z=O(D,Y),W=await qu(Z),J=W.filter((x)=>x.endsWith(".m4s")).sort((x,L)=>{let M=parseInt(x.match(/_(\d+)\.m4s$/)?.[1]||"0"),S=parseInt(L.match(/_(\d+)\.m4s$/)?.[1]||"0");return M-S}),_=W.find((x)=>x.endsWith("_.mp4"));if(!_||J.length===0)continue;let G=bD(J,_,F),N=O(Z,"playlist.m3u8");await vD(N,G,"utf-8");let k=parseInt(U.videoBitrate)*1000;B.push({path:`${Y}/playlist.m3u8`,bandwidth:k,resolution:`${U.width}x${U.height}`,fps:U.fps||30})}let $,K=[];if(C){let U=O(D,"audio"),Y=[];try{Y=await qu(U)}catch{Y=[]}if(K=Y.filter((Z)=>Z.endsWith(".m4s")).sort((Z,W)=>{let J=parseInt(Z.match(/_(\d+)\.m4s$/)?.[1]||"0"),_=parseInt(W.match(/_(\d+)\.m4s$/)?.[1]||"0");return J-_}),$=Y.find((Z)=>Z.endsWith("_.mp4")),$&&K.length>0){let Z=bD(K,$,F);await vD(O(U,"playlist.m3u8"),Z,"utf-8")}}let X=zu(B,C&&$!==void 0&&K.length>0);return await vD(A,X,"utf-8"),A}async function PD(D){let{input:u,outputDir:F,segmentDuration:E=2,profiles:C,customProfiles:A,codec:B="auto",format:$="auto",hardwareDecoder:K,hardwareAccelerator:X,quality:U,generateThumbnails:Y=!0,thumbnailConfig:Z={},generatePoster:W=!0,posterTimecode:J="00:00:00",parallel:_=!0,onProgress:G}=D,N=zD("/tmp",`dash-converter-${X8()}`);await l(N);let k=Hu(u,xu(u)),x=zD(F,k);await l(x);let L=zD(x,"conversion.log");jD(L);let{writeFile:M}=await import("node:fs/promises"),S=`=========================================== +`}return F}async function Z8(D,u,F,E,C,A){let B=L(u,"manifest.mpd"),$=C.length>1,K=["-dash",String(E*1000),"-frag",String(E*1000),"-rap","-segment-timeline","-segment-name","$RepresentationID$_$Number$","-out",B],X=!0;for(let[U,Y]of D.entries())for(let Z of F){let W=Y.get(Z.name);if(!W)throw Error(`MP4 file not found for profile: ${Z.name}, codec: ${U}`);let J=$?`${Z.name}-${U}`:Z.name;if(K.push(`${W}#video:id=${J}`),X&&A)K.push(`${W}#audio:id=audio`),X=!1}if(await jD(K),await $8(u,F,C,A),await _u(B),$)await zu(B);return await Qu(B),B}async function $8(D,u,F,E){let{readdir:C,rename:A,mkdir:B}=await import("node:fs/promises"),$=F.length>1,K=[];for(let Y of F)for(let Z of u){let W=$?`${Z.name}-${Y}`:Z.name;K.push(W);let J=L(D,W);await B(J,{recursive:!0})}let X=L(D,"audio");if(E)await B(X,{recursive:!0});let U=await C(D);for(let Y of U){if(Y==="manifest.mpd")continue;if(E&&(Y.startsWith("audio_")||Y==="audio_init.m4s")){let Z=L(D,Y),W=L(X,Y);await A(Z,W);continue}for(let Z of K)if(Y.startsWith(`${Z}_`)){let W=L(D,Y),J=L(D,Z,Y);await A(W,J);break}}}async function Hu(D,u,F,E,C,A,B){let $,K,X=A.length>0,U=A.includes("dash"),Y=A.includes("hls");if(X){if($=await Z8(D,u,F,E,C,B),!U)$=void 0}if(Y)K=await J8(u,F,E,C.length>1,B);return{manifestPath:$,hlsManifestPath:K}}async function J8(D,u,F,E,C){let A=L(D,"master.m3u8"),B=[];for(let U of u){let Y=E?`${U.name}-h264`:U.name,Z=L(D,Y),W=await Iu(Z),J=W.filter((x)=>x.endsWith(".m4s")).sort((x,O)=>{let M=parseInt(x.match(/_(\d+)\.m4s$/)?.[1]||"0"),S=parseInt(O.match(/_(\d+)\.m4s$/)?.[1]||"0");return M-S}),Q=W.find((x)=>x.endsWith("_.mp4"));if(!Q||J.length===0)continue;let G=SD(J,Q,F),N=L(Z,"playlist.m3u8");await bD(N,G,"utf-8");let k=parseInt(U.videoBitrate)*1000;B.push({path:`${Y}/playlist.m3u8`,bandwidth:k,resolution:`${U.width}x${U.height}`,fps:U.fps||30})}let $,K=[];if(C){let U=L(D,"audio"),Y=[];try{Y=await Iu(U)}catch{Y=[]}if(K=Y.filter((Z)=>Z.endsWith(".m4s")).sort((Z,W)=>{let J=parseInt(Z.match(/_(\d+)\.m4s$/)?.[1]||"0"),Q=parseInt(W.match(/_(\d+)\.m4s$/)?.[1]||"0");return J-Q}),$=Y.find((Z)=>Z.endsWith("_.mp4")),$&&K.length>0){let Z=SD(K,$,F);await bD(L(U,"playlist.m3u8"),Z,"utf-8")}}let X=qu(B,C&&$!==void 0&&K.length>0);return await bD(A,X,"utf-8"),A}async function vD(D){let{input:u,outputDir:F,segmentDuration:E=2,profiles:C,customProfiles:A,codec:B=["h264"],formats:$=["dash","hls"],hardwareDecoder:K,hardwareAccelerator:X,quality:U,generateThumbnails:Y=!0,thumbnailConfig:Z={},generatePoster:W=!0,posterTimecode:J="00:00:00",parallel:Q=!0,onProgress:G}=D,N=kD("/tmp",`dash-converter-${K8()}`);await l(N);let k=xu(u,Mu(u)),x=kD(F,k);await l(x);let O=kD(x,"conversion.log");RD(O);let{writeFile:M}=await import("node:fs/promises"),S=`=========================================== DASH Conversion Log Started: ${new Date().toISOString()} Input: ${u} Output: ${x} -Codec: ${B} -Format: ${$} +Codec: ${Array.isArray(B)?B.join(","):B} +Formats: ${$?.join(",")||"dash,hls"} =========================================== -`;await M(L,S,"utf-8");try{return await Y8(u,F,N,E,C,A,B,$,X,K,U,Y,Z,W,J,_,G)}finally{let{appendFile:s}=await import("node:fs/promises");try{await s(L,` +`;await M(O,S,"utf-8");try{return await X8(u,F,N,E,C,A,B,$,X,K,U,Y,Z,W,J,Q,G)}finally{let{appendFile:ED}=await import("node:fs/promises");try{await ED(O,` Completed: ${new Date().toISOString()} -`,"utf-8")}catch(XD){}try{await Mu(N,{recursive:!0,force:!0})}catch(XD){console.warn(`Warning: Failed to cleanup temp directory: ${N}`)}}}async function Y8(D,u,F,E,C,A,B,$,K,X,U,Y,Z,W,J,_,G){if(!await r())throw Error("FFmpeg is not installed or not in PATH");if(!await o())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let N=(z,I,LD,OD)=>{if(G)G({stage:z,percent:I,message:LD,currentProfile:OD})};N("analyzing",0,"Analyzing input video...");let k=await DD(D),x=k.hasAudio,L=K&&K!=="auto"?K:"auto",M=await t(),S=await e(),s=M.some((z)=>z.av1Encoder),XD=B==="h264"||B==="auto",xD=B==="av1"||B==="auto";if(B==="auto"&&!s)xD=!1;let{selected:YD,h264Encoder:jF,av1Encoder:TF,warnings:eD}=G8(M,L,XD,xD);if(eD.length>0)for(let z of eD)console.warn(`⚠️ ${z}`);let{selected:GD}=U8(S,X||"auto");if(B==="av1"&&!s)console.warn("⚠️ AV1 hardware encoder not detected. AV1 will use CPU encoder (slow).");let P=[];if(XD)P.push("h264");if(xD)P.push("av1");if(P.length===0)P.push("h264");let a=[];if($==="dash"||$==="auto")a.push("dash");if($==="hls"||$==="auto")a.push("hls");if(a.length===0)a.push("dash");let R;if(A&&A.length>0){let z=_D(A,k.width,k.height,k.fps,k.videoBitrate);if(z.errors.length>0){console.warn(` +`,"utf-8")}catch($D){}try{await Ou(N,{recursive:!0,force:!0})}catch($D){console.warn(`Warning: Failed to cleanup temp directory: ${N}`)}}}async function X8(D,u,F,E,C,A,B,$,K,X,U,Y,Z,W,J,Q,G){if(!await s())throw Error("FFmpeg is not installed or not in PATH");if(!await a())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let N=(z,I,MD,OD)=>{if(G)G({stage:z,percent:I,message:MD,currentProfile:OD})};N("analyzing",0,"Analyzing input video...");let k=await o(D),x=k.hasAudio,O=K&&K!=="auto"?K:"auto",M=await i(),S=await r(),ED=M.some((z)=>z.av1Encoder),$D=Array.isArray(B)?B:[B],tD=$D.includes("h264"),VD=$D.includes("av1"),{selected:JD,h264Encoder:RF,av1Encoder:jF,warnings:eD}=Y8(M,O,tD,VD);if(eD.length>0)for(let z of eD)console.warn(`⚠️ ${z}`);let{selected:KD}=G8(S,X||"auto");if(VD&&!ED)console.warn("⚠️ AV1 hardware encoder not detected. AV1 will use CPU encoder (slow).");let v=[];if(tD)v.push("h264");if(VD)v.push("av1");if(v.length===0)v.push("h264");let Du=$&&$.length>0?Array.from(new Set($)):["dash","hls"],R;if(A&&A.length>0){let z=ND(A,k.width,k.height,k.fps,k.videoBitrate);if(z.errors.length>0){console.warn(` ❌ Profile errors:`);for(let I of z.errors)console.warn(` - ${I}`);console.warn("")}if(z.warnings.length>0){console.warn(` -⚠️ Profile warnings:`);for(let I of z.warnings)console.warn(` - ${I}`);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=JD(k.width,k.height,k.fps,k.videoBitrate);if(R.length===0)throw Error("No suitable profiles found for input video resolution");let wF=Hu(D,xu(D)),ZD=zD(u,wF);try{await Mu(ZD,{recursive:!0,force:!0})}catch(z){}await l(ZD);let h=[];if(P.includes("h264")){let z=jF||"libx264",I=Vu(z,"h264");h.push({type:"h264",codec:z,preset:I})}if(P.includes("av1")){let z=TF||"libsvtav1",I=Vu(z,"av1");h.push({type:"av1",codec:z,preset:I})}let yF=h.map((z)=>z.type.toUpperCase()).join(" + "),SF=YD==="cpu"?"CPU":YD.toUpperCase();N("analyzing",20,`Using ${yF} encoding (${SF}, decoder ${GD.toUpperCase()})`,void 0);let bF=YD==="cpu"?2:3,MD=new Map;for(let z=0;z{let $3=R.findIndex((mF)=>mF.name===$D),Au=25+Cu*40,Zu=Bu/100*(40*hF/R.length);if(N("encoding",Au+Zu,`Encoding ${I.toUpperCase()} ${$D}...`,`${I}-${$D}`),G)G({stage:"encoding",percent:Au+Zu,currentProfile:`${I}-${$D}`,profilePercent:Bu,message:`Encoding ${I.toUpperCase()} ${$D}...`})});MD.set(I,gF)}N("encoding",65,"Stage 1 complete: All codecs and profiles encoded"),N("encoding",70,"Stage 2: Creating segments and manifests...");let{manifestPath:vF,hlsManifestPath:PF}=await Iu(MD,ZD,R,E,P,a,x),Du=[];for(let z of MD.values())Du.push(...Array.from(z.values()));N("encoding",80,"Stage 2 complete: All formats packaged");let uu,Fu;if(Y){N("thumbnails",80,"Generating thumbnail sprites...");let z={width:Z.width||160,height:Z.height||90,interval:Z.interval||1,columns:Z.columns||10},I=await Uu(D,ZD,k.duration,z);uu=I.spritePath,Fu=I.vttPath,N("thumbnails",90,"Thumbnails generated")}let Eu;if(W)N("thumbnails",92,"Generating poster image..."),Eu=await Gu(D,ZD,J),N("thumbnails",95,"Poster generated");return N("manifest",95,"Finalizing..."),N("complete",100,"Conversion complete!"),{manifestPath:vF,hlsManifestPath:PF,videoPaths:Du,thumbnailSpritePath:uu,thumbnailVttPath:Fu,posterPath:Eu,duration:k.duration,profiles:R,usedNvenc:h.some((z)=>z.codec.includes("nvenc")),selectedAccelerator:YD,selectedDecoder:GD,codecs:P,formats:a}}var uD={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60,cpu:1};function G8(D,u,F,E){let C=[],A=new Set(["nvenc","qsv","amf","vaapi","videotoolbox","v4l2"]),B=D.filter((G)=>F&&G.h264Encoder||E&&G.av1Encoder),$=B.filter((G)=>A.has(G.accelerator)),K=(G)=>B.find((N)=>N.accelerator===G);if(u==="cpu")return{selected:"cpu",h264Encoder:void 0,av1Encoder:void 0,warnings:C};let X;if(u!=="auto"){if(!A.has(u))C.push(`Ускоритель "${u}" пока не поддерживается, использую CPU`);else if(X=K(u),!X)throw Error(`Аппаратный ускоритель "${u}" недоступен в системе`)}else if(X=($.length>0?$:[]).sort((N,k)=>(uD[k.accelerator]||0)-(uD[N.accelerator]||0))[0],!X&&B.length>0)C.push("Доступен аппаратный ускоритель, но он пока не поддерживается пайплайном, использую CPU");let Y=($.length>0?$:[]).sort((G,N)=>(uD[N.accelerator]||0)-(uD[G.accelerator]||0)),Z=(G)=>{let N=G==="h264"?X?.h264Encoder:X?.av1Encoder;if(N)return{encoder:N,accel:X?.accelerator};let k=Y.find((x)=>G==="h264"?x.h264Encoder:x.av1Encoder);if(k){if(u!=="auto"&&X)C.push(`Выбранный ускоритель "${X.accelerator}" не поддерживает ${G.toUpperCase()}, использую ${k.accelerator}`);return{encoder:G==="h264"?k.h264Encoder:k.av1Encoder,accel:k.accelerator}}if(u!=="auto")C.push(`Ускоритель "${u}" не поддерживает ${G.toUpperCase()}, использую CPU`);return{encoder:void 0,accel:"cpu"}},W=F?Z("h264"):{encoder:void 0,accel:X?.accelerator},J=E?Z("av1"):{encoder:void 0,accel:X?.accelerator};return{selected:X?.accelerator||W.accel||J.accel||"cpu",h264Encoder:W.encoder,av1Encoder:J.encoder,warnings:C}}function U8(D,u){let F=new Set(["nvenc","qsv","vaapi","videotoolbox","v4l2"]),E=(B)=>D.find(($)=>$.accelerator===B);if(u!=="auto"){if(u==="cpu")return{selected:"cpu"};let B=E(u);return{selected:B?B.accelerator:"cpu"}}let C=D.filter((B)=>F.has(B.accelerator));if(C.length===0)return{selected:"cpu"};return{selected:C.sort((B,$)=>(uD[$.accelerator]||0)-(uD[B.accelerator]||0))[0].accelerator}}function Vu(D,u){if(D.includes("nvenc"))return"p4";if(D.includes("qsv"))return"medium";if(D.includes("amf"))return"balanced";if(D.includes("vaapi"))return"5";if(D.includes("videotoolbox"))return"medium";if(D.includes("v4l2"))return"medium";if(D==="libsvtav1")return"8";if(D==="libx264")return"medium";return u==="av1"?"8":"medium"}var aD=UD(XF(),1);import{statSync as c8}from"node:fs";var Q=process.argv.slice(2),KD,rD,v="auto",FD="auto",oD=[],j,T,w,y,ED,CD;for(let D=0;DE.trim()).filter((E)=>E.length>0)}else if(Q[D]==="-p"||Q[D]==="--poster")rD=Q[D+1],D++;else if(Q[D]==="-c"||Q[D]==="--codec"){let u=Q[D+1];if(u==="av1"||u==="h264")v=u;else console.error(`❌ Invalid codec: ${u}. Valid options: av1, h264`),process.exit(1);D++}else if(Q[D]==="-f"||Q[D]==="--format"){let u=Q[D+1];if(u==="dash"||u==="hls")FD=u;else console.error(`❌ Invalid format: ${u}. Valid options: dash, hls`),process.exit(1);D++}else if(Q[D]==="--h264-cq"){if(j=parseInt(Q[D+1]),isNaN(j)||j<0||j>51)console.error(`❌ Invalid H.264 CQ value: ${Q[D+1]}. Must be 0-51`),process.exit(1);D++}else if(Q[D]==="--h264-crf"){if(T=parseInt(Q[D+1]),isNaN(T)||T<0||T>51)console.error(`❌ Invalid H.264 CRF value: ${Q[D+1]}. Must be 0-51`),process.exit(1);D++}else if(Q[D]==="--av1-cq"){if(w=parseInt(Q[D+1]),isNaN(w)||w<0||w>51)console.error(`❌ Invalid AV1 CQ value: ${Q[D+1]}. Must be 0-51`),process.exit(1);D++}else if(Q[D]==="--av1-crf"){if(y=parseInt(Q[D+1]),isNaN(y)||y<0||y>63)console.error(`❌ Invalid AV1 CRF value: ${Q[D+1]}. Must be 0-63`),process.exit(1);D++}else if(Q[D]==="-e"||Q[D]==="--encoder"){let u=Q[D+1];if(!["auto","nvenc","qsv","amf","cpu","vaapi","videotoolbox","v4l2"].includes(u))console.error(`❌ Invalid accelerator: ${u}. Valid: auto, nvenc, qsv, amf, vaapi, videotoolbox, v4l2, cpu`),process.exit(1);ED=u,D++}else if(Q[D]==="-d"||Q[D]==="--decoder"){let u=Q[D+1];if(!["auto","nvenc","qsv","amf","vaapi","videotoolbox","v4l2","cpu"].includes(u))console.error(`❌ Invalid decoder: ${u}. Valid: auto, nvenc, qsv, amf, vaapi, videotoolbox, v4l2, cpu`),process.exit(1);CD=u,D++}else if(!Q[D].startsWith("-"))oD.push(Q[D]);var n=oD[0],QF=oD[1]||".";if(!n)console.error("❌ Usage: create-vod [output-dir] [options]"),console.error(` +⚠️ Profile warnings:`);for(let I of z.warnings)console.warn(` - ${I}`);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=AD(k.width,k.height,k.fps,k.videoBitrate);if(R.length===0)throw Error("No suitable profiles found for input video resolution");let TF=xu(D,Mu(D)),CD=kD(u,TF);try{await Ou(CD,{recursive:!0,force:!0})}catch(z){}await l(CD);let P=[];if(v.includes("h264")){let z=RF||"libx264",I=Vu(z,"h264");P.push({type:"h264",codec:z,preset:I})}if(v.includes("av1")){let z=jF||"libsvtav1",I=Vu(z,"av1");P.push({type:"av1",codec:z,preset:I})}let wF=P.map((z)=>z.type.toUpperCase()).join(" + "),yF=JD==="cpu"?"CPU":JD.toUpperCase();N("analyzing",20,`Using ${wF} encoding (${yF}, decoder ${KD.toUpperCase()})`,void 0);let SF=JD==="cpu"?2:3,xD=new Map;for(let z=0;z{let J3=R.findIndex((gF)=>gF.name===BD),Zu=25+Bu*40,$u=Au/100*(40*PF/R.length);if(N("encoding",Zu+$u,`Encoding ${I.toUpperCase()} ${BD}...`,`${I}-${BD}`),G)G({stage:"encoding",percent:Zu+$u,currentProfile:`${I}-${BD}`,profilePercent:Au,message:`Encoding ${I.toUpperCase()} ${BD}...`})});xD.set(I,fF)}N("encoding",65,"Stage 1 complete: All codecs and profiles encoded"),N("encoding",70,"Stage 2: Creating segments and manifests...");let{manifestPath:bF,hlsManifestPath:vF}=await Hu(xD,CD,R,E,v,Du,x),uu=[];for(let z of xD.values())uu.push(...Array.from(z.values()));N("encoding",80,"Stage 2 complete: All formats packaged");let Fu,Eu;if(Y){N("thumbnails",80,"Generating thumbnail sprites...");let z={width:Z.width||160,height:Z.height||90,interval:Z.interval||1,columns:Z.columns||10},I=await Wu(D,CD,k.duration,z);Fu=I.spritePath,Eu=I.vttPath,N("thumbnails",90,"Thumbnails generated")}let Cu;if(W)N("thumbnails",92,"Generating poster image..."),Cu=await Uu(D,CD,J),N("thumbnails",95,"Poster generated");return N("manifest",95,"Finalizing..."),N("complete",100,"Conversion complete!"),{manifestPath:bF,hlsManifestPath:vF,videoPaths:uu,thumbnailSpritePath:Fu,thumbnailVttPath:Eu,posterPath:Cu,duration:k.duration,profiles:R,usedNvenc:P.some((z)=>z.codec.includes("nvenc")),selectedAccelerator:JD,selectedDecoder:KD,codecs:v,formats:Du}}var t={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60,cpu:1};function Y8(D,u,F,E){let C=[],A=new Set(["nvenc","qsv","amf","vaapi","videotoolbox","v4l2"]),B=D.filter((G)=>F&&G.h264Encoder||E&&G.av1Encoder),$=B.filter((G)=>A.has(G.accelerator)),K=(G)=>B.find((N)=>N.accelerator===G);if(u==="cpu")return{selected:"cpu",h264Encoder:void 0,av1Encoder:void 0,warnings:C};let X;if(u!=="auto"){if(!A.has(u))C.push(`Ускоритель "${u}" пока не поддерживается, использую CPU`);else if(X=K(u),!X)throw Error(`Аппаратный ускоритель "${u}" недоступен в системе`)}else if(X=($.length>0?$:[]).sort((N,k)=>(t[k.accelerator]||0)-(t[N.accelerator]||0))[0],!X&&B.length>0)C.push("Доступен аппаратный ускоритель, но он пока не поддерживается пайплайном, использую CPU");let Y=($.length>0?$:[]).sort((G,N)=>(t[N.accelerator]||0)-(t[G.accelerator]||0)),Z=(G)=>{let N=G==="h264"?X?.h264Encoder:X?.av1Encoder;if(N)return{encoder:N,accel:X?.accelerator};let k=Y.find((x)=>G==="h264"?x.h264Encoder:x.av1Encoder);if(k){if(u!=="auto"&&X)C.push(`Выбранный ускоритель "${X.accelerator}" не поддерживает ${G.toUpperCase()}, использую ${k.accelerator}`);return{encoder:G==="h264"?k.h264Encoder:k.av1Encoder,accel:k.accelerator}}if(u!=="auto")C.push(`Ускоритель "${u}" не поддерживает ${G.toUpperCase()}, использую CPU`);return{encoder:void 0,accel:"cpu"}},W=F?Z("h264"):{encoder:void 0,accel:X?.accelerator},J=E?Z("av1"):{encoder:void 0,accel:X?.accelerator};return{selected:X?.accelerator||W.accel||J.accel||"cpu",h264Encoder:W.encoder,av1Encoder:J.encoder,warnings:C}}function G8(D,u){let F=new Set(["nvenc","qsv","vaapi","videotoolbox","v4l2"]),E=(B)=>D.find(($)=>$.accelerator===B);if(u!=="auto"){if(u==="cpu")return{selected:"cpu"};let B=E(u);return{selected:B?B.accelerator:"cpu"}}let C=D.filter((B)=>F.has(B.accelerator));if(C.length===0)return{selected:"cpu"};return{selected:C.sort((B,$)=>(t[$.accelerator]||0)-(t[B.accelerator]||0))[0].accelerator}}function Vu(D,u){if(D.includes("nvenc"))return"p4";if(D.includes("qsv"))return"medium";if(D.includes("amf"))return"balanced";if(D.includes("vaapi"))return"5";if(D.includes("videotoolbox"))return"medium";if(D.includes("v4l2"))return"medium";if(D==="libsvtav1")return"8";if(D==="libx264")return"medium";return u==="av1"?"8":"medium"}var sD=XD(YF(),1);import{statSync as c8}from"node:fs";var _=process.argv.slice(2),ZD,iD,zD,rD=[],j,T,w,y,e,DD;for(let D=0;D<_.length;D++)if(_[D]==="-r"||_[D]==="--resolutions"){let u=[];for(let E=D+1;E<_.length;E++){if(_[E].startsWith("-"))break;u.push(_[E]),D=E}ZD=u.join(",").split(/[,\s]+/).map((E)=>E.trim()).filter((E)=>E.length>0)}else if(_[D]==="-p"||_[D]==="--poster")iD=_[D+1],D++;else if(_[D]==="-c"||_[D]==="--codec"){let F=_[D+1].split(/[,\s]+/).map((C)=>C.trim()).filter(Boolean),E=new Set(["h264","av1"]);for(let C of F)if(!E.has(C))console.error(`❌ Invalid codec: ${C}. Valid options: av1, h264`),process.exit(1);zD=Array.from(new Set(F)),D++}else if(_[D]==="--h264-cq"){if(j=parseInt(_[D+1]),isNaN(j)||j<0||j>51)console.error(`❌ Invalid H.264 CQ value: ${_[D+1]}. Must be 0-51`),process.exit(1);D++}else if(_[D]==="--h264-crf"){if(T=parseInt(_[D+1]),isNaN(T)||T<0||T>51)console.error(`❌ Invalid H.264 CRF value: ${_[D+1]}. Must be 0-51`),process.exit(1);D++}else if(_[D]==="--av1-cq"){if(w=parseInt(_[D+1]),isNaN(w)||w<0||w>51)console.error(`❌ Invalid AV1 CQ value: ${_[D+1]}. Must be 0-51`),process.exit(1);D++}else if(_[D]==="--av1-crf"){if(y=parseInt(_[D+1]),isNaN(y)||y<0||y>63)console.error(`❌ Invalid AV1 CRF value: ${_[D+1]}. Must be 0-63`),process.exit(1);D++}else if(_[D]==="-e"||_[D]==="--encoder"){let u=_[D+1];if(!["auto","nvenc","qsv","amf","cpu","vaapi","videotoolbox","v4l2"].includes(u))console.error(`❌ Invalid accelerator: ${u}. Valid: auto, nvenc, qsv, amf, vaapi, videotoolbox, v4l2, cpu`),process.exit(1);e=u,D++}else if(_[D]==="-d"||_[D]==="--decoder"){let u=_[D+1];if(!["auto","nvenc","qsv","amf","vaapi","videotoolbox","v4l2","cpu"].includes(u))console.error(`❌ Invalid decoder: ${u}. Valid: auto, nvenc, qsv, amf, vaapi, videotoolbox, v4l2, cpu`),process.exit(1);DD=u,D++}else if(!_[D].startsWith("-"))rD.push(_[D]);var d=rD[0],_F=rD[1]||".";if(!d)console.error("❌ Usage: create-vod [output-dir] [options]"),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 or h264 (default: auto = h264 + AV1 if HW)"),console.error(" -f, --format Streaming format: dash or hls (default: auto = dash + hls)"),console.error(" -p, --poster Poster timecode (e.g., 00:00:05 or 10)"),console.error(" -e, --encoder Hardware encoder: auto|nvenc|qsv|amf|vaapi|videotoolbox|v4l2|cpu (default: auto)"),console.error(" -d, --decoder Hardware decoder: auto|nvenc|qsv|amf|vaapi|videotoolbox|v4l2|cpu (default: auto)"),console.error(` Quality Options (override defaults):`),console.error(" --h264-cq H.264 GPU CQ value (0-51, lower = better, default: auto)"),console.error(" --h264-crf H.264 CPU CRF value (0-51, lower = better, default: auto)"),console.error(" --av1-cq AV1 GPU CQ value (0-51, lower = better, default: auto)"),console.error(" --av1-crf AV1 CPU CRF value (0-63, lower = better, default: auto)"),console.error(` Examples:`),console.error(" create-vod video.mp4"),console.error(" create-vod video.mp4 ./output"),console.error(" create-vod video.mp4 -r 360,480,720"),console.error(" create-vod video.mp4 -c av1 --av1-cq 40"),console.error(" create-vod video.mp4 -c h264 --h264-cq 30"),console.error(" create-vod video.mp4 -f hls"),console.error(" create-vod video.mp4 -r 720@60,1080@60,2160@60 -c av1 -f dash"),console.error(" create-vod video.mp4 -p 00:00:05"),console.error(" create-vod video.mp4 ./output -r 720,1080 -p 10 --h264-cq 28"),process.exit(1);console.log(`\uD83D\uDD0D Checking system... -`);var _F=await r(),zF=await o(),qF=await t(),l8=await e(),tD=qF.some((D)=>D.av1Encoder),VD={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60,cpu:1},d8={nvenc:"h264_nvenc",qsv:"h264_qsv",amf:"h264_amf",vaapi:"h264_vaapi",videotoolbox:"h264_videotoolbox",v4l2:"h264_v4l2m2m",cpu:"libx264"},n8=Array.from(new Set([...qF.map((D)=>D.accelerator),"cpu"])),s8=Array.from(new Set([...l8.map((D)=>D.accelerator),"cpu"]));async function a8(){let D=[];for(let u of n8){if(u==="amf")continue;let F=d8[u]||"libx264";if(await WD(F))D.push(u)}return D}async function i8(){let D=[];for(let u of s8){if(u==="cpu"){D.push("cpu");continue}if(await ND(u,n))D.push(u)}return D}var IF=await a8(),VF=await i8(),BD=IF.slice().sort((D,u)=>(VD[u]||0)-(VD[D]||0))[0],AD=VF.slice().sort((D,u)=>(VD[u]||0)-(VD[D]||0))[0];console.log(`FFmpeg: ${_F?"✅":"❌"}`);console.log(`MP4Box: ${zF?"✅":"❌"}`);var YF=Array.from(new Set(IF.map((D)=>D.toUpperCase()))),GF=Array.from(new Set(VF.map((D)=>D.toUpperCase()))),UF=ED?ED.toUpperCase():BD&&BD.toUpperCase()||"CPU",HF=YF.length>0?YF:["CPU"],WF=CD?CD.toUpperCase():AD&&AD.toUpperCase()||"CPU",xF=GF.length>0?GF:["CPU"];console.log(`Encoder: ${UF==="AUTO"?BD&&BD.toUpperCase()||"CPU":UF} (${HF.join(", ")})`);console.log(`Decoder: ${WF==="AUTO"?AD&&AD.toUpperCase()||"CPU":WF} (${xF.join(", ")})`);console.log("");if(!_F)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!zF)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);var MF=v==="h264"||v==="auto",HD=v==="av1"||v==="auto";if(HD&&!tD&&v==="auto")HD=!1;if(v==="av1"&&!tD)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(` Consider using --codec h264 for faster encoding. -`);var r8=FD==="dash"||FD==="auto",LF=FD==="hls"||FD==="auto";if(LF&&!MF)console.error("❌ Error: HLS format requires H.264 codec for Safari/iOS compatibility."),console.error(` Please use --codec h264 or omit --codec to keep H.264. -`),process.exit(1);console.log(`\uD83D\uDCCA Analyzing video... -`);var H=await DD(n),o8=c8(n),t8=(o8.size/1048576).toFixed(2);console.log("\uD83D\uDCF9 Video Information:");console.log(` File: ${n}`);console.log(` Size: ${t8} MB`);console.log(` Resolution: ${H.width}x${H.height}`);console.log(` FPS: ${H.fps.toFixed(2)}`);console.log(` Duration: ${Math.floor(H.duration/60)}m ${Math.floor(H.duration%60)}s`);console.log(` Codec: ${H.codec}`);if(H.videoBitrate)console.log(` Video Bitrate: ${(H.videoBitrate/1000).toFixed(2)} Mbps`);if(H.audioBitrate)console.log(` Audio Bitrate: ${H.audioBitrate} kbps`);var iD=[];if(KD&&KD.length>0){let D=_D(KD,H.width,H.height,H.fps,H.videoBitrate);if(D.errors.length>0)console.error(` +`);var zF=await s(),qF=await a(),IF=await i(),l8=await r(),p8=IF.some((D)=>D.av1Encoder),qD={nvenc:100,qsv:90,amf:80,vaapi:70,videotoolbox:65,v4l2:60,cpu:1},d8={nvenc:"h264_nvenc",qsv:"h264_qsv",amf:"h264_amf",vaapi:"h264_vaapi",videotoolbox:"h264_videotoolbox",v4l2:"h264_v4l2m2m",cpu:"libx264"},n8=Array.from(new Set([...IF.map((D)=>D.accelerator),"cpu"])),s8=Array.from(new Set([...l8.map((D)=>D.accelerator),"cpu"]));async function a8(){let D=[];for(let u of n8){if(u==="amf")continue;let F=d8[u]||"libx264";if(await YD(F))D.push(u)}return D}async function i8(){let D=[];for(let u of s8){if(u==="cpu"){D.push("cpu");continue}if(await GD(u,d))D.push(u)}return D}var HF=await a8(),VF=await i8(),uD=HF.slice().sort((D,u)=>(qD[u]||0)-(qD[D]||0))[0],FD=VF.slice().sort((D,u)=>(qD[u]||0)-(qD[D]||0))[0];console.log(`FFmpeg: ${zF?"✅":"❌"}`);console.log(`MP4Box: ${qF?"✅":"❌"}`);var GF=Array.from(new Set(HF.map((D)=>D.toUpperCase()))),UF=Array.from(new Set(VF.map((D)=>D.toUpperCase()))),WF=e?e.toUpperCase():uD&&uD.toUpperCase()||"CPU",xF=GF.length>0?GF:["CPU"],NF=DD?DD.toUpperCase():FD&&FD.toUpperCase()||"CPU",MF=UF.length>0?UF:["CPU"];console.log(`Encoder: ${WF==="AUTO"?uD&&uD.toUpperCase()||"CPU":WF} (${xF.join(", ")})`);console.log(`Decoder: ${NF==="AUTO"?FD&&FD.toUpperCase()||"CPU":NF} (${MF.join(", ")})`);console.log("");if(!zF)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!qF)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);var oD=zD&&zD.length>0?zD:["h264"],ID=oD.includes("h264"),HD=oD.includes("av1");if(!ID)console.warn("⚠️ H.264 is mandatory for compatibility. Adding H.264."),ID=!0;if(HD&&!p8)console.error("⚠️ AV1 requested but no hardware AV1 encoder found."),console.error(" CPU-based AV1 encoding (libsvtav1) will be VERY slow."),console.error(` Consider using --codec h264 for faster encoding. +`);var r8=!0,o8=!0;console.log(`\uD83D\uDCCA Analyzing video... +`);var V=await o(d),t8=c8(d),e8=(t8.size/1048576).toFixed(2);console.log("\uD83D\uDCF9 Video Information:");console.log(` File: ${d}`);console.log(` Size: ${e8} MB`);console.log(` Resolution: ${V.width}x${V.height}`);console.log(` FPS: ${V.fps.toFixed(2)}`);console.log(` Duration: ${Math.floor(V.duration/60)}m ${Math.floor(V.duration%60)}s`);console.log(` Codec: ${V.codec}`);if(V.videoBitrate)console.log(` Video Bitrate: ${(V.videoBitrate/1000).toFixed(2)} Mbps`);if(V.audioBitrate)console.log(` Audio Bitrate: ${V.audioBitrate} kbps`);var aD=[];if(ZD&&ZD.length>0){let D=ND(ZD,V.width,V.height,V.fps,V.videoBitrate);if(D.errors.length>0)console.error(` ❌ Profile errors:`),D.errors.forEach((u)=>console.error(` - ${u}`)),process.exit(1);if(D.warnings.length>0)console.warn(` -⚠️ Profile warnings:`),D.warnings.forEach((u)=>console.warn(` - ${u}`));iD=D.profiles.map((u)=>u.name)}else iD=JD(H.width,H.height,H.fps,H.videoBitrate).map((u)=>u.name);var e8=[r8?"DASH (manifest.mpd)":null,LF?"HLS (master.m3u8)":null].filter(Boolean).join(", "),D3=!0,u3=rD||"00:00:00",F3=[MF?"h264":null,HD?"av1":null].filter(Boolean).join(", "),E3=!HD&&v==="auto"&&!tD?" (AV1 disabled: no HW)":"",OF=BD&&BD.toUpperCase()||"CPU",RF=AD&&AD.toUpperCase()||"CPU",NF=ED?ED.toUpperCase():OF,kF=CD?CD.toUpperCase():RF,C3=NF==="AUTO"?OF:NF,B3=kF==="AUTO"?RF:kF,A3=HF.join(", "),Z3=xF.join(", ");console.log(` -\uD83D\uDCE6 Parameters:`);console.log(` Input: ${n}`);console.log(` Output: ${QF}`);console.log(` Codec: ${F3}${E3}`);console.log(` Profiles: ${iD.join(", ")}`);console.log(` Manifests: ${e8}`);console.log(` Poster: ${u3} (will be generated)`);console.log(` Thumbnails: ${D3?"yes (with VTT)":"no"}`);console.log(` Encoder: ${C3} (available: ${A3})`);console.log(` Decoder: ${B3} (available: ${Z3})`);var p;if(j!==void 0||T!==void 0||w!==void 0||y!==void 0){if(p={},j!==void 0||T!==void 0){if(p.h264={},j!==void 0)p.h264.cq=j;if(T!==void 0)p.h264.crf=T;console.log(`\uD83C\uDF9A️ H.264 Quality: ${j!==void 0?`CQ ${j}`:""}${T!==void 0?` CRF ${T}`:""}`)}if(w!==void 0||y!==void 0){if(p.av1={},w!==void 0)p.av1.cq=w;if(y!==void 0)p.av1.crf=y;console.log(`\uD83C\uDF9A️ AV1 Quality: ${w!==void 0?`CQ ${w}`:""}${y!==void 0?` CRF ${y}`:""}`)}}console.log(` +⚠️ Profile warnings:`),D.warnings.forEach((u)=>console.warn(` - ${u}`));aD=D.profiles.map((u)=>u.name)}else aD=AD(V.width,V.height,V.fps,V.videoBitrate).map((u)=>u.name);var D3=[r8?"DASH (manifest.mpd)":null,o8?"HLS (master.m3u8)":null].filter(Boolean).join(", "),u3=!0,F3=iD||"00:00:00",E3=[ID?"h264":null,HD?"av1":null].filter(Boolean).join(", "),C3=!HD&&oD.includes("av1")?" (AV1 disabled: no HW)":"",OF=uD&&uD.toUpperCase()||"CPU",LF=FD&&FD.toUpperCase()||"CPU",kF=e?e.toUpperCase():OF,QF=DD?DD.toUpperCase():LF,B3=kF==="AUTO"?OF:kF,A3=QF==="AUTO"?LF:QF,Z3=xF.join(", "),$3=MF.join(", ");console.log(` +\uD83D\uDCE6 Parameters:`);console.log(` Input: ${d}`);console.log(` Output: ${_F}`);console.log(` Codec: ${E3}${C3}`);console.log(` Profiles: ${aD.join(", ")}`);console.log(` Manifests: ${D3}`);console.log(` Poster: ${F3} (will be generated)`);console.log(` Thumbnails: ${u3?"yes (with VTT)":"no"}`);console.log(` Encoder: ${B3} (available: ${Z3})`);console.log(` Decoder: ${A3} (available: ${$3})`);var m;if(j!==void 0||T!==void 0||w!==void 0||y!==void 0){if(m={},j!==void 0||T!==void 0){if(m.h264={},j!==void 0)m.h264.cq=j;if(T!==void 0)m.h264.crf=T;console.log(`\uD83C\uDF9A️ H.264 Quality: ${j!==void 0?`CQ ${j}`:""}${T!==void 0?` CRF ${T}`:""}`)}if(w!==void 0||y!==void 0){if(m.av1={},w!==void 0)m.av1.cq=w;if(y!==void 0)m.av1.crf=y;console.log(`\uD83C\uDF9A️ AV1 Quality: ${w!==void 0?`CQ ${w}`:""}${y!==void 0?` CRF ${y}`:""}`)}}console.log(` \uD83D\uDE80 Starting conversion... -`);var ID=new aD.default.MultiBar({format:"{stage} | {bar} | {percentage}% | {name}",barCompleteChar:"█",barIncompleteChar:"░",hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0},aD.default.Presets.shades_classic),nD={},sD=null;try{let D=Date.now(),u=await PD({input:n,outputDir:QF,customProfiles:KD,posterTimecode:rD,codec:v,format:FD,segmentDuration:2,hardwareAccelerator:ED,hardwareDecoder:CD,quality:p,generateThumbnails:!0,generatePoster:!0,parallel:!0,onProgress:(C)=>{let A=C.stage==="encoding"?"Encoding":C.stage==="thumbnails"?"Thumbnails":C.stage==="manifest"?"Manifest":C.stage==="analyzing"?"Analyzing":"Complete";if(C.stage==="encoding"&&C.currentProfile){if(!nD[C.currentProfile])nD[C.currentProfile]=ID.create(100,0,{stage:"Encode",name:C.currentProfile});let B=C.profilePercent??C.percent;nD[C.currentProfile].update(B,{stage:"Encode",name:C.currentProfile})}if(!sD)sD=ID.create(100,0,{stage:A,name:"Overall"});sD.update(C.percent,{stage:A,name:C.message||"Overall"})}});ID.stop();let E=((Date.now()-D)/1000).toFixed(2);console.log(` +`);var _D=new sD.default.MultiBar({format:"{stage} | {bar} | {percentage}% | {name}",barCompleteChar:"█",barIncompleteChar:"░",hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0},sD.default.Presets.shades_classic),dD={},nD=null;try{let D=Date.now(),u=await vD({input:d,outputDir:_F,customProfiles:ZD,posterTimecode:iD,codec:[...ID?["h264"]:[],...HD?["av1"]:[]],segmentDuration:2,hardwareAccelerator:e,hardwareDecoder:DD,quality:m,generateThumbnails:!0,generatePoster:!0,parallel:!0,onProgress:(C)=>{let A=C.stage==="encoding"?"Encoding":C.stage==="thumbnails"?"Thumbnails":C.stage==="manifest"?"Manifest":C.stage==="analyzing"?"Analyzing":"Complete";if(C.stage==="encoding"&&C.currentProfile){if(!dD[C.currentProfile])dD[C.currentProfile]=_D.create(100,0,{stage:"Encode",name:C.currentProfile});let B=C.profilePercent??C.percent;dD[C.currentProfile].update(B,{stage:"Encode",name:C.currentProfile})}if(!nD)nD=_D.create(100,0,{stage:A,name:"Overall"});nD.update(C.percent,{stage:A,name:C.message||"Overall"})}});_D.stop();let E=((Date.now()-D)/1000).toFixed(2);console.log(` ✅ Conversion completed successfully! (${E}s) -`)}catch(D){ID.stop(),console.error(` +`)}catch(D){_D.stop(),console.error(` ❌ Error during conversion:`),console.error(D),process.exit(1)} diff --git a/src/cli.ts b/src/cli.ts index 9aa5426..116525d 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -14,15 +14,14 @@ import { convertToDash, checkFFmpeg, checkMP4Box, getVideoMetadata, detectHardwa import cliProgress from 'cli-progress'; import { statSync } from 'node:fs'; import { basename, extname } from 'node:path'; -import type { CodecChoice, StreamingFormatChoice, QualitySettings, HardwareAccelerationOption, HardwareAccelerator } from './types'; +import type { QualitySettings, HardwareAccelerationOption, HardwareAccelerator, CodecType } from './types'; import { selectProfiles, createProfilesFromStrings } from './config/profiles'; // Parse arguments const args = process.argv.slice(2); let customProfiles: string[] | undefined; let posterTimecode: string | undefined; -let codecChoice: CodecChoice = 'auto'; // h264 + AV1 if HW -let formatChoice: StreamingFormatChoice = 'auto'; // DASH + HLS +let codecChoice: Array | undefined; // default h264 const positionalArgs: string[] = []; // Quality settings @@ -57,22 +56,16 @@ for (let i = 0; i < args.length; i++) { posterTimecode = args[i + 1]; i++; // Skip next arg } else if (args[i] === '-c' || args[i] === '--codec') { - const codec = args[i + 1]; - if (codec === 'av1' || codec === 'h264') { - codecChoice = codec; - } else { - console.error(`❌ Invalid codec: ${codec}. Valid options: av1, h264`); - process.exit(1); - } - i++; // Skip next arg - } else if (args[i] === '-f' || args[i] === '--format') { - const format = args[i + 1]; - if (format === 'dash' || format === 'hls') { - formatChoice = format; - } else { - console.error(`❌ Invalid format: ${format}. Valid options: dash, hls`); - process.exit(1); + const codecArg = args[i + 1]; + const parts = codecArg.split(/[,\s]+/).map(p => p.trim()).filter(Boolean); + const allowed = new Set(['h264', 'av1']); + for (const p of parts) { + if (!allowed.has(p)) { + console.error(`❌ Invalid codec: ${p}. Valid options: av1, h264`); + process.exit(1); + } } + codecChoice = Array.from(new Set(parts)) as Array<'h264' | 'av1'>; i++; // Skip next arg } else if (args[i] === '--h264-cq') { h264CQ = parseInt(args[i + 1]); @@ -255,29 +248,24 @@ if (!hasMP4Box) { } // Resolve codec selection -let includeH264 = codecChoice === 'h264' || codecChoice === 'auto'; -let includeAv1 = codecChoice === 'av1' || codecChoice === 'auto'; +const codecsRequested = codecChoice && codecChoice.length > 0 ? codecChoice : ['h264']; +let includeH264 = codecsRequested.includes('h264'); +let includeAv1 = codecsRequested.includes('av1'); -if (includeAv1 && !hasAv1Hardware && codecChoice === 'auto') { - includeAv1 = false; +if (!includeH264) { + console.warn('⚠️ H.264 is mandatory for compatibility. Adding H.264.'); + includeH264 = true; } -if (codecChoice === 'av1' && !hasAv1Hardware) { - console.error(`⚠️ Warning: AV1 encoding requested but no hardware AV1 encoder found.`); +if (includeAv1 && !hasAv1Hardware) { + console.error(`⚠️ AV1 requested but no hardware AV1 encoder found.`); console.error(` CPU-based AV1 encoding (libsvtav1) will be VERY slow.`); console.error(` Consider using --codec h264 for faster encoding.\n`); } -// Resolve formats -const wantDash = formatChoice === 'dash' || formatChoice === 'auto'; -const wantHls = formatChoice === 'hls' || formatChoice === 'auto'; - -// Validate HLS requires H.264 -if (wantHls && !includeH264) { - console.error(`❌ Error: HLS format requires H.264 codec for Safari/iOS compatibility.`); - console.error(` Please use --codec h264 or omit --codec to keep H.264.\n`); - process.exit(1); -} +// Formats are always both +const wantDash = true; +const wantHls = true; // Get video metadata and file size console.log('📊 Analyzing video...\n'); @@ -343,7 +331,7 @@ const codecListDisplay = [ includeH264 ? 'h264' : null, includeAv1 ? 'av1' : null ].filter(Boolean).join(', '); -const codecNote = (!includeAv1 && codecChoice === 'auto' && !hasAv1Hardware) ? ' (AV1 disabled: no HW)' : ''; +const codecNote = (!includeAv1 && codecsRequested.includes('av1')) ? ' (AV1 disabled: no HW)' : ''; const bestAccelName = (bestAccel && bestAccel.toUpperCase()) || 'CPU'; const bestDecoderName = (bestDecoder && bestDecoder.toUpperCase()) || 'CPU'; const plannedAccel = accelerator ? accelerator.toUpperCase() : bestAccelName; @@ -407,8 +395,10 @@ try { outputDir, customProfiles, posterTimecode, - codec: codecChoice, - format: formatChoice, + codec: [ + ...(includeH264 ? ['h264'] as const : []), + ...(includeAv1 ? ['av1'] as const : []) + ], segmentDuration: 2, hardwareAccelerator: accelerator, hardwareDecoder: decoder, diff --git a/src/core/converter.ts b/src/core/converter.ts index 253dfc3..464b415 100644 --- a/src/core/converter.ts +++ b/src/core/converter.ts @@ -8,9 +8,7 @@ import type { ThumbnailConfig, ConversionProgress, CodecType, - CodecChoice, StreamingFormat, - StreamingFormatChoice, HardwareAccelerationOption, HardwareAccelerator, HardwareEncoderInfo, @@ -43,8 +41,8 @@ export async function convertToDash( segmentDuration = 2, profiles: userProfiles, customProfiles, - codec = 'auto', - format = 'auto', + codec = ['h264'], + formats = ['dash', 'hls'], hardwareDecoder, hardwareAccelerator, quality, @@ -76,8 +74,8 @@ DASH Conversion Log Started: ${new Date().toISOString()} Input: ${input} Output: ${videoOutputDir} -Codec: ${codec} -Format: ${format} +Codec: ${Array.isArray(codec) ? codec.join(',') : codec} +Formats: ${formats?.join(',') || 'dash,hls'} ===========================================\n`; await writeFile(logFile, header, 'utf-8'); @@ -90,7 +88,7 @@ Format: ${format} userProfiles, customProfiles, codec, - format, + formats, hardwareAccelerator, hardwareDecoder, quality, @@ -129,8 +127,8 @@ async function convertToDashInternal( segmentDuration: number, userProfiles: VideoProfile[] | undefined, customProfiles: string[] | undefined, - codec: CodecChoice, - format: StreamingFormatChoice, + codec: CodecType | CodecType[], + formats: StreamingFormat[] | undefined, hardwareAccelerator: HardwareAccelerationOption | undefined, hardwareDecoder: HardwareAccelerationOption | undefined, quality: DashConvertOptions['quality'], @@ -175,12 +173,9 @@ async function convertToDashInternal( const av1HardwareAvailable = hardwareEncoders.some(info => info.av1Encoder); - let wantH264 = codec === 'h264' || codec === 'auto'; - let wantAv1 = codec === 'av1' || codec === 'auto'; - - if (codec === 'auto' && !av1HardwareAvailable) { - wantAv1 = false; - } + const codecList = Array.isArray(codec) ? codec : [codec]; + const wantH264 = codecList.includes('h264'); + const wantAv1 = codecList.includes('av1'); const { selected, h264Encoder, av1Encoder, warnings: accelWarnings } = selectHardwareEncoders( hardwareEncoders, @@ -200,7 +195,7 @@ async function convertToDashInternal( hardwareDecoder || 'auto' ); - if (codec === 'av1' && !av1HardwareAvailable) { + if (wantAv1 && !av1HardwareAvailable) { console.warn('⚠️ AV1 hardware encoder not detected. AV1 will use CPU encoder (slow).'); } @@ -209,10 +204,7 @@ async function convertToDashInternal( if (wantAv1) codecsSelected.push('av1'); if (codecsSelected.length === 0) codecsSelected.push('h264'); - const formatsSelected: StreamingFormat[] = []; - if (format === 'dash' || format === 'auto') formatsSelected.push('dash'); - if (format === 'hls' || format === 'auto') formatsSelected.push('hls'); - if (formatsSelected.length === 0) formatsSelected.push('dash'); + const formatsSelected: StreamingFormat[] = formats && formats.length > 0 ? Array.from(new Set(formats)) : ['dash', 'hls']; // Select profiles let profiles: VideoProfile[]; diff --git a/src/index.ts b/src/index.ts index 823c8ea..cdcb2d3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,9 +11,7 @@ export type { VideoMetadata, VideoOptimizations, CodecType, - CodecChoice, StreamingFormat, - StreamingFormatChoice, HardwareAccelerator, HardwareAccelerationOption, HardwareEncoderInfo, diff --git a/src/types/index.ts b/src/types/index.ts index ceb1234..edcd961 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -8,16 +8,6 @@ export type CodecType = 'av1' | 'h264'; */ export type StreamingFormat = 'dash' | 'hls'; -/** - * Пользовательский выбор кодека (auto = h264 + av1 при наличии HW) - */ -export type CodecChoice = CodecType | 'auto'; - -/** - * Пользовательский выбор форматов (auto = dash + hls) - */ -export type StreamingFormatChoice = StreamingFormat | 'auto'; - /** * Тип аппаратного ускорителя */ @@ -85,11 +75,11 @@ export interface DashConvertOptions { /** Custom resolution profiles as strings (e.g., ['360p', '480p', '720p@60']) */ customProfiles?: string[]; - /** Video codec selection: h264, av1, or auto (default: auto = h264 + AV1 if HW) */ - codec?: CodecChoice; + /** Video codec selection: one or multiple (default: ['h264']) */ + codec?: CodecType | CodecType[]; - /** Streaming formats: dash, hls, or auto (default: auto = оба) */ - format?: StreamingFormatChoice; + /** Streaming formats: list (default: ['dash','hls']) */ + formats?: StreamingFormat[]; /** Предпочитаемый аппаратный ускоритель (auto по умолчанию) */ hardwareAccelerator?: HardwareAccelerationOption;