@qodestack/dl-yt-playlist
Advanced tools
Comparing version 7.3.0 to 7.4.0
@@ -94,2 +94,4 @@ // Generated by dts-bundle-generator v9.5.1 | ||
isUnavailable: boolean; | ||
/** LUFS value, as calculated by ffmpeg */ | ||
lufs: number | null; | ||
}; | ||
@@ -136,2 +138,6 @@ export type DownloadType = "audio" | "video" | "both" | "none"; | ||
videoId: string; | ||
} | { | ||
type: "lufs"; | ||
filePath: string; | ||
errorMessage: string; | ||
}); | ||
@@ -339,3 +345,6 @@ export type FailureType = Failure["type"]; | ||
}[]>; | ||
export declare function getLufsForFile(filePath: string): number | { | ||
error: string; | ||
}; | ||
export {}; |
@@ -52,2 +52,3 @@ // @bun | ||
import path from "path"; | ||
import {execSync} from "child_process"; | ||
import google from "@googleapis/youtube"; | ||
@@ -190,3 +191,4 @@ import cliProgress from "cli-progress"; | ||
audioFileExtension: null, | ||
videoFileExtension: null | ||
videoFileExtension: null, | ||
lufs: null | ||
}); | ||
@@ -344,6 +346,16 @@ } else { | ||
fs.renameSync(oldAudioPath, newAudioPath); | ||
const lufs = getLufsForFile(newAudioPath); | ||
if (typeof lufs !== "number") { | ||
failures.push({ | ||
type: "lufs", | ||
filePath: newAudioPath, | ||
errorMessage: lufs.error, | ||
date: Date.now() | ||
}); | ||
} | ||
return { | ||
...partialVideoWithDuration, | ||
audioFileExtension, | ||
videoFileExtension | ||
videoFileExtension, | ||
lufs: typeof lufs === "number" ? lufs : null | ||
}; | ||
@@ -377,6 +389,17 @@ }); | ||
const { ext: videoFileExtension } = parsedResults.output; | ||
const filePath = `${videoDir}/${id}.${videoFileExtension}`; | ||
const lufs = getLufsForFile(filePath); | ||
if (typeof lufs !== "number") { | ||
failures.push({ | ||
type: "lufs", | ||
filePath, | ||
errorMessage: lufs.error, | ||
date: Date.now() | ||
}); | ||
} | ||
return { | ||
...partialVideoWithDuration, | ||
audioFileExtension: null, | ||
videoFileExtension | ||
videoFileExtension, | ||
lufs: typeof lufs === "number" ? lufs : null | ||
}; | ||
@@ -410,6 +433,18 @@ }); | ||
const { requested_downloads } = parsedResults.output; | ||
const audioFileExtension = requested_downloads[0].ext; | ||
const filePath = `${audioDir}/${id}.${audioFileExtension}`; | ||
const lufs = getLufsForFile(filePath); | ||
if (typeof lufs !== "number") { | ||
failures.push({ | ||
type: "lufs", | ||
filePath, | ||
errorMessage: lufs.error, | ||
date: Date.now() | ||
}); | ||
} | ||
return { | ||
...partialVideoWithDuration, | ||
audioFileExtension: requested_downloads[0].ext, | ||
videoFileExtension: null | ||
audioFileExtension, | ||
videoFileExtension: null, | ||
lufs: typeof lufs === "number" ? lufs : null | ||
}; | ||
@@ -423,3 +458,4 @@ }); | ||
audioFileExtension: null, | ||
videoFileExtension: null | ||
videoFileExtension: null, | ||
lufs: null | ||
}); | ||
@@ -555,6 +591,15 @@ }; | ||
const videoFileExtension = existingVideo ? path.parse(existingVideo).ext.slice(1) : null; | ||
const lufs = (() => { | ||
if (!existingAudio && !existingVideo) | ||
return null; | ||
const typeDir = existingAudio ? audioDir : videoDir; | ||
const ext = existingAudio ? audioFileExtension : videoFileExtension; | ||
const filePath = `${typeDir}/${id}.${ext}`; | ||
return getLufsForFile(filePath); | ||
})(); | ||
return { | ||
...partialVideoWithDuration, | ||
audioFileExtension, | ||
videoFileExtension | ||
videoFileExtension, | ||
lufs: typeof lufs === "number" ? lufs : null | ||
}; | ||
@@ -620,3 +665,4 @@ }); | ||
thumbnailDownload: [], | ||
thumbnailUrlNotAvailable: [] | ||
thumbnailUrlNotAvailable: [], | ||
lufs: [] | ||
}); | ||
@@ -1051,4 +1097,21 @@ return { | ||
} | ||
function getLufsForFile(filePath) { | ||
try { | ||
const command = `ffmpeg -i ${filePath} -filter_complex ebur128 -f null - 2>&1 | grep -E 'I:.+ LUFS\$' | tail -1`; | ||
const result = execSync(command); | ||
const resArray = result.toString().trim().split(" "); | ||
const lastItem = resArray.at(-1); | ||
const isError = !lastItem || lastItem.toLowerCase() !== "lufs"; | ||
if (isError) | ||
return { error: "Unable to parse LUFS from ffmpeg command" }; | ||
const valueItem = resArray.at(-2); | ||
const num = Number(valueItem); | ||
return isNaN(num) ? { error: `Unexpected \`NaN\`: ${valueItem}` } : num; | ||
} catch (e) { | ||
return { error: e.message }; | ||
} | ||
} | ||
var MAX_YOUTUBE_RESULTS = 50; | ||
export { | ||
getLufsForFile, | ||
genStats, | ||
@@ -1055,0 +1118,0 @@ genDuplicatePlaylistEntries, |
@@ -6,3 +6,3 @@ { | ||
"type": "module", | ||
"version": "7.3.0", | ||
"version": "7.4.0", | ||
"exports": { | ||
@@ -9,0 +9,0 @@ ".": { |
Sorry, the diff of this file is too big to display
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
158638
3599
2