84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
import exec from './exec.js'
|
|
import addExtraVideos from './addExtraVideos.js'
|
|
import getArgument from './getArgument.js'
|
|
|
|
const chaos = Math.max(Math.min(getArgument('chaos')??50, 100), 0)
|
|
|
|
function calculateAbsSum(arr) {
|
|
return arr.reduce((total, current) => {
|
|
return total + Math.abs(current)
|
|
}, 0)
|
|
}
|
|
|
|
async function getVolumeFrames(inputPath) {
|
|
const { stdout } = await exec(`audiowaveform --input-file "${inputPath}" --output-format json --output-file -`, {
|
|
maxBuffer: 5 * 1024 * 1024
|
|
})
|
|
let info = JSON.parse(stdout)
|
|
const range = info.bits==8?255:65535
|
|
let finalArray = []
|
|
let amount = 2 // because the array is of sample pairs
|
|
let length = info.length / ((info.sample_rate / 1000) / info.samples_per_pixel)
|
|
let perMs = length / info.length
|
|
for (let i = 0; i < info.data.length; i+=amount) {
|
|
finalArray.push(calculateAbsSum(info.data.slice(i, i+amount))/range*100)
|
|
}
|
|
return {
|
|
perMs,
|
|
average: calculateAbsSum(finalArray)/finalArray.length,
|
|
length: finalArray.length,
|
|
data: finalArray
|
|
}
|
|
}
|
|
|
|
export default async function parseVolumeFrames(inputPath) {
|
|
let info = await getVolumeFrames(inputPath)
|
|
|
|
const indexToMs = i => i*info.perMs
|
|
|
|
let sections = []
|
|
|
|
let current = null
|
|
let lastLoud = 0
|
|
console.log(`Chaoticness set to ${chaos}%`)
|
|
let maxLastLoud = 2*(150-chaos)
|
|
let filter = info.average*1.2
|
|
|
|
let duration = 0
|
|
|
|
for (let i = 0; i < info.data.length; i ++) {
|
|
if (i%500==0) {
|
|
process.stdout.clearLine();
|
|
process.stdout.cursorTo(0);
|
|
process.stdout.write(`Parsing audio... ${Math.ceil(i/info.data.length*100)}%`)
|
|
}
|
|
let frame = info.data[i]
|
|
let ms = indexToMs(i)
|
|
if (frame>filter) {
|
|
lastLoud = ms
|
|
if (current) continue
|
|
current = {
|
|
start: Math.floor(ms)
|
|
}
|
|
} else {
|
|
if (!current||(ms-lastLoud)<maxLastLoud) continue
|
|
if (lastLoud-current.start>maxLastLoud) {
|
|
current.end = Math.ceil(lastLoud)
|
|
duration += current.end - current.start
|
|
sections.push(current)
|
|
}
|
|
current = null
|
|
}
|
|
}
|
|
console.log('')
|
|
if (current) {
|
|
current.end = Math.ceil(indexToMs(info.data.length))
|
|
sections.push(current)
|
|
}
|
|
console.log(`Created ${sections.length} clips`)
|
|
sections = await addExtraVideos(sections)
|
|
return {
|
|
duration: duration/1000,
|
|
sections
|
|
}
|
|
} |