1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
"""
A reconnection used to throw the read-ahead away.
The transport drops — a tunnel, a dead spot, a screen lock — and comes back.
The old stream died with it, so something has to be asked for again, and what
the player asked for was always the same thing: the stream, restarted at the
playhead. That goes through `reinitAt`, whose whole job is to empty the
SourceBuffer, because a seek has to.
But a reconnection is not a seek. The viewer did not navigate anywhere; the
film has been playing out of the buffer the entire time the link was gone, and
the buffer is the only reason it was still playing. Emptying it at the moment
the link returns is what finally stops the picture — and it is the *one* moment
the buffer is worth most.
This was invisible while the read-ahead was a fixed ninety seconds: a dead spot
long enough to notice had already drained the buffer, so there was nothing left
to throw away. Once the read-ahead became a byte budget worth minutes
(`test_video_buffer_ceiling.py`), it became the thing that stops the budget
paying for anything at all — several minutes of lead, bought and then discarded
by the reconnection it was bought for.
So `reconnectPlan` decides, and there are two modes that are not
interchangeable:
**resume** keeps the buffer and carries the stream on from the *end* of it. The
playhead must not move — it is already in the right place and still running.
**seek** discards the buffer and restarts at the playhead. The playhead must
move. This is the path that has always run, and it is still what happens when
there is no read-ahead worth keeping, or when the stream already ended.
`reconnectPlan` is pure and at module scope so that this file can *run* it
rather than read it. The rest is read, which is weak evidence and the only
evidence available for code that lives inside a component's effect.
"""
import json
import re
import shutil
import subprocess
from pathlib import Path
import pytest
STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static"
APP = STATIC / "video-player.js"
pytestmark = pytest.mark.skipif(
shutil.which("node") is None or not APP.exists(),
reason="node or the SPA sources are not available")
@pytest.fixture(scope="module")
def app():
return APP.read_text()
def _player(app: str) -> str:
i = app.index("function VideoPlayer(")
nxt = app.find("\nfunction ", i + 1)
return app[i:nxt if nxt > 0 else len(app)]
def _fn(player: str, name: str) -> str:
"""One `const <name> = ...` defined inside the effect, as text."""
i = player.index(f"const {name} = ")
return player[i:player.index("\n };", i)]
# ── The decision, executed ────────────────────────────────────────────────────
def _plan(app: str, cases: list[dict]) -> list[dict]:
"""Run the SHIPPED `reconnectPlan` over a table of cases.
Lifted out as text and executed, in the manner of harness/mse_harness.mjs:
a second implementation written here would agree with the first by
construction and prove nothing.
"""
i = app.index("function reconnectPlan(")
body = app[i:app.index("\n}\n", i) + 3]
const = re.search(r"^const RECONNECT_KEEP_MIN_S = .+;$", app, re.M)
assert const, "RECONNECT_KEEP_MIN_S is not a constant in video-player.js"
script = (
f"{const.group(0)}\n{body}\n"
f"console.log(JSON.stringify({json.dumps(cases)}.map("
"(c) => reconnectPlan(c.playhead, c.range, c.ended, c.cast))));"
)
proc = subprocess.run(["node", "--input-type=module", "-e", script],
capture_output=True, text=True)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_a_buffer_worth_keeping_is_carried_on_from_its_end(app):
"""The whole point: the minutes already paid for survive the reconnection."""
plan, = _plan(app, [{"playhead": 100, "range": [40, 400], "ended": False}])
assert plan["mode"] == "resume", (
"five minutes of read-ahead in hand and the reconnection still throws "
"it away")
assert plan["at"] == 400, (
f"resuming at {plan['at']} rather than the end of the buffer — "
"anything earlier re-fetches film already held")
def test_an_empty_buffer_still_restarts_at_the_playhead(app):
"""The old path, unchanged, for the case it was written for."""
plan, = _plan(app, [{"playhead": 100, "range": None, "ended": False}])
assert plan == {"mode": "seek", "at": 100}
def test_a_buffer_too_short_to_matter_takes_the_proven_path(app):
"""Below the threshold there is nothing to save and no reason to be clever.
Resuming buys a couple of seconds and costs a second code path through a
SourceBuffer that has just been reconnected; seeking is proven.
"""
keep = float(re.search(r"const RECONNECT_KEEP_MIN_S = (\d+)",
app).group(1))
below, at_threshold = _plan(app, [
{"playhead": 100, "range": [40, 100 + keep - 1], "ended": False},
{"playhead": 100, "range": [40, 100 + keep], "ended": False},
])
assert below["mode"] == "seek", (
f"{keep - 1}s of read-ahead took the resume path")
assert at_threshold["mode"] == "resume", (
f"exactly {keep}s of read-ahead did not, so the threshold excludes "
"its own boundary")
def test_a_cast_restarts_at_the_playhead_because_it_never_had_the_buffer(app):
"""The receiver is fed from the wire, not from this SourceBuffer.
`platform.cast.push` hands the relay each segment as it arrives, so
everything held in the SourceBuffer is material the receiver never saw.
Carrying on from the end of it would restart the relay there and skip the
television forward by the entire read-ahead — with a budget of minutes,
minutes of film silently missed.
"""
plan, = _plan(app, [{"playhead": 100, "range": [40, 400],
"ended": False, "cast": True}])
assert plan == {"mode": "seek", "at": 100}
def test_a_finished_stream_is_not_restarted_to_serve_nothing(app):
"""`endedRef` means the node already sent everything.
Asking to carry on from the end of the buffer would spawn an ffmpeg to
serve a position at or past the end of the film. Seeking is what this did
before the plan existed and is deliberately left alone.
"""
plan, = _plan(app, [{"playhead": 100, "range": [40, 400], "ended": True}])
assert plan["mode"] == "seek"
# ── Resuming must not do a seek's work ────────────────────────────────────────
def test_resuming_does_not_empty_the_buffer(app):
"""The one thing this whole change exists to stop."""
resume = _fn(_player(app), "resumeAt")
assert "sb.remove(0, Infinity)" not in resume, (
"resumeAt empties the SourceBuffer, which is exactly what it was "
"written to avoid")
assert "sb.abort()" in resume, (
"ffmpeg was killed mid-fragment, so the parser holds half of one and "
"the next stream's header lands on top of it")
assert "sb.timestampOffset = start" in resume, (
"the new fragments are not placed on the film's timeline, so they "
"land at zero instead of beside what is already buffered")
def test_resuming_does_not_move_the_playhead(app):
"""`landPlayhead` jumps the film to `seekTarget` once it is buffered.
A resume that set one would jump forward to the end of the buffer — over
the very minutes it just went to the trouble of keeping.
"""
resume = _fn(_player(app), "resumeAt")
assert "seekTargetRef.current = null" in resume, (
"resumeAt sets a seek target, so the film jumps to the end of the "
"buffer instead of playing through it")
assert "seekTargetRef.current = start" not in resume
def test_a_resume_that_would_leave_a_gap_falls_back(app):
"""A gap in the middle of a film is a permanent silent stall.
The node lands on a keyframe at or before what was asked for, and clamping
only ever moves it earlier, so this should not happen. "Should not happen"
is not the same as "cannot", and the proven path is one line away.
"""
resume = _fn(_player(app), "resumeAt")
assert "reinitAt(start)" in resume, (
"nothing catches a stream that starts past the end of the buffer, so "
"the film stalls on the gap for the rest of its run")
def test_the_reconnection_asks_the_plan_rather_than_assuming(app):
player = _player(app)
i = player.index("addReconnectListener(")
listener = player[i:player.index("\n });", i)]
assert "reconnectPlan(" in listener, (
"the reconnection still restarts at the playhead unconditionally")
assert "requestResume(" in listener, "nothing ever takes the resume path"
assert "seek(plan.at)" in listener, "nothing takes the seek path any more"
def test_resuming_does_not_show_the_loading_screen(app):
"""The film never stopped, so there is nothing to tell the viewer to await."""
resume_req = _fn(_player(app), "requestResume")
assert "setPhase('loading')" not in resume_req, (
"a reconnection that the buffer covered still blanks the picture for "
"a loading screen")
def test_the_resume_is_not_debounced(app):
"""The 350 ms exists for a finger on a scrubber; a reconnection happens once."""
resume_req = _fn(_player(app), "requestResume")
assert "SEEK_DEBOUNCE_MS" not in resume_req, (
"the resume waits out the scrubber debounce before asking, so the "
"stream restarts a third of a second later than it could")
# ── The flag that tells the two landings apart ────────────────────────────────
def test_the_two_landings_are_told_apart_and_the_flag_is_cleared(app):
player = _player(app)
init = player[player.index("transport.onStreamInit = "):]
init = init[:init.index("\n };")]
assert "const resuming = resumingRef.current;" in init
assert "resumingRef.current = false;" in init, (
"the flag outlives the stream_init it was raised for, so the next one "
"keeps a buffer nobody asked it to keep")
assert "resuming ? resumeAt : reinitAt" in init, (
"both landings still go through the same path")
def test_a_new_stream_and_a_seek_both_clear_the_resume_flag(app):
"""The `awaitingInitRef` trap, one ref along — see MESHBAY_DESIGN.md §8.5.
A resume in flight when the film changes, or when the viewer seeks, would
have the next `stream_init` keep a buffer belonging to something else.
"""
player = _player(app)
effect = player[player.index("useEffect(() => {\n let cancelled = false;"):]
reset = effect[:effect.index("const requestSeek = ")]
assert "resumingRef.current = false" in reset, (
"a resume in flight when the film changes is inherited by the new one")
seek = _fn(player, "requestSeek")
assert "resumingRef.current = false" in seek, (
"a seek after an unlanded resume takes the resume branch and keeps the "
"buffer it was supposed to discard")
|