@codearcade/subtitle-generator 1.0.0 → 1.0.2

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.
Files changed (2) hide show
  1. package/init/index.js +81 -32
  2. package/package.json +1 -1
package/init/index.js CHANGED
@@ -92,49 +92,98 @@ const init = async () => {
92
92
  // Windows Setup
93
93
  const binaryDest = path.join(whisperDir, "whisper-cli.exe");
94
94
  if (!fs.existsSync(binaryDest)) {
95
- // Using latest pre-built x64 binaries from ggml-org
96
- const zipUrl =
97
- "https://github.com/ggerganov/whisper.cpp/releases/latest/download/whisper-bin-x64.zip";
95
+ console.log("Detecting Windows architecture...");
96
+ const arch = os.arch(); // Usually 'x64', 'ia32', or 'arm64'
97
+
98
+ let zipName;
99
+
100
+ if (arch === "x64") {
101
+ zipName = "whisper-bin-x64.zip";
102
+ } else if (arch === "ia32") {
103
+ zipName = "whisper-bin-Win32.zip";
104
+ } else if (arch === "arm64") {
105
+ // Windows ARM can emulate x64 executables
106
+ console.log(
107
+ "ARM64 architecture detected. Using x64 binary via Windows emulation...",
108
+ );
109
+ zipName = "whisper-bin-x64.zip";
110
+ } else {
111
+ throw new Error(
112
+ `Unsupported Windows architecture: ${arch}. Whisper.cpp does not provide pre-compiled binaries for this system.`,
113
+ );
114
+ }
115
+
116
+ const zipUrl = `https://github.com/ggml-org/whisper.cpp/releases/download/v1.8.4/${zipName}`;
98
117
  const zipPath = path.join(whisperDir, "whisper.zip");
99
118
 
100
- await downloadFile(zipUrl, zipPath, "Whisper Windows Binary");
119
+ await downloadFile(zipUrl, zipPath, `Whisper Windows Binary (${arch})`);
101
120
 
102
121
  console.log("Extracting binary...");
103
- // Windows 10+ has native tar for unzipping
104
- execSync(`tar -xf "${zipPath}" -C "${whisperDir}"`);
105
122
 
106
- // 1. Move everything out of the "Release" folder (or any other subfolder the zip might use)
107
- const possibleReleaseDir = path.join(whisperDir, "Release");
123
+ let extractionSuccess = false;
124
+ let maxRetries = 5;
125
+ let retryDelay = 1000; // 1 second
108
126
 
109
- if (fs.existsSync(possibleReleaseDir)) {
110
- // Read all files inside the Release folder
111
- const files = fs.readdirSync(possibleReleaseDir);
112
-
113
- // Move them up one level into the main whisperDir
114
- for (const file of files) {
115
- fs.renameSync(
116
- path.join(possibleReleaseDir, file),
117
- path.join(whisperDir, file),
127
+ // 1. The Retry Loop for safe extraction
128
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
129
+ try {
130
+ execSync(
131
+ `powershell -command "Expand-Archive -Force -LiteralPath '${zipPath}' -DestinationPath '${whisperDir}'"`,
132
+ { stdio: "inherit" },
133
+ );
134
+ extractionSuccess = true;
135
+ break; // It worked! Break out of the loop.
136
+ } catch (error) {
137
+ if (attempt === maxRetries) {
138
+ console.error(
139
+ `\nExtraction failed after ${maxRetries} attempts. File might be permanently locked or corrupted.`,
140
+ );
141
+ throw error;
142
+ }
143
+ console.log(
144
+ `\nFile locked by Windows (likely Antivirus). Retrying in 1 second... (Attempt ${attempt} of ${maxRetries})`,
118
145
  );
146
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
119
147
  }
120
- // Delete the now-empty Release folder
121
- fs.rmdirSync(possibleReleaseDir);
122
148
  }
123
149
 
124
- // 2. Rename extracted main.exe to match our wrapper expectations
125
- const extractedMain = path.join(whisperDir, "main.exe");
126
- if (fs.existsSync(extractedMain)) {
127
- fs.renameSync(extractedMain, binaryDest);
128
- } else {
129
- console.error("Warning: Could not find main.exe after extraction.");
130
- }
150
+ // 2. The Cleanup Phase (Only runs if extraction worked)
151
+ if (extractionSuccess) {
152
+ try {
153
+ // Move everything out of the "Release" folder
154
+ const possibleReleaseDir = path.join(whisperDir, "Release");
155
+
156
+ if (fs.existsSync(possibleReleaseDir)) {
157
+ const files = fs.readdirSync(possibleReleaseDir);
158
+
159
+ for (const file of files) {
160
+ fs.renameSync(
161
+ path.join(possibleReleaseDir, file),
162
+ path.join(whisperDir, file),
163
+ );
164
+ }
165
+ // Delete the now-empty Release folder
166
+ fs.rmdirSync(possibleReleaseDir);
167
+ }
131
168
 
132
- // 3. Clean up the zip file so it doesn't clutter the folder
133
- if (fs.existsSync(zipPath)) {
134
- fs.unlinkSync(zipPath);
135
- }
169
+ // Rename extracted main.exe to match our wrapper expectations
170
+ const extractedMain = path.join(whisperDir, "main.exe");
171
+ if (fs.existsSync(extractedMain)) {
172
+ fs.renameSync(extractedMain, binaryDest);
173
+ } else {
174
+ console.error("Warning: Could not find main.exe after extraction.");
175
+ }
136
176
 
137
- console.log("Whisper binary setup complete for Windows.");
177
+ // Clean up the zip file
178
+ if (fs.existsSync(zipPath)) {
179
+ fs.unlinkSync(zipPath);
180
+ }
181
+
182
+ console.log(`Whisper binary setup complete for Windows (${arch}).`);
183
+ } catch (error) {
184
+ console.error("Error during binary cleanup/renaming:", error.message);
185
+ }
186
+ }
138
187
  } else {
139
188
  console.log("Whisper binary already exists for Windows.");
140
189
  }
@@ -151,7 +200,7 @@ const init = async () => {
151
200
  if (!fs.existsSync(repoDir)) {
152
201
  // Shallow clone to save time and bandwidth
153
202
  execSync(
154
- `git clone --depth 1 https://github.com/ggerganov/whisper.cpp.git "${repoDir}"`,
203
+ `git clone --depth 1 https://github.com/ggml-org/whisper.cpp.git "${repoDir}"`,
155
204
  { stdio: "inherit" },
156
205
  );
157
206
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codearcade/subtitle-generator",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",