From d472725167c1d335996059d24b7b74f3730768fb Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 17 Sep 2026 15:06:57 +0200 Subject: feat: tell a forced subtitle track from a full one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported as "I click a subtitle and nothing appears", on three films. Nothing was broken. The track selected was the container's forced track, which carries signage and foreign dialogue only: measured on the film in question, 30 cues and 77 seconds of text across 2h32 — 0.8% of the running time, against 1559 cues and 41.8% for the full track sitting beside it under the same language tag. At all three positions tested there was genuinely no cue to show; the full track would have shown one at two of them. So the defect is that the menu could not say which was which. The label used the container's title tag, which said "Forced" on that film and says nothing at all on most, and no other field was carried. The disposition is the half that is always there: `probe_video` now reads `forced` and `hearing_impaired`, `stream_init` carries them, and the label states them in the reader's own language rather than repeating an English word a muxer happened to type. The node fixture grows a forced track with no title, because a title would let the old code pass. The label harness's `t` stub took a parameters object unconditionally and threw on a key that has none — a fixture narrower than production, fixed here rather than worked around. Also removes the activeCues probe that found this. It answered its question: mode showing, cues 30, active 0, none due at that instant. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01UGY17EPph5LsLzePPXhUVc --- .../tests/test_stream_subtitle_tracks.py | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'packages/meshbay-node/tests/test_stream_subtitle_tracks.py') diff --git a/packages/meshbay-node/tests/test_stream_subtitle_tracks.py b/packages/meshbay-node/tests/test_stream_subtitle_tracks.py index cafb2e3..9a09edb 100644 --- a/packages/meshbay-node/tests/test_stream_subtitle_tracks.py +++ b/packages/meshbay-node/tests/test_stream_subtitle_tracks.py @@ -95,6 +95,9 @@ def _make_subtitled_clip(path: Path) -> None: "-metadata:s:s:0", "language=fre", "-metadata:s:s:1", "language=fre", "-metadata:s:s:2", "language=eng", + # Ordinal 1 is the forced one, and carries no title saying so — which + # is the case the disposition exists for. + "-disposition:s:1", "forced", str(path)], check=True, capture_output=True) @@ -208,6 +211,31 @@ def test_bitmap_codecs_are_not_offered(): assert "ass" in TEXT_SUBTITLE_CODECS +@pytest.mark.asyncio +async def test_a_forced_track_says_so_without_needing_a_title(tmp_path): + """The distinction a viewer cannot make for themselves. + + A forced track carries signage and foreign dialogue only — on a real film, + 30 cues and 77 seconds of text across 2h32, against 1559 cues and 41% of + the running time for the full track beside it. Selecting it and seeing + nothing for ten minutes is its normal behaviour, and was reported as a + broken feature. The container's title tag would say it too, when it is + there; the disposition is the half that is always there. + """ + clip = tmp_path / "clip.mp4" + _make_subtitled_clip(clip) + + probe = await _probe_video(str(clip)) + by_ordinal = {tr.ordinal: tr for tr in probe.subtitle_tracks} + + assert by_ordinal[1].forced is True + assert by_ordinal[2].forced is False + assert by_ordinal[1].title is None, ( + "the fixture must carry no title on the forced track, or it does not " + "exercise the case the disposition is for") + assert all(not tr.hearing_impaired for tr in probe.subtitle_tracks) + + @pytest.mark.asyncio async def test_stream_init_announces_the_tracks(tmp_path): """How a client discovers this node can do subtitles at all. @@ -226,6 +254,9 @@ async def test_stream_init_announces_the_tracks(tmp_path): init = next(m for m in session.sent if m.get("type") == "stream_init") assert [tr["i"] for tr in init["subtitle_tracks"]] == [1, 2] assert [tr["lang"] for tr in init["subtitle_tracks"]] == ["fre", "eng"] + assert [tr["forced"] for tr in init["subtitle_tracks"]] == [True, False], ( + "the client cannot mark a forced track it was never told about") + assert [tr["sdh"] for tr in init["subtitle_tracks"]] == [False, False] @pytest.mark.parametrize("track", [1, 2]) -- cgit v1.2.3