tphim 2.0.2 → 2.1.0

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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 🚀 Tính năng vượt trội
6
6
  - **Batch Pipeline:** Xử lý hàng loạt phim chỉ với 1 dòng lệnh.
7
- - **AI Subtitles:** Tự động tạo phụ đề Tiếng Việt/Tiếng Anh bằng công cụ AI (Whisper) chạy offline.
7
+ - **AI Subtitles:** Tự động tạo phụ đề Tiếng Việt/Tiếng Anh bằng công cụ AI (Whisper) chạy offline. Hỗ trợ bỏ qua phụ đề để tăng tốc độ.
8
8
  - **Cloud Ready:** Upload trực tiếp lên Tebi.io hoặc bất kỳ S3-compatible storage nào.
9
9
  - **Interactive CLI:** Giao diện terminal đẹp mắt với neon theme.
10
10
 
@@ -124,7 +124,7 @@ await executePipeline({
124
124
  input: "https://link-phim.com/phim.m3u8",
125
125
  slug: "phim-hay-2030",
126
126
  title: "Phim Hay 2030",
127
- langArg: "both"
127
+ langArg: "vi" // hoặc "en", "both", "skip"
128
128
  });
129
129
  ```
130
130
 
@@ -170,7 +170,7 @@ TEBI_PUBLIC_URL=https://your-bucket.tebi.io
170
170
  **Interactive Mode:**
171
171
  - Nhập multiple links (cách nhau bằng dấu phẩy)
172
172
  - Tự động fetch metadata từ video
173
- - Chọn ngôn ngữ phụ đề (VI/EN/Both)
173
+ - Chọn ngôn ngữ phụ đề (VI/EN/Both/Skip)
174
174
  - Batch processing với progress bar
175
175
 
176
176
  **Help System:**
@@ -182,4 +182,5 @@ ntxa -h # Tương tự
182
182
 
183
183
  ---
184
184
 
185
- *Phát triển bởi TXA - Ultimate Video Pipeline 2030* 🍿🎬
185
+ *Phát triển bởi TXA - Ultimate Video Pipeline 2030 v2.1.0* 🍿🎬
186
+ *Last Update: February 2026*
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tphim",
3
- "version": "2.0.2",
4
- "description": "TPHIM - Ultimate Video Pipeline: Download, Transcode HLS, AI Subtitles, and Cloud Upload.",
3
+ "version": "2.1.0",
4
+ "description": "TPHIM - Ultimate Video Pipeline: Download, Transcode HLS, AI Subtitles (with skip option), and Cloud Upload.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "bin": {
package/pipeline.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // pipeline.mjs
3
- // Usage: node pipeline.mjs "URL_hoac_duong_dan_mp4" "slug" "Tên Phim" [vi|en|both]
3
+ // Usage: node pipeline.mjs "URL_hoac_duong_dan_mp4" "slug" "Tên Phim" [vi|en|both|skip]
4
4
 
5
5
  import { execSync } from 'child_process';
6
6
  import { existsSync, mkdirSync, writeFileSync, rmSync, unlinkSync, readFileSync } from 'fs';
@@ -106,6 +106,7 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
106
106
  console.log(' node pipeline.mjs "URL_video" "slug" "Tên Phim" vi');
107
107
  console.log(' node pipeline.mjs "D:\\film.mp4" "slug" "Tên Phim" vi');
108
108
  console.log(' node pipeline.mjs "URL_video" "slug" "Tên Phim" both');
109
+ console.log(' node pipeline.mjs "URL_video" "slug" "Tên Phim" skip');
109
110
  return;
110
111
  }
111
112
  console.log('\n╔══════════════════════════════════════════════════════════════════╗');
@@ -152,7 +153,9 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
152
153
  return `${FINAL_YTDLP} ${proxyFlag} ${commonFlags} "${input}" -o "${mp4Path}"`;
153
154
  } else {
154
155
  const refFlag = referer ? `--referer "${referer}"` : '--referer "https://embed1.streamc.xyz/"';
155
- return `${FINAL_YTDLP} --extractor-args "generic:impersonate=chrome" ${refFlag} ${proxyFlag} ${commonFlags} "${input}" -o "${mp4Path}"`;
156
+ // Remove impersonation on Ubuntu if not available
157
+ const impersonateFlag = IS_WIN ? '--extractor-args "generic:impersonate=chrome"' : '';
158
+ return `${FINAL_YTDLP} ${impersonateFlag} ${refFlag} ${proxyFlag} ${commonFlags} "${input}" -o "${mp4Path}"`;
156
159
  }
157
160
  };
158
161
 
@@ -171,7 +174,7 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
171
174
 
172
175
  // Attempt 2-4: Retry with proxy rotation
173
176
  if (!downloaded && PROXY_LIST.length > 0) {
174
- const MAX_PROXY_RETRIES = Math.min(3, PROXY_LIST.length);
177
+ const MAX_PROXY_RETRIES = Math.min(5, PROXY_LIST.length);
175
178
  const usedProxies = [];
176
179
  console.log(` 🔄 Thử lại với proxy (${PROXY_LIST.length} proxies available)...`);
177
180
 
@@ -199,7 +202,7 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
199
202
  if (!downloaded) {
200
203
  throw new Error(
201
204
  `❌ Download thất bại: ${input}\n` +
202
- ` Đã thử: direct + ${Math.min(3, PROXY_LIST.length)} proxies\n` +
205
+ ` Đã thử: direct + ${Math.min(5, PROXY_LIST.length)} proxies\n` +
203
206
  ` Nguyên nhân phổ biến:\n` +
204
207
  ` • Link đã hết hạn hoặc bị xóa (HTTP 404)\n` +
205
208
  ` • Server CDN chặn tất cả IP\n` +
@@ -247,7 +250,7 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
247
250
 
248
251
  selectedQualities.forEach((q, i) => {
249
252
  maps += `-map 0:v -map 0:a `;
250
- outputs += `-c:v:${i} libx264 -preset veryfast -tune fastdecode -b:v:${i} ${q.bv} -s:v:${i} ${q.w}x${q.h} -c:a:${i} aac -b:a:${i} ${q.ba} `;
253
+ outputs += `-c:v:${i} libx264 -preset ultrafast -tune fastdecode -b:v:${i} ${q.bv} -s:v:${i} ${q.w}x${q.h} -c:a:${i} aac -b:a:${i} ${q.ba} -movflags +faststart `;
251
254
  varStreamMapArr.push(`v:${i},a:${i}`);
252
255
  });
253
256
 
@@ -301,30 +304,34 @@ export async function executePipeline({ input, slug, title, langArg = 'vi' }) {
301
304
  generateReadme(slug, mp4Path, { title });
302
305
 
303
306
  // ─── BƯỚC 4: Tạo Subtitle (Python faster-whisper) ─────────────
304
- console.log('\n📝 [4/5] Generating subtitles (faster-whisper offline)...');
305
- const langs = langArg === 'both' ? ['vi', 'en'] : [langArg];
306
-
307
- for (const lang of langs) {
308
- const vttPath = path.join('hls', slug, `${lang}.vtt`);
309
- if (!existsSync(vttPath)) {
310
- // Detection logic for python command (python vs python3)
311
- let pythonCmd = 'python';
312
- try {
313
- execSync('python --version', { stdio: 'ignore' });
314
- } catch (e) {
315
- pythonCmd = 'python3';
316
- }
307
+ if (langArg !== 'skip') {
308
+ console.log('\n📝 [4/5] Generating subtitles (faster-whisper offline)...');
309
+ const langs = langArg === 'both' ? ['vi', 'en'] : [langArg];
310
+
311
+ for (const lang of langs) {
312
+ const vttPath = path.join('hls', slug, `${lang}.vtt`);
313
+ if (!existsSync(vttPath)) {
314
+ // Detection logic for python command (python vs python3)
315
+ let pythonCmd = 'python';
316
+ try {
317
+ execSync('python --version', { stdio: 'ignore' });
318
+ } catch (e) {
319
+ pythonCmd = 'python3';
320
+ }
317
321
 
318
- execSync(
319
- `${pythonCmd} ${path.join(__dirname, 'scripts', 'gen_subtitle.py')} "${mp4Path}" "${slug}" ${lang} "${FFMPEG_BIN}"`,
320
- { stdio: 'inherit', cwd: process.cwd() }
321
- );
322
- } else {
323
- console.log(` ⏭ Subtitle [${lang}] đã có sẵn`);
322
+ execSync(
323
+ `${pythonCmd} ${path.join(__dirname, 'scripts', 'gen_subtitle.py')} "${mp4Path}" "${slug}" ${lang} "${FFMPEG_BIN}"`,
324
+ { stdio: 'inherit', cwd: process.cwd() }
325
+ );
326
+ } else {
327
+ console.log(` ⏭ Subtitle [${lang}] đã có sẵn`);
328
+ }
324
329
  }
330
+ } else {
331
+ console.log('\n⏭ [4/5] Skipping subtitle generation (selected "skip" option)');
325
332
  }
326
333
 
327
- // ─── BƯỚC 5: Upload Tebi.io ─────────────────────────────────── // --- STEP 5: UPLOAD ---
334
+ // ─── BƯỚC 5: Upload Tebi.io ───────────────────────────────────
328
335
  console.log('\n🚀 [5/5] Deploying to Quantum Cloud (Tebi.io)...');
329
336
 
330
337
  // Optimize upload with parallel processing
@@ -402,4 +409,4 @@ if (import.meta.url.endsWith(process.argv[1].replace(/\\/g, '/')) || process.arg
402
409
  console.error('\n❌ LỖI:', err.message);
403
410
  process.exit(1);
404
411
  });
405
- }
412
+ }
package/pro-terminal.mjs CHANGED
@@ -111,7 +111,7 @@ function showHelp() {
111
111
  )
112
112
  );
113
113
 
114
- console.log(chalk.gray(' ⚡ TPHIM ULTIMATE VIDEO CORE v2.0.2 | STATUS: READY ⚡\n'));
114
+ console.log(chalk.gray(' ⚡ TPHIM ULTIMATE VIDEO CORE v2.1.0 | STATUS: READY ⚡\n'));
115
115
 
116
116
  console.log(`${neonPurple('📖 CÁCH SỬ DỤNG:')}`);
117
117
  console.log(chalk.cyan(' ntxa help - Hiển thị help này'));
@@ -168,7 +168,7 @@ async function main() {
168
168
  )
169
169
  );
170
170
 
171
- console.log(chalk.gray(' ⚡ NEON-INFUSED VIDEO CORE v1.0 | STATUS: READY ⚡\n'));
171
+ console.log(chalk.gray(' ⚡ NEON-INFUSED VIDEO CORE v2.1.0 | STATUS: READY ⚡\n'));
172
172
 
173
173
  p.intro(`${neonPurple('▣ SYSTEM INITIALIZED - BATCH MODE ENABLED')}`);
174
174
 
@@ -203,6 +203,7 @@ async function main() {
203
203
  p.select({
204
204
  message: '🌐 Quantum transcription language:',
205
205
  options: [
206
+ { value: 'skip', label: '⏭ Bỏ qua Subtitle', hint: 'Nhanh nhất' },
206
207
  { value: 'vi', label: 'Tiếng Việt', hint: 'Default' },
207
208
  { value: 'en', label: 'English', hint: 'Secondary' },
208
209
  { value: 'both', label: 'Dual Core (VI+EN)', hint: 'Premium' },