diff --git a/server/app.py b/server/app.py index 1bfaa14..5171364 100644 --- a/server/app.py +++ b/server/app.py @@ -285,12 +285,13 @@ def api_events(evt: dict = Body(...), request: Request = None): # client-reported events; the diagnostics the browser can uniquely see # (playback failures, capability probes) happen client-side, not in the # request log — so the phone reports them here - if evt.get("type") not in ("error", "client-fail", "play-probe"): + if evt.get("type") not in ("error", "client-fail", "play-probe", "hls-err"): raise HTTPException(422, "unknown event type") c = db.connect() db.event(c, request.state.user, evt["type"], {k: evt[k] for k in ("ep_id", "ep", "lang", "msg", "detail", - "jsv", "branch", "hls_lib", "mse", "native_hls", "ua") if k in evt}) + "jsv", "branch", "hls_lib", "mse", "native_hls", "ua", + "step", "fatal", "details", "buffer", "retry", "http") if k in evt}) c.commit() c.close() return {"ok": True} diff --git a/static/app.js b/static/app.js index b62befa..08a5dfd 100644 --- a/static/app.js +++ b/static/app.js @@ -1,5 +1,5 @@ // app.js — ani-web frontend: search -> detail -> play, vanilla JS + hls.js -const JSV = 10; // bump with every app.js change; play-probe reports it so a +const JSV = 12; // bump with every app.js change; play-probe reports it so a // stale-cache phone is detectable server-side // BASE = this page's directory, so the app works at / or behind a // prefixing reverse proxy (e.g. https://host/ani/) @@ -915,14 +915,22 @@ async function play(ep_id, ep_no) { timeoutRetry: { maxNumRetry: 6, retryDelayMs: 1000, maxRetryDelayMs: 20000, backoff: "linear" }, errorRetry: { maxNumRetry: 8, retryDelayMs: 1000, maxRetryDelayMs: 20000, backoff: "linear" }, } } }); + // iPhone debugging: log EVERY hls.js error (fatal and not) so the + // client-side timeline is visible server-side hls.on(Hls.Events.ERROR, (_, data) => { + try { postEvent({type: "hls-err", jsv: JSV, fatal: data.fatal, details: data.details, + buffer: data.buffer || null, retry: data.retry ?? null, + http: data.response ? data.response.code : null}); } catch {} if (data.fatal) { stopHls(); playerFail(data.details + (data.response ? ` (HTTP ${data.response.code})` : "")); } }); + try { postEvent({type: "play-probe", jsv: JSV, step: "new-hls-ok"}); } catch {} hls.loadSource("/stream/" + s.token); + try { postEvent({type: "play-probe", jsv: JSV, step: "loadsource-called"}); } catch {} hls.attachMedia(v); + try { postEvent({type: "play-probe", jsv: JSV, step: "attach-ok"}); } catch {} } currentEp = {ep_id, ep_no, v}; lastSavedPos = 0; diff --git a/static/index.html b/static/index.html index c994f18..b808329 100644 --- a/static/index.html +++ b/static/index.html @@ -6,7 +6,7 @@ ani-web - +
@@ -30,6 +30,6 @@ max-age=300 in browser AND possibly in your HTTPS proxy, and a stale copy is exactly how users keep seeing an old UI after a deploy --> - +