feat(video): add support for trimming video downloads

This commit is contained in:
seszele64 2025-07-22 19:12:38 +02:00
parent bbc0e6aa93
commit 83a2eb9bb8

View File

@ -11,19 +11,21 @@ import {
/** /**
* Downloads a video from the specified URL. * Downloads a video from the specified URL.
* *
* @param url - The URL of the video to download * @param url - The URL of the video to download
* @param config - Configuration object for download settings * @param config - Configuration object for download settings
* @param resolution - Preferred video resolution ('480p', '720p', '1080p', 'best') * @param resolution - Preferred video resolution ('480p', '720p', '1080p', 'best')
* @param startTime - Optional start time for trimming (format: HH:MM:SS[.ms])
* @param endTime - Optional end time for trimming (format: HH:MM:SS[.ms])
* @returns Promise resolving to a success message with the downloaded file path * @returns Promise resolving to a success message with the downloaded file path
* @throws {Error} When URL is invalid or download fails * @throws {Error} When URL is invalid or download fails
* *
* @example * @example
* ```typescript * ```typescript
* // Download with default settings * // Download with default settings
* const result = await downloadVideo('https://youtube.com/watch?v=...'); * const result = await downloadVideo('https://youtube.com/watch?v=...');
* console.log(result); * console.log(result);
* *
* // Download with specific resolution * // Download with specific resolution
* const hdResult = await downloadVideo( * const hdResult = await downloadVideo(
* 'https://youtube.com/watch?v=...', * 'https://youtube.com/watch?v=...',
@ -31,12 +33,24 @@ import {
* '1080p' * '1080p'
* ); * );
* console.log(hdResult); * console.log(hdResult);
*
* // Download with trimming
* const trimmedResult = await downloadVideo(
* 'https://youtube.com/watch?v=...',
* undefined,
* '720p',
* '00:01:30',
* '00:02:45'
* );
* console.log(trimmedResult);
* ``` * ```
*/ */
export async function downloadVideo( export async function downloadVideo(
url: string, url: string,
config: Config, config: Config,
resolution: "480p" | "720p" | "1080p" | "best" = "720p" resolution: "480p" | "720p" | "1080p" | "best" = "720p",
startTime?: string,
endTime?: string
): Promise<string> { ): Promise<string> {
const userDownloadsDir = config.file.downloadsDir; const userDownloadsDir = config.file.downloadsDir;
@ -103,17 +117,36 @@ export async function downloadVideo(
expectedFilename = randomFilename; expectedFilename = randomFilename;
} }
// Build download arguments
const downloadArgs = [
"--ignore-config",
"--progress",
"--newline",
"--no-mtime",
"-f", format,
"--output", outputTemplate
];
// Add trimming parameters if provided
if (startTime || endTime) {
let downloadSection = "*";
if (startTime && endTime) {
downloadSection = `*${startTime}-${endTime}`;
} else if (startTime) {
downloadSection = `*${startTime}-`;
} else if (endTime) {
downloadSection = `*-${endTime}`;
}
downloadArgs.push("--download-sections", downloadSection, "--force-keyframes-at-cuts");
}
downloadArgs.push(url);
// Download with progress info // Download with progress info
try { try {
await _spawnPromise("yt-dlp", [ await _spawnPromise("yt-dlp", downloadArgs);
"--ignore-config",
"--progress",
"--newline",
"--no-mtime",
"-f", format,
"--output", outputTemplate,
url
]);
} catch (error) { } catch (error) {
throw new Error(`Download failed: ${error instanceof Error ? error.message : String(error)}`); throw new Error(`Download failed: ${error instanceof Error ? error.message : String(error)}`);
} }