watchparty/server
Nicolas 137977893a
All checks were successful
Publier l'image Docker / test (push) Successful in 20s
Publier l'image Docker / publish (push) Successful in 14s
Render subtitles client-side (<track>) instead of asking Emby to burn them in
Six rounds of real-server debugging (see docs/architecture.md's player-
track-selection section) found three different, unrelated reasons a
server-side burn-in could fail - missing fonts, a bitmap format libass
fundamentally can't burn, ffmpeg failing outright on an otherwise
unremarkable file - none of which this app's own request ever caused or
could have fixed, all downstream of the one thing every attempt had in
common: asking Emby for a real-time video re-encode. Not needing that
re-encode at all closes the whole class of failure instead of chasing
each one.

- server/src/services/CatalogService.ts: new proxySubtitle asks Emby to
  convert the track to WebVTT (GET /Videos/{id}/{mediaSourceId}/
  Subtitles/{index}/Stream.vtt - a real Emby endpoint their own web
  client already uses for this) - entirely separate from the video
  transcode. applyPlaybackOverrides lost its SubtitleStreamIndex/
  SubtitleMethod=Encode branch - the video request no longer needs to
  know a subtitle was picked at all.
- server/src/types.ts, client/src/types.ts: PlaybackTrackOption's flag
  renamed supportsBurnIn -> isTextBased - same underlying fact (image vs
  text codec), but the name shouldn't keep describing a mechanism this
  app no longer uses.
- server/src/index.ts: new GET /api/catalog/subtitle/:itemId/:subtitleIndex
  route, grouped with the other cookie-authed media-element routes (a
  <track> can't send a bearer header either).
- client/src/api/embyApi.ts: new subtitleUrl(); streamUrl no longer
  carries SubtitleStreamIndex at all.
- client/src/views/player/Player.ts: the subtitle <select> no longer
  reloads the video (reloadWithCurrentOptions, still used for audio/
  quality, never touches subtitles now). New applySubtitleTrack()
  removes/re-adds a fresh <track> and sets video.textTracks[0].mode =
  'showing' synchronously right after appending - deliberately not
  waiting on the <track>'s own "load" event, confirmed against a real
  browser that it doesn't fire reliably at all (a known cross-browser
  quirk), which would have left a subtitle silently never shown - the
  exact symptom this whole saga started from. Re-applied on every video
  (re)load so an audio/quality change (which does still reload the
  video) doesn't drop whatever subtitle was showing.
- server/test/catalogService.test.ts: updated/new cases for
  proxySubtitle and the renamed isTextBased flag; removed the test for
  the now-deleted subtitle-forcing behavior.

Verified against the real compiled bundle: picking a text track adds one
<track> with the right URL and flips it to showing; "Aucun" removes it;
an image-coded track is listed but disabled; changing audio reloads the
video but the subtitle survives it, same element, still showing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 16:31:25 +02:00
..
src Render subtitles client-side (<track>) instead of asking Emby to burn them in 2026-09-14 16:31:25 +02:00
test Render subtitles client-side (<track>) instead of asking Emby to burn them in 2026-09-14 16:31:25 +02:00
.dockerignore Pivot to a standalone app - Emby plugin hit a hard wall 2026-09-13 20:48:55 +02:00
.env.example Pivot to a standalone app - Emby plugin hit a hard wall 2026-09-13 20:48:55 +02:00
Dockerfile Rewrite server + client in TypeScript, service-oriented server architecture 2026-09-14 09:38:14 +02:00
package-lock.json Rewrite server + client in TypeScript, service-oriented server architecture 2026-09-14 09:38:14 +02:00
package.json Log Emby's real status + response body on any proxied call failure 2026-09-14 15:03:17 +02:00
tsconfig.json Rewrite server + client in TypeScript, service-oriented server architecture 2026-09-14 09:38:14 +02:00
tsconfig.test.json Add a real server test suite and gate CI's Docker publish on it 2026-09-14 09:57:47 +02:00