moovyket/subtitle-extract
James Ketrenos 6efcc0dabe Added subtitle
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2021-10-26 13:48:57 -07:00

105 lines
2.7 KiB
JavaScript
Executable File

#!/usr/bin/nodejs
const { spawn } = require('child_process'),
filename = process.argv[2],
child = spawn('ffmpeg', [
'-i', filename
]),
streams = [],
basename = filename.replace(/\.[^.]+$/, "");
let output = [];
child.stdout.on('data', (data) => {
});
child.stderr.on('data', (data) => {
output += data;
});
/*
Stream #0:2(eng): Subtitle: ass (default)
Metadata:
title : English
BPS-eng : 130
DURATION-eng : 00:47:44.040000000
...
Stream #0:4(eng): Subtitle: hdmv_pgs_subtitle
Metadata:
BPS : 3072
BPS-eng : 3072
DURATION : 00:21:51.602000000
DURATION-eng : 00:21:51.602000000
*/
let stream = undefined;
child.on('close', code => {
output.toString().split('\n').forEach(line => {
const parts = line.match(/^\s*Stream\s+#([^ ]+) Subtitle:\s*([^ ]+).*$/);
if (parts && parts.length > 0) {
/* parts[1] = '0:2(eng):'
parts[2] = 'srt'
*/
if (stream) {
streams.push(stream);
}
stream = {
extension: parts[2].replace(/hdmv_pgs_subtitle/, 'sup'), /* srt, sup */
number: parts[1].replace(/^.*([^(]+).*$/, '$1'), /* 0:2 -- not used */
language: parts[1].replace(/^[^(]*\((.*)\).*$/, '$1') /* eng */
};
return;
}
/* We tried parsing out 'title' for the langauge title, however
* that is not a consistent standard and title seems to be used
* arbitrarily. Instead, we will rely on the 'language' we parse
* from the stream name, which is specified inISO 639-1:
https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
*/
if (stream) {
if (!stream.metadata) {
if (/^\s*Metadata:.*/.exec(line)) {
stream.metadata = true;
} else {
streams.push(stream);
stream = undefined;
}
return;
}
const language = line.match(/^\s*title\s*:\s*([^\s]+)/);
if (language && language.length > 0) {
stream.language = language[1].toLowerCase();
streams.push(stream);
stream = undefined;
}
}
});
streams.forEach((stream, index) => {
const target = `${basename}.${index}_${stream.language}.${stream.extension}`,
ffmpeg = spawn('ffmpeg', [
'-i', filename,
'-c:s', 'copy',
'-map', `0:s:${index}`,
'-y',
target
]);
console.log(`0:s:${index} => ${target}`);
ffmpeg.stdout.on('data', (data) => {
console.log(data.toString());
});
ffmpeg.stderr.on('data', (data) => {
console.error(data.toString());
});
ffmpeg.on('close', code => {
console.log(`Completed: ${target} ${code}`);
});
});
console.log(JSON.stringify(streams));
});