|
11 | 11 | import { readFile, access } from 'node:fs/promises'
|
12 | 12 | import { fileTypeFromBuffer } from 'file-type'
|
13 | 13 | import { l, err } from '../utils/logging'
|
14 |
| -import { execPromise, execFilePromise } from '../utils/globals/process' |
| 14 | +import { executeWithRetry } from '../utils/retry' |
| 15 | +import { execPromise } from '../utils/globals/process' |
15 | 16 | import type { SupportedFileType, ProcessingOptions } from '../utils/types/process'
|
16 | 17 |
|
17 | 18 | /**
|
@@ -88,56 +89,24 @@ export async function downloadAudio(
|
88 | 89 | const finalPath = `content/${filename}`
|
89 | 90 | const outputPath = `${finalPath}.wav`
|
90 | 91 |
|
91 |
| - /** |
92 |
| - * Executes a command with retry logic to recover from transient failures. |
93 |
| - * |
94 |
| - * @param {string} command - The command to execute. |
95 |
| - * @param {string[]} args - Arguments for the command. |
96 |
| - * @param {number} retries - Number of retry attempts. |
97 |
| - * @returns {Promise<void>} Resolves if the command succeeds. |
98 |
| - * @throws {Error} If the command fails after all retry attempts. |
99 |
| - */ |
100 |
| - async function executeWithRetry( |
101 |
| - command: string, |
102 |
| - args: string[], |
103 |
| - retries: number |
104 |
| - ): Promise<void> { |
105 |
| - for (let attempt = 1; attempt <= retries; attempt++) { |
106 |
| - try { |
107 |
| - // Attempt to execute the command |
108 |
| - const { stderr } = await execFilePromise(command, args) |
109 |
| - // Log any warnings from yt-dlp |
110 |
| - if (stderr) { |
111 |
| - err(`yt-dlp warnings: ${stderr}`) |
112 |
| - } |
113 |
| - return // Exit the loop if successful |
114 |
| - } catch (error) { |
115 |
| - // If the last attempt also fails, throw the error |
116 |
| - if (attempt === retries) { |
117 |
| - err(`Failed after ${retries} attempts`) |
118 |
| - throw error |
119 |
| - } |
120 |
| - // Log and retry |
121 |
| - l.wait(`Retry ${attempt} of ${retries}: Retrying yt-dlp command...`) |
122 |
| - } |
123 |
| - } |
124 |
| - } |
125 |
| - |
126 | 92 | // Handle online content (YouTube, RSS feeds, etc.)
|
127 | 93 | if (options.video || options.playlist || options.urls || options.rss || options.channel) {
|
128 | 94 | try {
|
129 | 95 | // Execute yt-dlp with retry logic
|
130 |
| - await executeWithRetry('yt-dlp', [ |
131 |
| - '--no-warnings', // Suppress warning messages |
132 |
| - '--restrict-filenames', // Use safe filenames |
133 |
| - '--extract-audio', // Extract audio stream |
134 |
| - '--audio-format', 'wav', // Convert to WAV |
135 |
| - '--postprocessor-args', 'ffmpeg:-ar 16000 -ac 1', // 16kHz mono |
136 |
| - '--no-playlist', // Don't expand playlists |
137 |
| - '-o', outputPath, // Output path |
138 |
| - input, |
139 |
| - ], 5) |
140 |
| - // Retry up to 5 times |
| 96 | + await executeWithRetry( |
| 97 | + 'yt-dlp', |
| 98 | + [ |
| 99 | + '--no-warnings', // Suppress warning messages |
| 100 | + '--restrict-filenames', // Use safe filenames |
| 101 | + '--extract-audio', // Extract audio stream |
| 102 | + '--audio-format', 'wav', // Convert to WAV |
| 103 | + '--postprocessor-args', 'ffmpeg:-ar 16000 -ac 1', // 16kHz mono |
| 104 | + '--no-playlist', // Don't expand playlists |
| 105 | + '-o', outputPath, // Output path |
| 106 | + input, |
| 107 | + ], |
| 108 | + 5 // Retry up to 5 times |
| 109 | + ) |
141 | 110 | l.wait(`\n Audio downloaded successfully:\n - ${outputPath}`)
|
142 | 111 | } catch (error) {
|
143 | 112 | // Log the error and rethrow
|
|
0 commit comments