audiobookshelf/server/utils/downloadWorker.js

92 lines
2.3 KiB
JavaScript

const Ffmpeg = require('fluent-ffmpeg')
if (process.env.FFMPEG_PATH) {
Ffmpeg.setFfmpegPath(process.env.FFMPEG_PATH)
}
const { parentPort, workerData } = require("worker_threads")
parentPort.postMessage({
type: 'FFMPEG',
level: 'debug',
log: '[DownloadWorker] Starting Worker...'
})
const ffmpegCommand = Ffmpeg()
const startTime = Date.now()
workerData.inputs.forEach((inputData) => {
ffmpegCommand.input(inputData.input)
if (inputData.options) ffmpegCommand.inputOption(inputData.options)
})
if (workerData.options) ffmpegCommand.addOption(workerData.options)
if (workerData.outputOptions && workerData.outputOptions.length) ffmpegCommand.addOutputOption(workerData.outputOptions)
ffmpegCommand.output(workerData.output)
var isKilled = false
async function runFfmpeg() {
var success = await new Promise((resolve) => {
ffmpegCommand.on('start', (command) => {
parentPort.postMessage({
type: 'FFMPEG',
level: 'info',
log: '[DownloadWorker] FFMPEG concat started with command: ' + command
})
})
ffmpegCommand.on('stderr', (stdErrline) => {
parentPort.postMessage({
type: 'FFMPEG',
level: 'debug',
log: '[DownloadWorker] Ffmpeg Stderr: ' + stdErrline
})
})
ffmpegCommand.on('error', (err, stdout, stderr) => {
if (err.message && err.message.includes('SIGKILL')) {
// This is an intentional SIGKILL
parentPort.postMessage({
type: 'FFMPEG',
level: 'info',
log: '[DownloadWorker] User Killed worker'
})
} else {
parentPort.postMessage({
type: 'FFMPEG',
level: 'error',
log: '[DownloadWorker] Ffmpeg Err: ' + err.message
})
}
resolve(false)
})
ffmpegCommand.on('end', (stdout, stderr) => {
parentPort.postMessage({
type: 'FFMPEG',
level: 'info',
log: '[DownloadWorker] worker ended'
})
resolve(true)
})
ffmpegCommand.run()
})
var resultMessage = {
type: 'RESULT',
isKilled,
elapsed: Date.now() - startTime,
success
}
parentPort.postMessage(resultMessage)
}
parentPort.on('message', (message) => {
if (message === 'STOP') {
isKilled = true
ffmpegCommand.kill()
}
})
runFfmpeg()