112 lines
2.8 KiB
JavaScript

import fs from "node:fs"
import path from "node:path"
import { exec } from "node:child_process"
import { EventEmitter } from "node:events"
export default class SegmentedAudioMPDJob {
constructor({
input,
outputDir,
outputMasterName = "master.mpd",
audioCodec = "aac",
audioBitrate = undefined,
audioSampleRate = undefined,
segmentTime = 10,
}) {
this.input = input
this.outputDir = outputDir
this.outputMasterName = outputMasterName
this.audioCodec = audioCodec
this.audioBitrate = audioBitrate
this.segmentTime = segmentTime
this.audioSampleRate = audioSampleRate
this.bin = require("ffmpeg-static")
return this
}
events = new EventEmitter()
buildCommand = () => {
const cmdStr = [
this.bin,
`-v quiet -stats`,
`-i ${this.input}`,
`-c:a ${this.audioCodec}`,
`-map 0:a`,
`-map_metadata -1`,
`-f dash`,
`-dash_segment_type mp4`,
`-segment_time ${this.segmentTime}`,
`-use_template 1`,
`-use_timeline 1`,
`-init_seg_name "init.m4s"`,
]
if (typeof this.audioBitrate !== "undefined") {
cmdStr.push(`-b:a ${this.audioBitrate}`)
}
if (typeof this.audioSampleRate !== "undefined") {
cmdStr.push(`-ar ${this.audioSampleRate}`)
}
cmdStr.push(this.outputMasterName)
return cmdStr.join(" ")
}
run = () => {
const cmdStr = this.buildCommand()
console.log(cmdStr)
const cwd = `${path.dirname(this.input)}/dash`
if (!fs.existsSync(cwd)) {
fs.mkdirSync(cwd, { recursive: true })
}
console.log(`[DASH] Started audio segmentation`, {
input: this.input,
cwd: cwd,
})
const process = exec(
cmdStr,
{
cwd: cwd,
},
(error, stdout, stderr) => {
if (error) {
console.log(`[DASH] Failed to segment audio >`, error)
return this.events.emit("error", error)
}
if (stderr) {
//return this.events.emit("error", stderr)
}
console.log(`[DASH] Finished segmenting audio >`, cwd)
return this.events.emit("end", {
filepath: path.join(cwd, this.outputMasterName),
isDirectory: true,
})
}
)
process.stdout.on("data", (data) => {
console.log(data.toString())
})
}
on = (key, cb) => {
this.events.on(key, cb)
return this
}
}