dev-toolkit-cli 1.0.4 → 1.0.6

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.
package/bin/lib/bash.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { exec } from "child_process";
2
- import { resolutionMapping } from "./constants.js";
3
2
  import { CommanderError } from "commander";
3
+ import * as os from "os";
4
4
  export const execAsync = (command) => new Promise((resolve, reject) => {
5
5
  exec(command, (error, stdout, stderr) => {
6
6
  if (error)
@@ -25,40 +25,138 @@ export async function check_dependencies(dependencies = globalDependencies) {
25
25
  throw new CommanderError(1, "missing_dependencies", missing_dependencies.map((dep) => `'${dep}'`).join(", "));
26
26
  }
27
27
  }
28
- async function getBestEncoder() {
28
+ // Cache para não termos que detectar a GPU toda vez que formos comprimir um vídeo
29
+ let cachedGpuType = null;
30
+ /**
31
+ * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
32
+ */
33
+ async function detectGPU() {
34
+ if (cachedGpuType)
35
+ return cachedGpuType; // Retorna do cache se já sabemos
36
+ const platform = os.platform();
29
37
  try {
30
- const { stdout } = (await execAsync("ffmpeg -encoders"));
31
- // Prioridade para AMD (Windows: amf | Linux: vaapi)
32
- if (stdout.includes("h264_amf"))
33
- return "h264_amf";
34
- if (stdout.includes("h264_vaapi"))
35
- return "h264_vaapi";
36
- // Outros hardwares
37
- if (stdout.includes("h264_nvenc"))
38
- return "h264_nvenc";
39
- if (stdout.includes("h264_qsv"))
40
- return "h264_qsv";
41
- if (stdout.includes("h264_videotoolbox"))
42
- return "h264_videotoolbox";
43
- return "libx264"; // Fallback
38
+ // Se for Mac, assume VideoToolbox (Aceleração nativa da Apple)
39
+ if (platform === "darwin") {
40
+ cachedGpuType = "mac";
41
+ return cachedGpuType;
42
+ }
43
+ let output = "";
44
+ // Se for Windows, usa o WMIC para listar as placas de vídeo
45
+ if (platform === "win32") {
46
+ const stdout = await execAsync("wmic path win32_VideoController get name");
47
+ output = stdout.toLowerCase();
48
+ }
49
+ // Se for Linux, usa o lspci para listar os hardwares PCI
50
+ else if (platform === "linux") {
51
+ const stdout = await execAsync("lspci");
52
+ output = stdout.toLowerCase();
53
+ }
54
+ // Analisa a saída dos comandos para descobrir a marca
55
+ if (output.includes("nvidia")) {
56
+ cachedGpuType = "nvidia";
57
+ }
58
+ else if (output.includes("amd") || output.includes("radeon")) {
59
+ cachedGpuType = "amd";
60
+ }
61
+ else if (output.includes("intel")) {
62
+ cachedGpuType = "intel";
63
+ }
64
+ else {
65
+ cachedGpuType = "cpu"; // Fallback se não identificar nada
66
+ }
44
67
  }
45
- catch {
46
- return "libx264";
68
+ catch (error) {
69
+ if (error instanceof Error)
70
+ console.warn("⚠️ Aviso: Falha ao detectar GPU. Usando CPU por segurança.", error.message);
71
+ cachedGpuType = "cpu";
47
72
  }
73
+ return cachedGpuType;
48
74
  }
49
75
  export async function ffmpeg_video_compress(input, output, resolution = "480p", forceResolution) {
76
+ // Exemplo de mapeamento (ajuste para bater com o seu código original)
77
+ const resolutionMapping = {
78
+ "4320p": { w: 7680, h: 4320 }, // 8K
79
+ "2160p": { w: 3840, h: 2160 }, // 4K
80
+ "1440p": { w: 2560, h: 1440 }, // Quad HD
81
+ "1080p": { w: 1920, h: 1080 }, // Full HD
82
+ "720p": { w: 1280, h: 720 }, // HD
83
+ "480p": { w: 854, h: 480 }, // SD (WVGA)
84
+ "360p": { w: 640, h: 360 }, // nHD
85
+ "240p": { w: 426, h: 240 }, // WQVGA
86
+ };
50
87
  const { w, h } = resolutionMapping[resolution];
51
- const encoder = await getBestEncoder();
52
- // No VA-API (Linux), o redimensionamento deve ser feito via hardware para máxima performance
53
- let filter = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
54
- if (encoder === "h264_vaapi") {
55
- // Adiciona upload para hardware se usar vaapi
56
- filter = `format=nv12,hwupload,scale_vaapi=w=${forceResolution ? w : -1}:h=${h}`;
88
+ // 1. Detecta a GPU automaticamente
89
+ const gpu = await detectGPU();
90
+ // 2. Verifica se é Linux para usar a estratégia correta
91
+ const isLinux = os.platform() === "linux";
92
+ // Mapeia os Encoders. Nota: AMD e Intel no Linux usam VA-API
93
+ const encoders = {
94
+ nvidia: "-c:v h264_nvenc -preset p4",
95
+ amd: isLinux ? "-c:v h264_vaapi" : "-c:v h264_amf",
96
+ intel: isLinux ? "-c:v h264_vaapi" : "-c:v h264_qsv",
97
+ mac: "-c:v h264_videotoolbox",
98
+ cpu: "-c:v libx264 -preset fast",
99
+ };
100
+ const vcodec = encoders[gpu] || encoders.cpu;
101
+ // 3. Configura a aceleração e os filtros
102
+ let hwaccel = gpu === "cpu" ? "" : "-hwaccel auto";
103
+ let videoFilter = "";
104
+ // Lógica específica para o VA-API (AMD/Intel no Linux)
105
+ if (isLinux && (gpu === "amd" || gpu === "intel")) {
106
+ // Aponta diretamente para a placa de vídeo no Linux
107
+ hwaccel = "-vaapi_device /dev/dri/renderD128";
108
+ // O VA-API precisa que o formato seja nv12 e faça o upload para a GPU
109
+ videoFilter = forceResolution
110
+ ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
111
+ : `-vf "scale=-1:${h},format=nv12,hwupload"`;
57
112
  }
58
- const vaapiOpts = encoder === "h264_vaapi" ? "-vaapi_device /dev/dri/renderD128" : "";
59
- console.log("Compressing video using: ", encoder);
60
- return execAsync(`ffmpeg ${vaapiOpts} -i "${input}" -vf "${filter}" -c:v ${encoder} -pix_fmt yuv420p -acodec copy -y "${output}"`);
113
+ else {
114
+ // Lógica padrão para Windows, Mac e NVIDIA
115
+ videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
116
+ }
117
+ // 4. Monta e executa o comando FFmpeg
118
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} -acodec copy -y "${output}"`;
119
+ console.log("Converting using: ", vcodec);
120
+ return execAsync(command);
61
121
  }
122
+ // async function getBestEncoder(): Promise<string> {
123
+ // try {
124
+ // const { stdout } = (await execAsync("ffmpeg -encoders")) as {
125
+ // stdout: string;
126
+ // };
127
+ // // Prioridade para AMD (Windows: amf | Linux: vaapi)
128
+ // if (stdout.includes("h264_amf")) return "h264_amf";
129
+ // if (stdout.includes("h264_vaapi")) return "h264_vaapi";
130
+ // // Outros hardwares
131
+ // if (stdout.includes("h264_nvenc")) return "h264_nvenc";
132
+ // if (stdout.includes("h264_qsv")) return "h264_qsv";
133
+ // if (stdout.includes("h264_videotoolbox")) return "h264_videotoolbox";
134
+ // return "libx264"; // Fallback
135
+ // } catch {
136
+ // return "libx264";
137
+ // }
138
+ // }
139
+ // export async function ffmpeg_video_compress(
140
+ // input: string,
141
+ // output: string,
142
+ // resolution: Resolution = "480p",
143
+ // forceResolution?: boolean,
144
+ // ) {
145
+ // const { w, h } = resolutionMapping[resolution];
146
+ // const encoder = await getBestEncoder();
147
+ // // No VA-API (Linux), o redimensionamento deve ser feito via hardware para máxima performance
148
+ // let filter = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
149
+ // if (encoder === "h264_vaapi") {
150
+ // // Adiciona upload para hardware se usar vaapi
151
+ // filter = `format=nv12,hwupload,scale_vaapi=w=${forceResolution ? w : -1}:h=${h}`;
152
+ // }
153
+ // const vaapiOpts =
154
+ // encoder === "h264_vaapi" ? "-vaapi_device /dev/dri/renderD128" : "";
155
+ // console.log("Compressing video using: ", encoder);
156
+ // return execAsync(
157
+ // `ffmpeg ${vaapiOpts} -i "${input}" -vf "${filter}" -c:v ${encoder} -pix_fmt yuv420p -acodec copy -y "${output}"`,
158
+ // );
159
+ // }
62
160
  // export async function ffmpeg_video_compress(
63
161
  // input: string,
64
162
  // output: string,
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-toolkit-cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "repository": "https://github.com/daviinacio/dev-toolkit",
5
5
  "author": "Davi Inácio <aazz6850@gmail.com>",
6
6
  "license": "MIT",
package/src/lib/bash.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { exec } from "child_process";
2
2
  import { Resolution, resolutionMapping } from "./constants.js";
3
3
  import { CommanderError } from "commander";
4
+ import { promisify } from "util";
5
+ import * as os from "os";
4
6
 
5
- export const execAsync = (command: string) =>
7
+ export const execAsync = (command: string): Promise<string> =>
6
8
  new Promise((resolve, reject) => {
7
9
  exec(command, (error, stdout, stderr) => {
8
10
  if (error) reject(new Error(stderr));
@@ -33,26 +35,61 @@ export async function check_dependencies(dependencies = globalDependencies) {
33
35
  );
34
36
  }
35
37
  }
38
+ type GpuType = "nvidia" | "amd" | "intel" | "mac" | "cpu";
39
+
40
+ // Cache para não termos que detectar a GPU toda vez que formos comprimir um vídeo
41
+ let cachedGpuType: GpuType | null = null;
42
+
43
+ /**
44
+ * Detecta a GPU instalada na máquina rodando comandos nativos do SO.
45
+ */
46
+ async function detectGPU(): Promise<GpuType> {
47
+ if (cachedGpuType) return cachedGpuType; // Retorna do cache se já sabemos
48
+
49
+ const platform = os.platform();
36
50
 
37
- async function getBestEncoder(): Promise<string> {
38
51
  try {
39
- const { stdout } = (await execAsync("ffmpeg -encoders")) as {
40
- stdout: string;
41
- };
42
-
43
- // Prioridade para AMD (Windows: amf | Linux: vaapi)
44
- if (stdout.includes("h264_amf")) return "h264_amf";
45
- if (stdout.includes("h264_vaapi")) return "h264_vaapi";
46
-
47
- // Outros hardwares
48
- if (stdout.includes("h264_nvenc")) return "h264_nvenc";
49
- if (stdout.includes("h264_qsv")) return "h264_qsv";
50
- if (stdout.includes("h264_videotoolbox")) return "h264_videotoolbox";
51
-
52
- return "libx264"; // Fallback
53
- } catch {
54
- return "libx264";
52
+ // Se for Mac, assume VideoToolbox (Aceleração nativa da Apple)
53
+ if (platform === "darwin") {
54
+ cachedGpuType = "mac";
55
+ return cachedGpuType;
56
+ }
57
+
58
+ let output = "";
59
+
60
+ // Se for Windows, usa o WMIC para listar as placas de vídeo
61
+ if (platform === "win32") {
62
+ const stdout = await execAsync(
63
+ "wmic path win32_VideoController get name",
64
+ );
65
+ output = stdout.toLowerCase();
66
+ }
67
+ // Se for Linux, usa o lspci para listar os hardwares PCI
68
+ else if (platform === "linux") {
69
+ const stdout = await execAsync("lspci");
70
+ output = stdout.toLowerCase();
71
+ }
72
+
73
+ // Analisa a saída dos comandos para descobrir a marca
74
+ if (output.includes("nvidia")) {
75
+ cachedGpuType = "nvidia";
76
+ } else if (output.includes("amd") || output.includes("radeon")) {
77
+ cachedGpuType = "amd";
78
+ } else if (output.includes("intel")) {
79
+ cachedGpuType = "intel";
80
+ } else {
81
+ cachedGpuType = "cpu"; // Fallback se não identificar nada
82
+ }
83
+ } catch (error) {
84
+ if (error instanceof Error)
85
+ console.warn(
86
+ "⚠️ Aviso: Falha ao detectar GPU. Usando CPU por segurança.",
87
+ error.message,
88
+ );
89
+ cachedGpuType = "cpu";
55
90
  }
91
+
92
+ return cachedGpuType;
56
93
  }
57
94
 
58
95
  export async function ffmpeg_video_compress(
@@ -61,25 +98,109 @@ export async function ffmpeg_video_compress(
61
98
  resolution: Resolution = "480p",
62
99
  forceResolution?: boolean,
63
100
  ) {
101
+ // Exemplo de mapeamento (ajuste para bater com o seu código original)
102
+ const resolutionMapping: { [key in Resolution]: { w: number; h: number } } = {
103
+ "4320p": { w: 7680, h: 4320 }, // 8K
104
+ "2160p": { w: 3840, h: 2160 }, // 4K
105
+ "1440p": { w: 2560, h: 1440 }, // Quad HD
106
+ "1080p": { w: 1920, h: 1080 }, // Full HD
107
+ "720p": { w: 1280, h: 720 }, // HD
108
+ "480p": { w: 854, h: 480 }, // SD (WVGA)
109
+ "360p": { w: 640, h: 360 }, // nHD
110
+ "240p": { w: 426, h: 240 }, // WQVGA
111
+ };
112
+
64
113
  const { w, h } = resolutionMapping[resolution];
65
- const encoder = await getBestEncoder();
66
114
 
67
- // No VA-API (Linux), o redimensionamento deve ser feito via hardware para máxima performance
68
- let filter = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
69
- if (encoder === "h264_vaapi") {
70
- // Adiciona upload para hardware se usar vaapi
71
- filter = `format=nv12,hwupload,scale_vaapi=w=${forceResolution ? w : -1}:h=${h}`;
115
+ // 1. Detecta a GPU automaticamente
116
+ const gpu = await detectGPU();
117
+
118
+ // 2. Verifica se é Linux para usar a estratégia correta
119
+ const isLinux = os.platform() === "linux";
120
+
121
+ // Mapeia os Encoders. Nota: AMD e Intel no Linux usam VA-API
122
+ const encoders = {
123
+ nvidia: "-c:v h264_nvenc -preset p4",
124
+ amd: isLinux ? "-c:v h264_vaapi" : "-c:v h264_amf",
125
+ intel: isLinux ? "-c:v h264_vaapi" : "-c:v h264_qsv",
126
+ mac: "-c:v h264_videotoolbox",
127
+ cpu: "-c:v libx264 -preset fast",
128
+ };
129
+
130
+ const vcodec = encoders[gpu] || encoders.cpu;
131
+
132
+ // 3. Configura a aceleração e os filtros
133
+ let hwaccel = gpu === "cpu" ? "" : "-hwaccel auto";
134
+ let videoFilter = "";
135
+
136
+ // Lógica específica para o VA-API (AMD/Intel no Linux)
137
+ if (isLinux && (gpu === "amd" || gpu === "intel")) {
138
+ // Aponta diretamente para a placa de vídeo no Linux
139
+ hwaccel = "-vaapi_device /dev/dri/renderD128";
140
+
141
+ // O VA-API precisa que o formato seja nv12 e faça o upload para a GPU
142
+ videoFilter = forceResolution
143
+ ? `-vf "scale=${w}:${h},format=nv12,hwupload"`
144
+ : `-vf "scale=-1:${h},format=nv12,hwupload"`;
145
+ } else {
146
+ // Lógica padrão para Windows, Mac e NVIDIA
147
+ videoFilter = forceResolution ? `-s ${w}x${h}` : `-filter:v scale=-1:${h}`;
72
148
  }
73
149
 
74
- const vaapiOpts =
75
- encoder === "h264_vaapi" ? "-vaapi_device /dev/dri/renderD128" : "";
150
+ // 4. Monta e executa o comando FFmpeg
151
+ const command = `ffmpeg ${hwaccel} -i "${input}" ${videoFilter} ${vcodec} -acodec copy -y "${output}"`;
76
152
 
77
- console.log("Compressing video using: ", encoder);
153
+ console.log("Converting using: ", vcodec);
78
154
 
79
- return execAsync(
80
- `ffmpeg ${vaapiOpts} -i "${input}" -vf "${filter}" -c:v ${encoder} -pix_fmt yuv420p -acodec copy -y "${output}"`,
81
- );
155
+ return execAsync(command);
82
156
  }
157
+
158
+ // async function getBestEncoder(): Promise<string> {
159
+ // try {
160
+ // const { stdout } = (await execAsync("ffmpeg -encoders")) as {
161
+ // stdout: string;
162
+ // };
163
+
164
+ // // Prioridade para AMD (Windows: amf | Linux: vaapi)
165
+ // if (stdout.includes("h264_amf")) return "h264_amf";
166
+ // if (stdout.includes("h264_vaapi")) return "h264_vaapi";
167
+
168
+ // // Outros hardwares
169
+ // if (stdout.includes("h264_nvenc")) return "h264_nvenc";
170
+ // if (stdout.includes("h264_qsv")) return "h264_qsv";
171
+ // if (stdout.includes("h264_videotoolbox")) return "h264_videotoolbox";
172
+
173
+ // return "libx264"; // Fallback
174
+ // } catch {
175
+ // return "libx264";
176
+ // }
177
+ // }
178
+
179
+ // export async function ffmpeg_video_compress(
180
+ // input: string,
181
+ // output: string,
182
+ // resolution: Resolution = "480p",
183
+ // forceResolution?: boolean,
184
+ // ) {
185
+ // const { w, h } = resolutionMapping[resolution];
186
+ // const encoder = await getBestEncoder();
187
+
188
+ // // No VA-API (Linux), o redimensionamento deve ser feito via hardware para máxima performance
189
+ // let filter = forceResolution ? `scale=${w}:${h}` : `scale=-1:${h}`;
190
+ // if (encoder === "h264_vaapi") {
191
+ // // Adiciona upload para hardware se usar vaapi
192
+ // filter = `format=nv12,hwupload,scale_vaapi=w=${forceResolution ? w : -1}:h=${h}`;
193
+ // }
194
+
195
+ // const vaapiOpts =
196
+ // encoder === "h264_vaapi" ? "-vaapi_device /dev/dri/renderD128" : "";
197
+
198
+ // console.log("Compressing video using: ", encoder);
199
+
200
+ // return execAsync(
201
+ // `ffmpeg ${vaapiOpts} -i "${input}" -vf "${filter}" -c:v ${encoder} -pix_fmt yuv420p -acodec copy -y "${output}"`,
202
+ // );
203
+ // }
83
204
  // export async function ffmpeg_video_compress(
84
205
  // input: string,
85
206
  // output: string,