feat: add random filename fallback when filename cannot be retrieved - Add generateRandomFilename utility function - Modify downloadVideo to use random filename when yt-dlp fails to get filename - Update version to 0.6.26
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kevinwatt/yt-dlp-mcp",
|
||||
"version": "0.6.25",
|
||||
"version": "0.6.26",
|
||||
"description": "An MCP server implementation that integrates with yt-dlp, providing video and audio content download capabilities (e.g. YouTube, Facebook, Tiktok, etc.) for LLMs.",
|
||||
"keywords": [
|
||||
"mcp",
|
||||
|
||||
@@ -17,7 +17,7 @@ import { downloadVideo } from "./modules/video.js";
|
||||
import { downloadAudio } from "./modules/audio.js";
|
||||
import { listSubtitles, downloadSubtitles } from "./modules/subtitle.js";
|
||||
|
||||
const VERSION = '0.6.25';
|
||||
const VERSION = '0.6.26';
|
||||
|
||||
/**
|
||||
* Validate system configuration
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as fs from 'fs';
|
||||
import { spawn } from 'child_process';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
/**
|
||||
* Validates if a given string is a valid URL.
|
||||
@@ -126,4 +127,22 @@ export function getFormattedTimestamp(): string {
|
||||
.replace(/[:.]/g, '-')
|
||||
.replace('T', '_')
|
||||
.split('.')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random filename with timestamp prefix.
|
||||
*
|
||||
* @param extension - Optional file extension (default: 'mp4')
|
||||
* @returns A random filename with timestamp
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const filename = generateRandomFilename('mp3');
|
||||
* console.log(filename); // '2024-03-20_12-30-00_a1b2c3d4.mp3'
|
||||
* ```
|
||||
*/
|
||||
export function generateRandomFilename(extension: string = 'mp4'): string {
|
||||
const timestamp = getFormattedTimestamp();
|
||||
const randomId = randomBytes(4).toString('hex');
|
||||
return `${timestamp}_${randomId}.${extension}`;
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
_spawnPromise,
|
||||
validateUrl,
|
||||
getFormattedTimestamp,
|
||||
isYouTubeUrl
|
||||
isYouTubeUrl,
|
||||
generateRandomFilename
|
||||
} from "./utils.js";
|
||||
|
||||
/**
|
||||
@@ -76,27 +77,30 @@ export async function downloadVideo(
|
||||
format = "bestvideo[height>=720]+bestaudio/best[height>=720]/best";
|
||||
}
|
||||
}
|
||||
|
||||
// 使用安全的文件名模板
|
||||
const outputTemplate = path.join(
|
||||
userDownloadsDir,
|
||||
sanitizeFilename(`%(title)s [%(id)s] ${timestamp}`, config.file) + '.%(ext)s'
|
||||
);
|
||||
|
||||
// Get expected filename
|
||||
let outputTemplate: string;
|
||||
let expectedFilename: string;
|
||||
|
||||
try {
|
||||
// 嘗試獲取檔案名稱
|
||||
outputTemplate = path.join(
|
||||
userDownloadsDir,
|
||||
sanitizeFilename(`%(title)s [%(id)s] ${timestamp}`, config.file) + '.%(ext)s'
|
||||
);
|
||||
|
||||
expectedFilename = await _spawnPromise("yt-dlp", [
|
||||
"--get-filename",
|
||||
"-f", format,
|
||||
"--output", outputTemplate,
|
||||
url
|
||||
]);
|
||||
expectedFilename = expectedFilename.trim();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get filename: ${error instanceof Error ? error.message : String(error)}`);
|
||||
// 如果無法獲取檔案名稱,使用隨機檔案名
|
||||
const randomFilename = generateRandomFilename('mp4');
|
||||
outputTemplate = path.join(userDownloadsDir, randomFilename);
|
||||
expectedFilename = randomFilename;
|
||||
}
|
||||
|
||||
expectedFilename = expectedFilename.trim();
|
||||
|
||||
// Download with progress info
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user