Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add classic plugin: Rename Audio Title Plugin #735

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions Community/Tdarr_Plugin_rdub_audio_rename_channels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* eslint-disable no-console */
const details = () => ({
id: 'Tdarr_Plugin_rdub_audio_rename_channels',
Stage: 'Pre-processing',
Name: 'Rdub Rename Audio Titles',
Type: 'Video',
Operation: 'Transcode',
Description: 'This plugin renames titles for audio streams. '
+ 'An example would be in VLC -> Audio -> Audio Track -> "5.1 - [English]" \n\n'
+ '- 8 Channels will replace the title with 7.1\n '
+ '- 6 Channels will replace the title with 5.1"\n '
+ '- 2 Channels will replace the title with 2.0',
Version: '1.0',
Tags: 'pre-processing,ffmpeg',
Inputs: [],
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const plugin = (file, librarySettings, inputs, otherArguments) => {
const lib = require('../methods/lib')();

// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign
inputs = lib.loadDefaultValues(inputs, details);

const response = {
processFile: false,
preset: '',
container: `.${file.container}`,
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: false,
infoLog: '',
};

// Initialize ffmpeg command insert
let ffmpegCommandInsert = '';
let modifyFile = false;

// Check if file is a video. If it isn't, exit the plugin.
if (file.fileMedium !== 'video') {
response.infoLog += '☒ File is not a video. Skipping processing.\n';
response.processFile = false;
return response;
}

// Initialize audioIndex to track audio streams separately
let audioIndex = 0;

// Go through each stream in the file
for (let i = 0; i < file.ffProbeData.streams.length; i += 1) {
// Check if the stream is an audio stream
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
try {
// Retrieve current title metadata
let currentTitle = file.ffProbeData.streams[i].tags?.title || '';

// Trim whitespace
currentTitle = currentTitle.trim();

// Check if the title matches a standard format ("7.1", "5.1", "2.0")
if (['7.1', '5.1', '2.0'].includes(currentTitle)) {
response.infoLog += `☑ Audio stream ${audioIndex} already has a renamed title: "${currentTitle}".`
+ ' Skipping further renaming.\n';

// Increment audioIndex since we are processing an audio stream
// eslint-disable-next-line no-plusplus
audioIndex++;

// Skip further renaming for this stream
// eslint-disable-next-line no-continue
continue;
}

// Determine new title based on the channel count
let newTitle = '';
if (file.ffProbeData.streams[i].channels === 8) {
newTitle = '7.1';
} else if (file.ffProbeData.streams[i].channels === 6) {
newTitle = '5.1';
} else if (file.ffProbeData.streams[i].channels === 2) {
newTitle = '2.0';
}

// Rename the title if applicable
if (newTitle) {
response.infoLog += `☑ Audio stream ${audioIndex} has ${file.ffProbeData.streams[i].channels} channels. `
+ `Renaming title to "${newTitle}"\n`;

ffmpegCommandInsert += ` -metadata:s:a:${audioIndex} title=${newTitle} `;
modifyFile = true;
}
} catch (err) {
// Log error during audio stream processing
response.infoLog += `Error processing audio stream ${audioIndex}: ${err}\n`;
}

// Increment audioIndex for the next audio stream
// eslint-disable-next-line no-plusplus
audioIndex++;
}
}

// Finalize the command if modifications were made
if (modifyFile) {
response.infoLog += '☒ File has audio tracks to rename. Renaming...\n';

// Set the new preset
response.preset = `, ${ffmpegCommandInsert} -c copy -map 0 -max_muxing_queue_size 9999`;

// Re-queue the file for further processing
response.reQueueAfter = true;
response.processFile = true;
} else {
// No modifications needed
response.infoLog += '☑ File has no need to rename audio streams.\n';
}

return response;
};

module.exports.details = details;
module.exports.plugin = plugin;
119 changes: 119 additions & 0 deletions tests/Community/Tdarr_Plugin_rdub_audio_rename_channels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint max-len: 0 */
const _ = require('lodash');
const run = require('../helpers/run');

// Test suite for the Tdarr_Plugin_rdub_audio_rename_channels plugin
const pluginTests = [

{
input: {
file: (() => {
const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json'));
// Simulate a video file with multiple audio streams
file.fileMedium = 'video';
file.ffProbeData.streams = [
{
codec_type: 'audio',
channels: 8,
tags: { title: '' },
},
{
codec_type: 'audio',
channels: 6,
tags: { title: '' },
},
{
codec_type: 'audio',
channels: 2,
tags: { title: '' },
},
];
return file;
})(),
librarySettings: {},
inputs: {},
otherArguments: {},
},
output: {
processFile: true,
preset: ', -metadata:s:a:0 title=7.1 -metadata:s:a:1 title=5.1 -metadata:s:a:2 title=2.0 -c copy -map 0 -max_muxing_queue_size 9999',
container: '.mkv',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: '☑ Audio stream 0 has 8 channels. Renaming title to "7.1"\n'
+ '☑ Audio stream 1 has 6 channels. Renaming title to "5.1"\n'
+ '☑ Audio stream 2 has 2 channels. Renaming title to "2.0"\n'
+ '☒ File has audio tracks to rename. Renaming...\n',
},
},

{
input: {
file: (() => {
const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json'));
// Simulate a video file with already renamed audio streams
file.fileMedium = 'video';
file.ffProbeData.streams = [
{
codec_type: 'audio',
channels: 8,
tags: { title: '7.1' },
},
{
codec_type: 'audio',
channels: 6,
tags: { title: '5.1' },
},
{
codec_type: 'audio',
channels: 2,
tags: { title: '2.0' },
},
];
return file;
})(),
librarySettings: {},
inputs: {},
otherArguments: {},
},
output: {
processFile: false,
preset: '',
container: '.mkv',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: false,
infoLog: '☑ Audio stream 0 already has a renamed title: "7.1". Skipping further renaming.\n'
+ '☑ Audio stream 1 already has a renamed title: "5.1". Skipping further renaming.\n'
+ '☑ Audio stream 2 already has a renamed title: "2.0". Skipping further renaming.\n'
+ '☑ File has no need to rename audio streams.\n',
},
},

{
input: {
file: (() => {
const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json'));
// Simulate a non-video file
file.fileMedium = 'audio';
file.ffProbeData.streams = [];
return file;
})(),
librarySettings: {},
inputs: {},
otherArguments: {},
},
output: {
processFile: false,
preset: '',
container: '.mkv',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: false,
infoLog: '☒ File is not a video. Skipping processing.\n',
},
},
];

void run(pluginTests);