-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTdarr_Plugin_MC93_Migz4CleanSubs_MOD.js
243 lines (230 loc) · 9.51 KB
/
Tdarr_Plugin_MC93_Migz4CleanSubs_MOD.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = () => ({
id: 'Tdarr_Plugin_MC93_Migz4CleanSubs_MOD',
Stage: 'Pre-processing',
Name: 'Migz-Clean subtitle streams',
Type: 'Subtitle',
Operation: 'Transcode',
Description: 'This plugin keeps only specified language tracks & can tag tracks with an unknown language, MOD: remove anime signs and songs. \n\n',
Version: '2.4',
Tags: 'pre-processing,ffmpeg,subtitle only,configurable',
Inputs: [{
name: 'language',
type: 'string',
defaultValue: 'eng',
inputUI: {
type: 'text',
},
tooltip: `Specify language tag/s here for the subtitle tracks you'd like to keep.
\\nMust follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
\\nExample:\\n
eng
\\nExample:\\n
eng,jpn`,
},
{
name: 'commentary',
type: 'boolean',
defaultValue: false,
inputUI: {
type: 'dropdown',
options: [
'false',
'true',
],
},
tooltip: `Specify if subtitle tracks that contain commentary/description should be removed.
\\nExample:\\n
true
\\nExample:\\n
false`,
},
{
name: 'signssongs',
type: 'boolean',
defaultValue: false,
inputUI: {
type: 'dropdown',
options: [
'false',
'true',
],
},
tooltip: `Specify if subtitle tracks that contain signs and songs should be removed.
\\nExample:\\n
true
\\nExample:\\n
false`,
},
{
name: 'tag_language',
type: 'string',
defaultValue: '',
inputUI: {
type: 'text',
},
tooltip: `Specify a single language for subtitle tracks with no language or unknown language to be tagged with.
\\nMust follow ISO-639-2 3 letter format. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
\\nLeave empty to disable.
\\nExample:\\n
eng
\\nExample:\\n
por`,
},
],
});
// eslint-disable-next-line no-unused-vars
const plugin = (file, librarySettings, inputs, otherArguments) => {
const lib = require('../methods/lib')();
// eslint-disable-next-line 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: '',
};
// Check if file is a video. If it isn't then exit plugin.
if (file.fileMedium !== 'video') {
// eslint-disable-next-line no-console
console.log('File is not video');
response.infoLog += '☒File is not video \n';
response.processFile = false;
return response;
}
// Check if inputs.language has been configured. If it hasn't then exit plugin.
if (inputs.language === '') {
response.infoLog
+= '☒Language/s to keep have not been configured, '
+ 'please configure required options. Skipping this plugin. \n';
response.processFile = false;
return response;
}
// Set up required variables.
const language = inputs.language.split(',');
let ffmpegCommandInsert = '';
let subtitleIdx = 0;
let convert = false;
let removeSub = false;
// Regex Pattern for Signs and Songs
let regexPatern = /(s\s*&\s*s|signs(\s?(and|&|\/)\s?songs)?)/i
// Go through each stream in the file.
for (let i = 0; i < file.ffProbeData.streams.length; i++) {
// Catch error here incase the language metadata is completely missing.
try {
// Check if stream is subtitle
// AND checks if the tracks language code does not match any of the languages entered in inputs.language.
if (
file.ffProbeData.streams[i].codec_type.toLowerCase() === 'subtitle'
&& language.indexOf(
file.ffProbeData.streams[i].tags.language.toLowerCase(),
) === -1
) {
ffmpegCommandInsert += `-map -0:s:${subtitleIdx} `;
response.infoLog += `☒Subtitle stream 0:s:${subtitleIdx} has unwanted language tag ${file.ffProbeData.streams[
i
].tags.language.toLowerCase()}, removing. \n`;
convert = true;
}
} catch (err) {
// Error
}
// Catch error here incase the title metadata is completely missing.
try {
// Check if inputs.commentary is set to true
// AND if stream is subtitle
// AND then checks for stream titles with the following "commentary, description, sdh".
// Removing any streams that are applicable.
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'subtitle') {
if (
inputs.commentary === true
&& (file.ffProbeData.streams[i].tags.title
.toLowerCase().includes('commentary')
|| file.ffProbeData.streams[i].tags.title
.toLowerCase().includes('description')
|| file.ffProbeData.streams[i].tags.title
.toLowerCase().includes('sdh')
)
) {
removeSub = true;
response.infoLog += `☒Subtitle stream 0:s:${subtitleIdx} detected as being descriptive, removing. \n`;
}
if(
inputs.signssongs === true
&& regexPatern.test(file.ffProbeData.streams[i].tags.title)
) {
removeSub = true;
response.infoLog += `☒Subtitle stream 0:s:${subtitleIdx} detected as being signs and songs, removing. \n`;
}
if(removeSub === true) {
ffmpegCommandInsert += `-map -0:s:${subtitleIdx} `;
convert = true;
removeSub = false;
}
}
} catch (err) {
// Error
}
// Check if inputs.tag_language has something entered.
// (Entered means user actually wants something to happen, empty would disable this)
// AND checks that stream is subtitle.
if (
inputs.tag_language !== ''
&& file.ffProbeData.streams[i].codec_type.toLowerCase() === 'subtitle'
) {
// Catch error here incase the metadata is completely missing.
try {
// Look for subtitle with "und" as metadata language.
if (
file.ffProbeData.streams[i].tags.language
.toLowerCase()
.includes('und')
) {
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
response.infoLog
+= `☒Subtitle stream 0:s:${subtitleIdx} has no language, tagging as ${inputs.tag_language}. \n`;
convert = true;
}
} catch (err) {
// Error
}
// Checks if the tags metadata is completely missing.
// If so this would cause playback to show language as "undefined".
// No catch error here otherwise it would never detect the metadata as missing.
if (typeof file.ffProbeData.streams[i].tags === 'undefined') {
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
response.infoLog
+= `☒Subtitle stream 0:s:${subtitleIdx} has no language, tagging as ${inputs.tag_language}. \n`;
convert = true;
} else if (typeof file.ffProbeData.streams[i].tags.language === 'undefined') {
// Checks if the tags.language metadata is completely missing.
// If so this would cause playback to show language as "undefined".
// No catch error here otherwise it would never detect the metadata as missing
ffmpegCommandInsert += `-metadata:s:s:${subtitleIdx} language=${inputs.tag_language} `;
response.infoLog
+= `☒Subtitle stream 0:s:${subtitleIdx} has no language, tagging as ${inputs.tag_language}. \n`;
convert = true;
}
}
// Check if stream type is subtitle and increment subtitleIdx if true.
if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'subtitle') {
subtitleIdx += 1;
}
}
// Convert file if convert variable is set to true.
if (convert === true) {
response.processFile = true;
response.preset = `, -map 0 ${ffmpegCommandInsert} -c copy -max_muxing_queue_size 9999`;
response.container = `.${file.container}`;
response.reQueueAfter = true;
} else {
response.processFile = false;
response.infoLog += "☑File doesn't contain subtitle tracks which are unwanted or that require tagging.\n";
}
return response;
};
module.exports.details = details;
module.exports.plugin = plugin;