aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/locales
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-17 13:39:23 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-17 13:39:23 +0200
commitad4ca3229002997934ccb5b2eaeb553c13b8888f (patch)
treea680f9e5d3ba43a84236b84f73e0b71eaf916db4 /packages/meshbay-hub/src/meshbay_hub/static/locales
parent3e6d514663a5df1be3b2f0286c5f67f669d9c1d6 (diff)
downloadmeshbay-ad4ca3229002997934ccb5b2eaeb553c13b8888f.tar.gz
feat: embedded subtitles in the video player (MNP 3.3)
MSE decodes no in-band text track, so a subtitle cannot ride inside the fragmented MP4 the player is fed. The node extracts one track whole, converts it to WebVTT and caches it under its own hash; the client pulls that blob through the ordinary file_req/chunk path and hangs a <track> on the video element — the same indirection as a TMDB poster or an audio transcode, which is what makes a film's subtitles extracted once in the life of the file rather than once per viewing. Whole-file also makes the cues absolute, so a seek and an audio-language change both leave the track untouched. **The ordinal counts every subtitle stream, including the ones never listed.** Only text codecs are offered: a bitmap track (PGS, VOBSUB — about a fifth of a real library) has no path to WebVTT without OCR, and one extracted anyway yields a header with no cues, which is a menu entry that shows nothing and reports no error. Numbering the survivors of that filter would give a PGS/SRT/SRT file the ordinals 0 and 1 for its text tracks and `-map 0:s:0` would then extract the PGS — the same trap `AudioTrack.ordinal` exists for, one level deeper. A fixture whose first subtitle stream cannot be decoded pins it, and the handler checks membership of the probed list, never a range. Additive and MINOR: the selector is drawn from `subtitle_tracks` in the node's own `stream_init` and from no version number, so `subtitle_req` is never sent to a peer that would not answer it. The floor stays at 3.0. Also here: a failed extraction never touches playback, a superseded reply cannot install its blob over a newer choice, and `_languageName` is shared with the audio labels — lifted by both label harnesses, since a lift that names one function stops covering the rule the moment logic moves out of it. Tests: 9 node (tracks told apart by the words in the extracted cues, not by tags), 10 client. Full suite green: 1545 node/common, 1252 hub. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UGY17EPph5LsLzePPXhUVc
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/locales')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/de.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/en.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/it.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js4
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js4
10 files changed, 40 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
index 806fa38..dd53bcf 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
@@ -251,6 +251,10 @@ export default {
'video.from_start': "Von vorn beginnen",
'video.audio_track': 'Tonspur',
'video.audio_track_n': 'Spur {n}',
+ 'video.subtitles': 'Untertitel',
+ 'video.subtitles_off': 'Aus',
+ 'video.subtitle_track_n': 'Spur {n}',
+ 'video.err_subtitle': 'Diese Untertitelspur konnte nicht geladen werden',
'video.close': 'Schließen (Esc)',
'preview.pdf_fallback': 'Dieser Browser zeigt das PDF nicht direkt an. Laden Sie es '
+ 'stattdessen herunter — entschlüsselt wurde es ohnehin hier.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
index 92114c9..e9f3d8d 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
@@ -250,6 +250,10 @@ export default {
'video.from_start': "Start from the beginning",
'video.audio_track': 'Audio track',
'video.audio_track_n': 'Track {n}',
+ 'video.subtitles': 'Subtitles',
+ 'video.subtitles_off': 'Off',
+ 'video.subtitle_track_n': 'Track {n}',
+ 'video.err_subtitle': 'Could not load this subtitle track',
'video.close': 'Close (Esc)',
'preview.pdf_fallback': 'This browser will not display the PDF inline. Download it instead — it was decrypted here either way.',
'preview.too_large': 'This file is {size}, more than this page can hold in memory ({limit}). Download it instead — a download is written straight to disk.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
index d9b8f63..68fbe10 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
@@ -249,6 +249,10 @@ export default {
'video.from_start': "Empezar desde el principio",
'video.audio_track': 'Pista de audio',
'video.audio_track_n': 'Pista {n}',
+ 'video.subtitles': 'Subtítulos',
+ 'video.subtitles_off': 'Ninguno',
+ 'video.subtitle_track_n': 'Pista {n}',
+ 'video.err_subtitle': 'No se pudo cargar esta pista de subtítulos',
'video.close': 'Cerrar (Esc)',
'preview.pdf_fallback': 'Este navegador no mostrará el PDF integrado. Descárguelo '
+ 'en su lugar — en cualquier caso se descifró aquí.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
index d507d28..679a458 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -250,6 +250,10 @@ export default {
'video.from_start': "Reprendre depuis le début",
'video.audio_track': 'Piste audio',
'video.audio_track_n': 'Piste {n}',
+ 'video.subtitles': 'Sous-titres',
+ 'video.subtitles_off': 'Aucun',
+ 'video.subtitle_track_n': 'Piste {n}',
+ 'video.err_subtitle': 'Impossible de charger cette piste de sous-titres',
'video.close': 'Fermer (Échap)',
'preview.pdf_fallback': 'Ce navigateur n’affichera pas le PDF directement. '
+ 'Téléchargez-le plutôt — il a été déchiffré ici dans les deux cas.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
index b6c68dd..9a34c93 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
@@ -250,6 +250,10 @@ export default {
'video.from_start': "Riparti dall'inizio",
'video.audio_track': 'Traccia audio',
'video.audio_track_n': 'Traccia {n}',
+ 'video.subtitles': 'Sottotitoli',
+ 'video.subtitles_off': 'Nessuno',
+ 'video.subtitle_track_n': 'Traccia {n}',
+ 'video.err_subtitle': 'Impossibile caricare questa traccia di sottotitoli',
'video.close': 'Chiudi (Esc)',
'preview.pdf_fallback': 'Questo browser non mostrerà il PDF nella pagina. Lo scarichi '
+ 'invece — in ogni caso è stato decifrato qui.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
index 99e2e1f..1d58e2c 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
@@ -247,6 +247,10 @@ export default {
'video.from_start': "最初から再生する",
'video.audio_track': '音声トラック',
'video.audio_track_n': 'トラック {n}',
+ 'video.subtitles': '字幕',
+ 'video.subtitles_off': 'なし',
+ 'video.subtitle_track_n': 'トラック {n}',
+ 'video.err_subtitle': 'この字幕トラックを読み込めませんでした',
'video.close': '閉じる(Esc)',
'preview.pdf_fallback': 'このブラウザーはページ内に PDF を表示しません。'
+ 'ダウンロードしてご覧ください。いずれにせよ復号はここで行われています。',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
index 269fa70..5bef61f 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
@@ -251,6 +251,10 @@ export default {
'video.from_start': "Vanaf het begin afspelen",
'video.audio_track': 'Audiospoor',
'video.audio_track_n': 'Spoor {n}',
+ 'video.subtitles': 'Ondertiteling',
+ 'video.subtitles_off': 'Geen',
+ 'video.subtitle_track_n': 'Spoor {n}',
+ 'video.err_subtitle': 'Dit ondertitelspoor kon niet worden geladen',
'video.close': 'Sluiten (Esc)',
'preview.pdf_fallback': 'Deze browser toont de PDF niet in de pagina zelf. Download '
+ 'hem in plaats daarvan — ontsleuteld werd hij hoe dan ook hier.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
index 363296c..8989880 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
@@ -256,6 +256,10 @@ export default {
'video.from_start': "Odtwórz od początku",
'video.audio_track': 'Ścieżka dźwiękowa',
'video.audio_track_n': 'Ścieżka {n}',
+ 'video.subtitles': 'Napisy',
+ 'video.subtitles_off': 'Brak',
+ 'video.subtitle_track_n': 'Ścieżka {n}',
+ 'video.err_subtitle': 'Nie udało się wczytać tej ścieżki napisów',
'video.close': 'Zamknij (Esc)',
'preview.pdf_fallback': 'Ta przeglądarka nie wyświetli pliku PDF na stronie. Proszę '
+ 'go pobrać — i tak został odszyfrowany tutaj.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
index 2a90956..f1b8643 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
@@ -251,6 +251,10 @@ export default {
'video.from_start': "Começar do início",
'video.audio_track': 'Faixa de áudio',
'video.audio_track_n': 'Faixa {n}',
+ 'video.subtitles': 'Legendas',
+ 'video.subtitles_off': 'Nenhuma',
+ 'video.subtitle_track_n': 'Faixa {n}',
+ 'video.err_subtitle': 'Não foi possível carregar esta faixa de legendas',
'video.close': 'Fechar (Esc)',
'preview.pdf_fallback': 'Este navegador não exibirá o PDF na própria página. Baixe '
+ 'o arquivo — de todo modo ele foi descriptografado aqui.',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
index e3aa440..91da464 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
@@ -245,6 +245,10 @@ export default {
'video.from_start': "从头开始播放",
'video.audio_track': '音轨',
'video.audio_track_n': '音轨 {n}',
+ 'video.subtitles': '字幕',
+ 'video.subtitles_off': '关闭',
+ 'video.subtitle_track_n': '字幕 {n}',
+ 'video.err_subtitle': '无法加载此字幕轨道',
'video.close': '关闭(Esc)',
'preview.pdf_fallback': '此浏览器不会在页面内显示该 PDF。请改为下载——无论如何它都已在本地解密。',
'preview.too_large': '该文件为 {size},超出本页面可在内存中保存的上限({limit})。请改为下载——下载会直接写入磁盘。',