Extended version I created for a ticket user:
Main differences:
- special logging capabilities
- exception-test boolean
- all "settings" (boolean switches) are at the beginning of the code
- uses "early return" principle
Code:
Code:
function run() {
// Converts aac/m4a/ogg/opus files to mp3.
// Trigger: "A Download Stopped"
// Requires ffmpeg/ffprobe. Uses ffmpeg/ffprobe settings if available.
// Does NOT overwrite the destination file (mp3) if it already exists.
var testExceptionHandling = false; // Boolean to trigger a test exception
var writeErrorToLogfile = true; // Boolean to determine if errors should be written to a log file
var deleteSourceFile = true; // Set whether the source file should be deleted after conversion.
try {
if (!link.isFinished()) {
throw new Error("Download is not finished yet"); // Throw error if the download is not completed.
}
// Extract file name and extension (as provided)
var fileName = link.name.replace(/(.+)(\..+$)/, "$1");
var fileType = link.name.replace(/(.+)(\..+$)/, "$2");
var sourceFile = link.getDownloadPath();
// Check if the file is an audio file (aac/m4a/ogg/opus)
var isAudioFile = /\.(aac|m4a|ogg|opus)$/i.test(sourceFile);
if (!isAudioFile) {
return; // Exit the function if it is not an audio file.
}
var downloadFolder = package.getDownloadFolder();
var destFile = downloadFolder + "/" + fileName + ".mp3";
// Check if the destination file already exists
if (getPath(destFile).exists()) {
throw new Error("The destination file already exists"); // Throw error if the destination file already exists.
}
// Retrieve ffmpeg and ffprobe paths (unchanged)
var ffmpeg = callAPI("config", "get", "org.jdownloader.controlling.ffmpeg.FFmpegSetup", null, "binarypath");
var ffprobe = callAPI("config", "get", "org.jdownloader.controlling.ffmpeg.FFmpegSetup", null, "binarypathprobe");
// ffprobe call with "-v quiet" (as provided)
var data = JSON.parse(callSync(ffprobe, "-v", "quiet", "-print_format", "json", "-show_streams", "-show_format", sourceFile));
if (!data || !data.streams || data.streams.length === 0) {
throw new Error("No valid data could be retrieved from the source file"); // Throw error if no valid data is found.
}
if (testExceptionHandling) {
throw new Error("Test-Exception wurde manuell ausgelöst"); // Throw test exception if the flag is true
}
// Calculate bitrate (as provided)
var streamsBitrate = data.streams[0].bit_rate ? data.streams[0].bit_rate : 0;
var formatBitrate = data.format.bit_rate ? data.format.bit_rate : 0;
var bitrate = Math.max(streamsBitrate, formatBitrate) / 1000; // Convert bitrate to Kbps
// Throw error if the bitrate is invalid
if (bitrate <= 0) {
throw new Error("The file's bitrate is invalid");
}
// Convert the file with ffmpeg
callSync(ffmpeg, "-y", "-i", sourceFile, "-b:a", bitrate + "k", destFile);
// Delete the source file if the conversion was successful
if (deleteSourceFile && getPath(destFile).exists()) {
deleteFile(sourceFile, false);
}
} catch (e) {
// Check if the destination file path was determined
if (writeErrorToLogfile && typeof destFile !== 'undefined') {
// Create a log file and write the exception text into it
var logFilePath = package.getDownloadFolder() + "/" + fileName + ".txt";
var text = e.name + ": " + e.message;
writeFile(logFilePath, text, true);
}
// Re-throw the exception to propagate it further
throw e;
}
}
// Run the function
run();