From 902364e391798051fa77dd55c3f7ea714b155105 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Wed, 27 Mar 2024 01:27:03 -0400 Subject: [PATCH] feat(node-subsync): use ffprobe to check available languages --- .../nos/modules/subtitles/syncing/default.nix | 6 +- .../syncing/node-syncsub/default.nix | 7 ++- .../subtitles/syncing/node-syncsub/main.ts | 57 ++++++++++++------- .../syncing/node-syncsub/package-lock.json | 47 +++++++++++++-- .../syncing/node-syncsub/package.json | 4 ++ flake.nix | 1 + 6 files changed, 90 insertions(+), 32 deletions(-) diff --git a/devices/nos/modules/subtitles/syncing/default.nix b/devices/nos/modules/subtitles/syncing/default.nix index 414b4fbc..3e64b5e0 100644 --- a/devices/nos/modules/subtitles/syncing/default.nix +++ b/devices/nos/modules/subtitles/syncing/default.nix @@ -31,9 +31,9 @@ in { ]; script = '' - find /data/anime -name '*.srt' -exec node-syncsub "{}" \; - find /data/movies -name '*.srt' -exec node-syncsub "{}" \; - find /data/tv -name '*.srt' -exec node-syncsub "{}" \; + # find /data/anime -name '*.srt' -exec node-syncsub "{}" \; + # find /data/movies -name '*.srt' -exec node-syncsub "{}" \; + # find /data/tv -name '*.srt' -exec node-syncsub "{}" \; ''; }; timers.subsync-job = { diff --git a/devices/nos/modules/subtitles/syncing/node-syncsub/default.nix b/devices/nos/modules/subtitles/syncing/node-syncsub/default.nix index 034a0033..e5f679cb 100644 --- a/devices/nos/modules/subtitles/syncing/node-syncsub/default.nix +++ b/devices/nos/modules/subtitles/syncing/node-syncsub/default.nix @@ -1,5 +1,6 @@ { buildNpmPackage, + ffmpeg, nodejs_20, subsync, typescript, @@ -8,13 +9,13 @@ buildNpmPackage { name = "node-syncsub"; src = ./.; - npmDepsHash = "sha256-kQBZ13bTMxZnv45IwyIV0cYA5tjr4KKU1cpDNx02th0= -"; + npmDepsHash = "sha256-O00VQPCUX6T+rtK3VcAibBipXFwNs4AFA3251qycPBQ="; nativeBuildInputs = [ + nodejs_20 + ffmpeg subsync typescript - nodejs_20 ]; buildPhase = '' diff --git a/devices/nos/modules/subtitles/syncing/node-syncsub/main.ts b/devices/nos/modules/subtitles/syncing/node-syncsub/main.ts index 4be7d25f..2574ddbe 100755 --- a/devices/nos/modules/subtitles/syncing/node-syncsub/main.ts +++ b/devices/nos/modules/subtitles/syncing/node-syncsub/main.ts @@ -1,4 +1,6 @@ import { readdir } from 'fs'; +import { ffprobe } from 'fluent-ffmpeg'; +import { exec } from 'child_process'; const SUB_EXT_LENGTH = 7; @@ -14,40 +16,53 @@ const main = () => { const DIR = FILE.substring(0, FILE.lastIndexOf('/')); readdir(DIR, (_, files) => { - const VIDEO = files.filter((f) => + const VIDEO = `${DIR}/${files.filter((f) => f.includes(BASE_NAME) && !f.endsWith('.nfo') && - !f.endsWith('.srt'))[0]; + !f.endsWith('.srt'))[0]}`; - let lang = FILE.split('.').at(-2); + ffprobe(VIDEO, (_e, data) => { + const other = (lang: string) => lang === 'fre' ? 'eng' : 'fre'; - if (lang === 'fr') { - lang = 'fre'; - } - else if (lang === 'en') { - lang = 'eng'; - } + let lang = FILE.split('.').at(-2) ?? 'en'; - const cmd = [ - 'subsync --cli sync', - `--sub-lang ${lang}`, - `--ref-lang ${lang}`, + if (lang === 'fr') { + lang = 'fre'; + } + else if (lang === 'en') { + lang = 'eng'; + } - `--sub-file '${FILE}'`, - `--out-file '${FILE}'`, - `--ref-file '${VIDEO}'`, + const availLangs = data.streams + .filter((s) => s.codec_type === 'audio') + .map((s) => s['tags']['language']); - '--overwrite', - ]; + const cmd = [ + 'subsync --cli sync', + `--sub-lang ${lang}`, - // TODO: actually call the command - console.log(cmd); + `--ref-stream-by-lang ${availLangs.includes(lang) ? lang : other(lang)}`, + '--ref-stream-by-type "audio"', + + `--sub '${FILE}'`, + `--out '${DIR}/${BASE_NAME}.synced.${lang.substring(0, 2)}.srt'`, + // `--out '${FILE}'`, + `--ref '${VIDEO}'`, + + // '--overwrite', + ].join(' '); + + exec(cmd, (error, stdout, stderr) => { + console.log(error); + console.log(stdout); + console.log(stderr); + }); + }); }); }; if (FILE) { main(); - process.exit(); } else { console.error('Error: no argument passed'); diff --git a/devices/nos/modules/subtitles/syncing/node-syncsub/package-lock.json b/devices/nos/modules/subtitles/syncing/node-syncsub/package-lock.json index 112148a5..b4dd66f2 100644 --- a/devices/nos/modules/subtitles/syncing/node-syncsub/package-lock.json +++ b/devices/nos/modules/subtitles/syncing/node-syncsub/package-lock.json @@ -4,6 +4,10 @@ "requires": true, "packages": { "": { + "dependencies": { + "@types/fluent-ffmpeg": "^2.1.24", + "fluent-ffmpeg": "^2.1.2" + }, "devDependencies": { "@stylistic/eslint-plugin": "^1.4.0", "@types/node": "^20.10.5", @@ -292,6 +296,14 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/fluent-ffmpeg": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.24.tgz", + "integrity": "sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -302,7 +314,6 @@ "version": "20.11.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -585,6 +596,11 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1013,6 +1029,29 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==", + "dependencies": { + "async": ">=0.2.9", + "which": "^1.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fluent-ffmpeg/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1215,8 +1254,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -1726,8 +1764,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/uri-js": { "version": "4.4.1", diff --git a/devices/nos/modules/subtitles/syncing/node-syncsub/package.json b/devices/nos/modules/subtitles/syncing/node-syncsub/package.json index b8880e51..ed3f8425 100644 --- a/devices/nos/modules/subtitles/syncing/node-syncsub/package.json +++ b/devices/nos/modules/subtitles/syncing/node-syncsub/package.json @@ -6,5 +6,9 @@ "@typescript-eslint/parser": "^6.9.1", "eslint": "^8.52.0", "typescript": "^5.3.3" + }, + "dependencies": { + "@types/fluent-ffmpeg": "^2.1.24", + "fluent-ffmpeg": "^2.1.2" } } diff --git a/flake.nix b/flake.nix index 063d48d7..da2226df 100644 --- a/flake.nix +++ b/flake.nix @@ -95,6 +95,7 @@ packages = with pkgs; [ nodejs_latest + ffmpeg typescript ] ++ (with nodePackages; [