dev-toolkit-cli 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import fs from "fs/promises";
2
2
  import mime from "mime";
3
- import { getFolderFiles, replaceFilenameExtension, } from "../lib/utils/index.js";
4
- import { check_dependencies, ffmpeg_image_to_webp, ffmpeg_video_compress_webm, } from "../lib/bash.js";
3
+ import { addFilenameSuffix, getFolderFiles, replaceFilenameExtension, } from "../lib/utils/index.js";
4
+ import { check_dependencies, ffmpeg_image_to_webp, ffmpeg_compress_mp4_gpu, } from "../lib/bash.js";
5
5
  export const FileType = ["image", "video"];
6
6
  const unsupportedFormats = {
7
7
  image: ["image/webp", "image/gif", "image/svg+xml"],
@@ -13,7 +13,7 @@ export async function file(pathname, { verbose, type, resolution, force, horizon
13
13
  console.warn("⚠️ Ignoring already compressed files");
14
14
  if (horizontal)
15
15
  console.warn("⚠️ Forcing horizontal aspect ratio 16x9");
16
- let verbose_title = "";
16
+ // let verbose_title = "";
17
17
  const filePathList = await getFolderFiles(pathname, true);
18
18
  for (let filePath of filePathList) {
19
19
  const mimetype = mime.getType(filePath);
@@ -21,16 +21,17 @@ export async function file(pathname, { verbose, type, resolution, force, horizon
21
21
  continue;
22
22
  const fileType = mimetype.split("/")[0];
23
23
  if (!(type ? [type] : FileType).includes(fileType) ||
24
- (unsupportedFormats[fileType] || []).includes(mimetype))
24
+ (unsupportedFormats[fileType] || []).includes(mimetype) ||
25
+ filePath.includes(".compressed"))
25
26
  continue;
26
27
  const title = filePath
27
28
  .substring(pathname.length)
28
29
  .split("/")
29
30
  .slice(1, 1 + verbose)
30
31
  .join("/");
31
- if (title !== verbose_title)
32
- console.log(`Compressing ${fileType} at:`, title);
33
- verbose_title = title;
32
+ // if (title !== verbose_title)
33
+ // console.log(`Compressing ${fileType} at:`, title);
34
+ // verbose_title = title;
34
35
  try {
35
36
  if (fileType === "image")
36
37
  await compressImage(filePath);
@@ -51,7 +52,7 @@ async function compressImage(filePath) {
51
52
  await fs.rm(filePath);
52
53
  }
53
54
  async function compressVideo(filePath, resolution, force) {
54
- await ffmpeg_video_compress_webm(filePath, replaceFilenameExtension(filePath, "webm"), resolution, force);
55
+ await ffmpeg_compress_mp4_gpu(filePath, addFilenameSuffix(filePath, ".compressed"), resolution, force);
55
56
  await fs.rm(filePath);
56
57
  }
57
58
  //# sourceMappingURL=action-compress.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-compress.js","sourceRoot":"","sources":["../../src/actions/action-compress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,EAKL,cAAc,EAGd,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AAExB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,OAAO,CAAU,CAAC;AAGpD,MAAM,kBAAkB,GAAoC;IAC1D,KAAK,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,eAAe,CAAC;IACnD,KAAK,EAAE,CAAC,YAAY,CAAC;CACtB,CAAC;AAaF,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,QAAgB,EAChB,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAoB;IAElE,MAAM,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAErC,IAAI,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IAChE,IAAI,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IAExE,IAAI,aAAa,GAAG,EAAE,CAAC;IAEvB,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE1D,KAAK,IAAI,QAAQ,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAa,CAAC;QACpD,IACE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAoB,CAAC;YAC1D,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAEvD,SAAS;QAEX,MAAM,KAAK,GAAG,QAAQ;aACnB,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;aAC1B,KAAK,CAAC,GAAG,CAAC;aACV,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;aACrB,IAAI,CAAC,GAAG,CAAC,CAAC;QAEb,IAAI,KAAK,KAAK,aAAa;YACzB,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC;QAEpD,aAAa,GAAG,KAAK,CAAC;QAEtB,IAAI,CAAC;YACH,IAAI,QAAQ,KAAK,OAAO;gBAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;iBACnD,IAAI,QAAQ,KAAK,OAAO;gBAC3B,MAAM,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,OAAO,GAAG,EAAE;gBAAE,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;;gBACzD,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,QAAQ,GAAG,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAgB;IAC3C,MAAM,oBAAoB,CACxB,QAAQ,EACR,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC3C,CAAC;IACF,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,QAAgB,EAChB,UAAsB,EACtB,KAAe;IAEf,MAAM,0BAA0B,CAC9B,QAAQ,EACR,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC1C,UAAU,EACV,KAAK,CACN,CAAC;IACF,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"action-compress.js","sourceRoot":"","sources":["../../src/actions/action-compress.ts"],"names":[],"mappings":"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"}
package/bin/lib/bash.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { exec } from "child_process";
2
+ import { resolutionMapping } from "./constants.js";
2
3
  import { CommanderError } from "commander";
3
4
  import * as os from "os";
4
5
  export const execAsync = (command) => new Promise((resolve, reject) => {
@@ -27,9 +28,6 @@ export async function check_dependencies(dependencies = globalDependencies) {
27
28
  }
28
29
  // Cache para não termos que detectar a GPU toda vez que formos comprimir um vídeo
29
30
  let cachedGpuType = null;
30
- /**
31
- * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
32
- */
33
31
  async function detectGPU() {
34
32
  if (cachedGpuType)
35
33
  return cachedGpuType;
@@ -60,47 +58,149 @@ async function detectGPU() {
60
58
  }
61
59
  return cachedGpuType;
62
60
  }
63
- export async function ffmpeg_video_compress_webm(input, output, resolution = "480p", forceResolution) {
64
- const resolutionMapping = {
65
- "4320p": { w: 7680, h: 4320 }, // 8K
66
- "2160p": { w: 3840, h: 2160 }, // 4K
67
- "1440p": { w: 2560, h: 1440 }, // Quad HD
68
- "1080p": { w: 1920, h: 1080 }, // Full HD
69
- "720p": { w: 1280, h: 720 }, // HD
70
- "480p": { w: 854, h: 480 }, // SD (WVGA)
71
- "360p": { w: 640, h: 360 }, // nHD
72
- "240p": { w: 426, h: 240 }, // WQVGA
73
- };
74
- const { w, h } = resolutionMapping[resolution];
61
+ export async function ffmpeg_video_to_webm(input, output) {
75
62
  const gpu = await detectGPU();
76
63
  const isLinux = os.platform() === "linux";
77
- // Utilizamos o codec VP9, que é o padrão moderno de alta qualidade para vídeos WebM
64
+ // 1. Mapeia os Encoders VP9 para usar as GPUs
78
65
  const encoders = {
79
66
  nvidia: "-c:v vp9_nvenc -preset p4",
80
67
  amd: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_amf",
81
68
  intel: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_qsv",
82
- mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
69
+ mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4", // Fallback (Mac não expõe VP9 nativo no FFmpeg)
83
70
  cpu: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
84
71
  };
85
72
  const vcodec = encoders[gpu] || encoders.cpu;
86
- let hwaccel = gpu === "cpu" || gpu === "mac" ? "" : "-hwaccel auto";
73
+ let hwaccel = "";
74
+ let videoFilter = "";
75
+ // 2. Lógica VA-API (Linux) para manter todo o fluxo de frames na GPU
76
+ if (isLinux && (gpu === "amd" || gpu === "intel")) {
77
+ // Estas flags transferem a decodificação para a GPU e mantêm os frames na memória de vídeo
78
+ hwaccel =
79
+ "-hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi";
80
+ // Como não vamos mudar a resolução, o filtro apenas formata e sobe para a GPU caso o input não venha em formato compatível
81
+ videoFilter = `-vf "format=nv12,hwupload"`;
82
+ }
83
+ else if (gpu === "nvidia" || gpu === "amd" || gpu === "intel") {
84
+ hwaccel = "-hwaccel auto";
85
+ }
86
+ // 3. Áudio para WebM
87
+ const acodec = "-c:a libopus -b:a 128k";
88
+ // 4. Monta o comando (removido o -s e -filter:v de redimensionamento)
89
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter ? videoFilter : ""} ${vcodec} ${acodec} -f webm -y "${output}"`;
90
+ console.log(`Compressing video [${gpu}]:`, input);
91
+ return execAsync(command);
92
+ }
93
+ // /**
94
+ // * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
95
+ // */
96
+ // async function detectGPU(): Promise<GpuType> {
97
+ // if (cachedGpuType) return cachedGpuType;
98
+ // const platform = os.platform();
99
+ // try {
100
+ // if (platform === "darwin") return (cachedGpuType = "mac");
101
+ // let output = "";
102
+ // if (platform === "win32") {
103
+ // const stdout = await execAsync(
104
+ // "wmic path win32_VideoController get name",
105
+ // );
106
+ // output = stdout.toLowerCase();
107
+ // } else if (platform === "linux") {
108
+ // const stdout = await execAsync("lspci");
109
+ // output = stdout.toLowerCase();
110
+ // }
111
+ // if (output.includes("nvidia")) cachedGpuType = "nvidia";
112
+ // else if (output.includes("amd") || output.includes("radeon"))
113
+ // cachedGpuType = "amd";
114
+ // else if (output.includes("intel")) cachedGpuType = "intel";
115
+ // else cachedGpuType = "cpu";
116
+ // } catch (error) {
117
+ // cachedGpuType = "cpu";
118
+ // }
119
+ // return cachedGpuType;
120
+ // }
121
+ // export async function ffmpeg_video_compress_webm(
122
+ // input: string,
123
+ // output: string,
124
+ // resolution: Resolution = "480p",
125
+ // forceResolution?: boolean,
126
+ // ) {
127
+ // const { w, h } = resolutionMapping[resolution];
128
+ // const gpu = await detectGPU();
129
+ // const isLinux = os.platform() === "linux";
130
+ // // 1. Mapeia os Encoders para o codec VP9
131
+ // const encoders = {
132
+ // nvidia: "-c:v vp9_nvenc -preset p4",
133
+ // // Removemos o vp9_vaapi da AMD no Linux, caindo para a CPU (libvpx-vp9)
134
+ // amd: isLinux ? "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4" : "-c:v vp9_amf",
135
+ // intel: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_qsv", // Intel costuma suportar melhor vp9_vaapi, mas pode dar o mesmo erro dependendo da geração
136
+ // mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
137
+ // cpu: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
138
+ // };
139
+ // const vcodec = encoders[gpu] || encoders.cpu;
140
+ // // 2. Só ativamos o hwaccel se NÃO formos usar a CPU (libvpx-vp9)
141
+ // // Como a AMD no Linux agora usa libvpx-vp9, ela entra na regra de desativar o hwaccel para encode
142
+ // const isUsingCpuEncoder = vcodec.includes("libvpx");
143
+ // let hwaccel = isUsingCpuEncoder ? "" : "-hwaccel auto";
144
+ // let videoFilter = "";
145
+ // // 3. Lógica específica VA-API (agora só ativada se a Intel for usar hardware)
146
+ // if (isLinux && !isUsingCpuEncoder && gpu === "intel") {
147
+ // hwaccel = "-vaapi_device /dev/dri/renderD128";
148
+ // videoFilter = forceResolution
149
+ // ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
150
+ // : `-vf "scale=-1:${h},format=nv12,hwupload"`;
151
+ // } else {
152
+ // // Escala normal via CPU (necessária para o libvpx-vp9)
153
+ // videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
154
+ // }
155
+ // // O vídeo WebM necessita de codecs de áudio específicos como o Opus
156
+ // const acodec = "-c:a libopus -b:a 128k";
157
+ // // A flag '-f webm' força explicitamente a criação de um contentor de vídeo WebM
158
+ // const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} -f webm -y "${output}"`;
159
+ // return execAsync(command);
160
+ // }
161
+ /**
162
+ * Comprime vídeo para MP4 (H.264) utilizando a GPU disponível com taxa de compressão otimizada.
163
+ */
164
+ export async function ffmpeg_compress_mp4_gpu(input, output, // O arquivo deve terminar em .mp4
165
+ resolution = "480p", forceResolution) {
166
+ const { w, h } = resolutionMapping[resolution];
167
+ const gpu = await detectGPU();
168
+ const isLinux = os.platform() === "linux";
169
+ // 1. Mapeia os Encoders H.264 com equivalência de compressão (Qualidade vs Tamanho)
170
+ // O valor 28 é o "sweet spot". Menor = mais qualidade/mais pesado. Maior = menos qualidade/mais leve.
171
+ const encoders = {
172
+ nvidia: "-c:v h264_nvenc -preset p4 -cq 28",
173
+ amd: isLinux ? "-c:v h264_vaapi -qp 28" : "-c:v h264_amf -qp_i 28 -qp_p 28",
174
+ intel: isLinux
175
+ ? "-c:v h264_vaapi -qp 28"
176
+ : "-c:v h264_qsv -global_quality 28",
177
+ mac: "-c:v h264_videotoolbox -q:v 60", // No Mac a escala é diferente, 60 é um bom balanço
178
+ cpu: "-c:v libx264 -preset fast -crf 28",
179
+ };
180
+ const vcodec = encoders[gpu] || encoders.cpu;
181
+ let hwaccel = gpu === "cpu" ? "" : "-hwaccel auto";
87
182
  let videoFilter = "";
183
+ // 2. Define a string base do redimensionamento (Scale)
184
+ const scaleStr = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
185
+ // 3. Aplica o filtro correto baseado na necessidade de VA-API no Linux
88
186
  if (isLinux && (gpu === "amd" || gpu === "intel")) {
89
187
  hwaccel = "-vaapi_device /dev/dri/renderD128";
90
- videoFilter = forceResolution
91
- ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
92
- : `-vf "scale=-1:${h},format=nv12,hwupload"`;
188
+ // Integra a resolução e o upload para a GPU no mesmo filtro
189
+ videoFilter = `-vf "${scaleStr},format=nv12,hwupload"`;
93
190
  }
94
191
  else {
95
- videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
192
+ // Para NVIDIA, Mac e Windows, o scale simples via software antes de subir pra GPU funciona melhor
193
+ videoFilter = `-vf "${scaleStr}"`;
96
194
  }
97
- // O vídeo WebM necessita de codecs de áudio específicos como o Opus
98
- const acodec = "-c:a libopus -b:a 128k";
99
- // A flag '-f webm' força explicitamente a criação de um contentor de vídeo WebM
100
- const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} -f webm -y "${output}"`;
195
+ // 4. Áudio AAC universal e forçamento do container MP4
196
+ const acodec = "-c:a aac -b:a 128k";
197
+ const format = "-f mp4";
198
+ // 5. Monta e executa o comando final
199
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} ${format} -y "${output}"`;
101
200
  return execAsync(command);
102
201
  }
103
202
  export async function ffmpeg_image_to_webp(input, output) {
203
+ console.log(`Compressing image:`, input);
104
204
  return execAsync(`ffmpeg -i "${input}" -c:v libwebp "${output}"`);
105
205
  }
106
206
  //# sourceMappingURL=bash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/lib/bash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/lib/bash.ts"],"names":[],"mappings":"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"}
@@ -1,36 +1,12 @@
1
1
  export const resolutionMapping = {
2
- "4320p": {
3
- w: 7680,
4
- h: 4320,
5
- },
6
- "2160p": {
7
- w: 3840,
8
- h: 2160,
9
- },
10
- "1440p": {
11
- w: 2560,
12
- h: 1440,
13
- },
14
- "1080p": {
15
- w: 1920,
16
- h: 1080,
17
- },
18
- "720p": {
19
- w: 1280,
20
- h: 720,
21
- },
22
- "480p": {
23
- w: 854,
24
- h: 480,
25
- },
26
- "360p": {
27
- w: 640,
28
- h: 360,
29
- },
30
- "240p": {
31
- w: 426,
32
- h: 240,
33
- },
2
+ "4320p": { w: 7680, h: 4320 }, // 8K
3
+ "2160p": { w: 3840, h: 2160 }, // 4K
4
+ "1440p": { w: 2560, h: 1440 }, // Quad HD
5
+ "1080p": { w: 1920, h: 1080 }, // Full HD
6
+ "720p": { w: 1280, h: 720 }, // HD
7
+ "480p": { w: 854, h: 480 }, // SD (WVGA)
8
+ "360p": { w: 640, h: 360 }, // nHD
9
+ "240p": { w: 426, h: 240 }, // WQVGA
34
10
  };
35
11
  export const Resolution = [
36
12
  "4320p",
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,OAAO,EAAE;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;IACD,OAAO,EAAE;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;IACD,OAAO,EAAE;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;IACD,OAAO,EAAE;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACR;IACD,MAAM,EAAE;QACN,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,GAAG;KACP;IACD,MAAM,EAAE;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;KACP;IACD,MAAM,EAAE;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;KACP;IACD,MAAM,EAAE;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;KACP;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAE1B;IACF,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK;IACpC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK;IACpC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,UAAU;IACzC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,UAAU;IACzC,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,YAAY;IACxC,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,MAAM;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ;CACrC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-toolkit-cli",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "repository": "https://github.com/daviinacio/dev-toolkit",
5
5
  "author": "Davi Inácio <aazz6850@gmail.com>",
6
6
  "license": "MIT",
@@ -6,6 +6,7 @@ import path from "path";
6
6
  import { Resolution } from "../lib/constants.js";
7
7
  import {
8
8
  addFilenamePrefix,
9
+ addFilenameSuffix,
9
10
  getAvailablePathname,
10
11
  getDirectory,
11
12
  getFilename,
@@ -17,7 +18,7 @@ import {
17
18
  import {
18
19
  check_dependencies,
19
20
  ffmpeg_image_to_webp,
20
- ffmpeg_video_compress_webm,
21
+ ffmpeg_compress_mp4_gpu,
21
22
  } from "../lib/bash.js";
22
23
 
23
24
  export const FileType = ["image", "video"] as const;
@@ -48,7 +49,7 @@ export async function file(
48
49
  if (force) console.warn("⚠️ Ignoring already compressed files");
49
50
  if (horizontal) console.warn("⚠️ Forcing horizontal aspect ratio 16x9");
50
51
 
51
- let verbose_title = "";
52
+ // let verbose_title = "";
52
53
 
53
54
  const filePathList = await getFolderFiles(pathname, true);
54
55
 
@@ -58,7 +59,8 @@ export async function file(
58
59
  const fileType = mimetype.split("/")[0] as FileType;
59
60
  if (
60
61
  !(type ? [type] : FileType).includes(fileType as FileType) ||
61
- (unsupportedFormats[fileType] || []).includes(mimetype)
62
+ (unsupportedFormats[fileType] || []).includes(mimetype) ||
63
+ filePath.includes(".compressed")
62
64
  )
63
65
  continue;
64
66
 
@@ -68,10 +70,10 @@ export async function file(
68
70
  .slice(1, 1 + verbose)
69
71
  .join("/");
70
72
 
71
- if (title !== verbose_title)
72
- console.log(`Compressing ${fileType} at:`, title);
73
+ // if (title !== verbose_title)
74
+ // console.log(`Compressing ${fileType} at:`, title);
73
75
 
74
- verbose_title = title;
76
+ // verbose_title = title;
75
77
 
76
78
  try {
77
79
  if (fileType === "image") await compressImage(filePath);
@@ -99,9 +101,9 @@ async function compressVideo(
99
101
  resolution: Resolution,
100
102
  force?: boolean,
101
103
  ) {
102
- await ffmpeg_video_compress_webm(
104
+ await ffmpeg_compress_mp4_gpu(
103
105
  filePath,
104
- replaceFilenameExtension(filePath, "webm"),
106
+ addFilenameSuffix(filePath, ".compressed"),
105
107
  resolution,
106
108
  force,
107
109
  );
package/src/lib/bash.ts CHANGED
@@ -41,9 +41,6 @@ type GpuType = "nvidia" | "amd" | "intel" | "mac" | "cpu";
41
41
  // Cache para não termos que detectar a GPU toda vez que formos comprimir um vídeo
42
42
  let cachedGpuType: GpuType | null = null;
43
43
 
44
- /**
45
- * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
46
- */
47
44
  async function detectGPU(): Promise<GpuType> {
48
45
  if (cachedGpuType) return cachedGpuType;
49
46
  const platform = os.platform();
@@ -73,59 +70,183 @@ async function detectGPU(): Promise<GpuType> {
73
70
  return cachedGpuType;
74
71
  }
75
72
 
76
- export async function ffmpeg_video_compress_webm(
73
+ export async function ffmpeg_video_to_webm(
77
74
  input: string,
78
- output: string,
79
- resolution: Resolution = "480p",
80
- forceResolution?: boolean,
75
+ output: string, // O arquivo deve terminar em .webm
81
76
  ) {
82
- const resolutionMapping: { [key in Resolution]: { w: number; h: number } } = {
83
- "4320p": { w: 7680, h: 4320 }, // 8K
84
- "2160p": { w: 3840, h: 2160 }, // 4K
85
- "1440p": { w: 2560, h: 1440 }, // Quad HD
86
- "1080p": { w: 1920, h: 1080 }, // Full HD
87
- "720p": { w: 1280, h: 720 }, // HD
88
- "480p": { w: 854, h: 480 }, // SD (WVGA)
89
- "360p": { w: 640, h: 360 }, // nHD
90
- "240p": { w: 426, h: 240 }, // WQVGA
91
- };
92
-
93
- const { w, h } = resolutionMapping[resolution];
94
77
  const gpu = await detectGPU();
95
78
  const isLinux = os.platform() === "linux";
96
79
 
97
- // Utilizamos o codec VP9, que é o padrão moderno de alta qualidade para vídeos WebM
80
+ // 1. Mapeia os Encoders VP9 para usar as GPUs
98
81
  const encoders = {
99
82
  nvidia: "-c:v vp9_nvenc -preset p4",
100
83
  amd: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_amf",
101
84
  intel: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_qsv",
102
- mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
85
+ mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4", // Fallback (Mac não expõe VP9 nativo no FFmpeg)
103
86
  cpu: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
104
87
  };
105
88
 
106
89
  const vcodec = encoders[gpu] || encoders.cpu;
107
90
 
108
- let hwaccel = gpu === "cpu" || gpu === "mac" ? "" : "-hwaccel auto";
91
+ let hwaccel = "";
109
92
  let videoFilter = "";
110
93
 
94
+ // 2. Lógica VA-API (Linux) para manter todo o fluxo de frames na GPU
95
+ if (isLinux && (gpu === "amd" || gpu === "intel")) {
96
+ // Estas flags transferem a decodificação para a GPU e mantêm os frames na memória de vídeo
97
+ hwaccel =
98
+ "-hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi";
99
+ // Como não vamos mudar a resolução, o filtro apenas formata e sobe para a GPU caso o input não venha em formato compatível
100
+ videoFilter = `-vf "format=nv12,hwupload"`;
101
+ } else if (gpu === "nvidia" || gpu === "amd" || gpu === "intel") {
102
+ hwaccel = "-hwaccel auto";
103
+ }
104
+
105
+ // 3. Áudio para WebM
106
+ const acodec = "-c:a libopus -b:a 128k";
107
+
108
+ // 4. Monta o comando (removido o -s e -filter:v de redimensionamento)
109
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter ? videoFilter : ""} ${vcodec} ${acodec} -f webm -y "${output}"`;
110
+
111
+ console.log(`Compressing video [${gpu}]:`, input);
112
+
113
+ return execAsync(command);
114
+ }
115
+
116
+ // /**
117
+ // * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
118
+ // */
119
+ // async function detectGPU(): Promise<GpuType> {
120
+ // if (cachedGpuType) return cachedGpuType;
121
+ // const platform = os.platform();
122
+
123
+ // try {
124
+ // if (platform === "darwin") return (cachedGpuType = "mac");
125
+
126
+ // let output = "";
127
+ // if (platform === "win32") {
128
+ // const stdout = await execAsync(
129
+ // "wmic path win32_VideoController get name",
130
+ // );
131
+ // output = stdout.toLowerCase();
132
+ // } else if (platform === "linux") {
133
+ // const stdout = await execAsync("lspci");
134
+ // output = stdout.toLowerCase();
135
+ // }
136
+
137
+ // if (output.includes("nvidia")) cachedGpuType = "nvidia";
138
+ // else if (output.includes("amd") || output.includes("radeon"))
139
+ // cachedGpuType = "amd";
140
+ // else if (output.includes("intel")) cachedGpuType = "intel";
141
+ // else cachedGpuType = "cpu";
142
+ // } catch (error) {
143
+ // cachedGpuType = "cpu";
144
+ // }
145
+ // return cachedGpuType;
146
+ // }
147
+
148
+ // export async function ffmpeg_video_compress_webm(
149
+ // input: string,
150
+ // output: string,
151
+ // resolution: Resolution = "480p",
152
+ // forceResolution?: boolean,
153
+ // ) {
154
+ // const { w, h } = resolutionMapping[resolution];
155
+ // const gpu = await detectGPU();
156
+ // const isLinux = os.platform() === "linux";
157
+
158
+ // // 1. Mapeia os Encoders para o codec VP9
159
+ // const encoders = {
160
+ // nvidia: "-c:v vp9_nvenc -preset p4",
161
+ // // Removemos o vp9_vaapi da AMD no Linux, caindo para a CPU (libvpx-vp9)
162
+ // amd: isLinux ? "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4" : "-c:v vp9_amf",
163
+ // intel: isLinux ? "-c:v vp9_vaapi" : "-c:v vp9_qsv", // Intel costuma suportar melhor vp9_vaapi, mas pode dar o mesmo erro dependendo da geração
164
+ // mac: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
165
+ // cpu: "-c:v libvpx-vp9 -row-mt 1 -cpu-used 4",
166
+ // };
167
+
168
+ // const vcodec = encoders[gpu] || encoders.cpu;
169
+
170
+ // // 2. Só ativamos o hwaccel se NÃO formos usar a CPU (libvpx-vp9)
171
+ // // Como a AMD no Linux agora usa libvpx-vp9, ela entra na regra de desativar o hwaccel para encode
172
+ // const isUsingCpuEncoder = vcodec.includes("libvpx");
173
+ // let hwaccel = isUsingCpuEncoder ? "" : "-hwaccel auto";
174
+ // let videoFilter = "";
175
+
176
+ // // 3. Lógica específica VA-API (agora só ativada se a Intel for usar hardware)
177
+ // if (isLinux && !isUsingCpuEncoder && gpu === "intel") {
178
+ // hwaccel = "-vaapi_device /dev/dri/renderD128";
179
+ // videoFilter = forceResolution
180
+ // ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
181
+ // : `-vf "scale=-1:${h},format=nv12,hwupload"`;
182
+ // } else {
183
+ // // Escala normal via CPU (necessária para o libvpx-vp9)
184
+ // videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
185
+ // }
186
+
187
+ // // O vídeo WebM necessita de codecs de áudio específicos como o Opus
188
+ // const acodec = "-c:a libopus -b:a 128k";
189
+
190
+ // // A flag '-f webm' força explicitamente a criação de um contentor de vídeo WebM
191
+ // const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} -f webm -y "${output}"`;
192
+
193
+ // return execAsync(command);
194
+ // }
195
+
196
+ /**
197
+ * Comprime vídeo para MP4 (H.264) utilizando a GPU disponível com taxa de compressão otimizada.
198
+ */
199
+ export async function ffmpeg_compress_mp4_gpu(
200
+ input: string,
201
+ output: string, // O arquivo deve terminar em .mp4
202
+ resolution: Resolution = "480p",
203
+ forceResolution?: boolean,
204
+ ) {
205
+ const { w, h } = resolutionMapping[resolution];
206
+ const gpu = await detectGPU();
207
+ const isLinux = os.platform() === "linux";
208
+
209
+ // 1. Mapeia os Encoders H.264 com equivalência de compressão (Qualidade vs Tamanho)
210
+ // O valor 28 é o "sweet spot". Menor = mais qualidade/mais pesado. Maior = menos qualidade/mais leve.
211
+ const encoders = {
212
+ nvidia: "-c:v h264_nvenc -preset p4 -cq 28",
213
+ amd: isLinux ? "-c:v h264_vaapi -qp 28" : "-c:v h264_amf -qp_i 28 -qp_p 28",
214
+ intel: isLinux
215
+ ? "-c:v h264_vaapi -qp 28"
216
+ : "-c:v h264_qsv -global_quality 28",
217
+ mac: "-c:v h264_videotoolbox -q:v 60", // No Mac a escala é diferente, 60 é um bom balanço
218
+ cpu: "-c:v libx264 -preset fast -crf 28",
219
+ };
220
+
221
+ const vcodec = encoders[gpu] || encoders.cpu;
222
+
223
+ let hwaccel = gpu === "cpu" ? "" : "-hwaccel auto";
224
+ let videoFilter = "";
225
+
226
+ // 2. Define a string base do redimensionamento (Scale)
227
+ const scaleStr = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
228
+
229
+ // 3. Aplica o filtro correto baseado na necessidade de VA-API no Linux
111
230
  if (isLinux && (gpu === "amd" || gpu === "intel")) {
112
231
  hwaccel = "-vaapi_device /dev/dri/renderD128";
113
- videoFilter = forceResolution
114
- ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
115
- : `-vf "scale=-1:${h},format=nv12,hwupload"`;
232
+ // Integra a resolução e o upload para a GPU no mesmo filtro
233
+ videoFilter = `-vf "${scaleStr},format=nv12,hwupload"`;
116
234
  } else {
117
- videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
235
+ // Para NVIDIA, Mac e Windows, o scale simples via software antes de subir pra GPU funciona melhor
236
+ videoFilter = `-vf "${scaleStr}"`;
118
237
  }
119
238
 
120
- // O vídeo WebM necessita de codecs de áudio específicos como o Opus
121
- const acodec = "-c:a libopus -b:a 128k";
239
+ // 4. Áudio AAC universal e forçamento do container MP4
240
+ const acodec = "-c:a aac -b:a 128k";
241
+ const format = "-f mp4";
122
242
 
123
- // A flag '-f webm' força explicitamente a criação de um contentor de vídeo WebM
124
- const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} -f webm -y "${output}"`;
243
+ // 5. Monta e executa o comando final
244
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} ${acodec} ${format} -y "${output}"`;
125
245
 
126
246
  return execAsync(command);
127
247
  }
128
248
 
129
249
  export async function ffmpeg_image_to_webp(input: string, output: string) {
250
+ console.log(`Compressing image:`, input);
130
251
  return execAsync(`ffmpeg -i "${input}" -c:v libwebp "${output}"`);
131
252
  }
@@ -1,37 +1,15 @@
1
- export const resolutionMapping = {
2
- "4320p": {
3
- w: 7680,
4
- h: 4320,
5
- },
6
- "2160p": {
7
- w: 3840,
8
- h: 2160,
9
- },
10
- "1440p": {
11
- w: 2560,
12
- h: 1440,
13
- },
14
- "1080p": {
15
- w: 1920,
16
- h: 1080,
17
- },
18
- "720p": {
19
- w: 1280,
20
- h: 720,
21
- },
22
- "480p": {
23
- w: 854,
24
- h: 480,
25
- },
26
- "360p": {
27
- w: 640,
28
- h: 360,
29
- },
30
- "240p": {
31
- w: 426,
32
- h: 240,
33
- },
34
- } as const;
1
+ export const resolutionMapping: {
2
+ [key in Resolution]: { w: number; h: number };
3
+ } = {
4
+ "4320p": { w: 7680, h: 4320 }, // 8K
5
+ "2160p": { w: 3840, h: 2160 }, // 4K
6
+ "1440p": { w: 2560, h: 1440 }, // Quad HD
7
+ "1080p": { w: 1920, h: 1080 }, // Full HD
8
+ "720p": { w: 1280, h: 720 }, // HD
9
+ "480p": { w: 854, h: 480 }, // SD (WVGA)
10
+ "360p": { w: 640, h: 360 }, // nHD
11
+ "240p": { w: 426, h: 240 }, // WQVGA
12
+ };
35
13
 
36
14
  export const Resolution = [
37
15
  "4320p",
@@ -43,5 +21,4 @@ export const Resolution = [
43
21
  "360p",
44
22
  "240p",
45
23
  ] as const;
46
-
47
24
  export type Resolution = (typeof Resolution)[number];