Files
video-downloader/worker/processor.ts
T

62 lines
1.8 KiB
TypeScript

import { spawn } from 'child_process'
import { readdirSync, statSync } from 'fs'
import path from 'path'
import { prisma } from '@/lib/prisma'
import { buildYtdlpArgs } from '@/lib/ytdlp'
import { createToken } from '@/lib/token'
import { config } from '../config/app.config'
export async function processDownload(downloadId: string): Promise<void> {
const download = await prisma.download.findUnique({ where: { id: downloadId } })
if (!download) return
const args = buildYtdlpArgs({
url: download.url,
uuid: download.uuid,
format: download.format,
quality: download.quality,
subtitles: download.subtitles,
extraArgs: download.extraArgs,
})
let stderr = ''
await new Promise<void>((resolve) => {
const proc = spawn('yt-dlp', args)
proc.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString() })
proc.on('close', async (code) => {
if (code === 0) {
const files = readdirSync(config.STORAGE_PATH).filter((f) =>
f.startsWith(download.uuid)
)
const relFile = files[0] ?? null
const filePath = relFile ? path.join(config.STORAGE_PATH, relFile) : null
const fileSize = filePath ? BigInt(statSync(filePath).size) : null
await prisma.download.update({
where: { id: downloadId },
data: {
status: 'DONE',
filePath,
fileName: relFile,
fileSize,
completedAt: new Date(),
},
})
await createToken(downloadId)
} else {
await prisma.download.update({
where: { id: downloadId },
data: {
status: 'FAILED',
errorMsg: stderr || `yt-dlp exited with code ${code}`,
completedAt: new Date(),
},
})
}
resolve()
})
})
}