#!/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)); });