# Video Streaming v1

## Doel

Video Streaming v1 voegt een kleine, veilige manier toe om videobestanden direct vanuit de webui af te spelen in de browser, zonder eerst een volledige lokale kopie te maken. Dat past bij de bestaande dual-pane workflow: bestanden blijven centraal browsebaar, en video openen wordt een gerichte viewer-actie binnen dezelfde app.

De kern is browser-native streaming via HTTP, niet het bouwen van een mediaserver. De app blijft een file manager met een beperkte preview-/playbackfunctie.

## Scope

Video Streaming v1 ondersteunt:

- `mp4`
- `mkv`
- afspelen in een modal/popup video viewer
- browser-native:
  - play/pause
  - seek/scrub bar
  - volume
  - fullscreen

Niet in scope voor v1:

- transcoding
- codecconversie
- adaptive bitrate streaming
- playlists
- thumbnails / chapter support
- picture-in-picture specifieke UI-logica
- ingebedde subtitle-extractie uit containers

Ondertiteling in v1 is alleen kansrijk als losse subtitle-bestanden later eenvoudig gekoppeld kunnen worden; dat is niet de basis van deze eerste slice.

## Open-/Afspeelgedrag in de UI

Aanbevolen v1-gedrag:

- dubbelklik op videobestand = afspelen
- `Enter` op geselecteerd videobestand = afspelen
- gewone single click blijft selectie
- klik op directorynaam blijft directory openen

Dit sluit aan op standaard file-manager gedrag:

- selecteren en openen blijven gescheiden
- directory-open gedrag blijft intact
- video-open is alleen voor videobestanden

Rechtermuisknop/contextmenu blijft buiten scope. Dat zou extra event-complexiteit toevoegen zonder noodzaak voor een eerste bruikbare versie.

## Streamingmodel

De aanbevolen techniek is een read-only HTTP endpoint met `Range` request ondersteuning.

Waarom:

- browsers kunnen dan direct streamen en seeken
- grote bestanden hoeven niet volledig in memory of eerst volledig gedownload te worden
- dit past goed bij `<video src="...">`

Gewenst gedrag:

- browser vraagt een eerste byte-range op
- server serveert alleen de gevraagde byte-range
- bij seeken vraagt de browser een nieuw bereik op
- response gebruikt `206 Partial Content` waar nodig

Dit is beter dan volledige download vooraf omdat:

- startup sneller is
- geheugenverbruik laag blijft
- netwerkverkeer beperkt blijft tot wat de speler echt nodig heeft

## Backend-impact

Aanbevolen nieuw endpoint:

- `GET /api/files/video?path=...`

Aanvullend gedrag:

- alleen files
- alleen binnen bestaand `path_guard` / whitelist model
- directory => `type_conflict`
- niet gevonden => `path_not_found`
- traversal / buiten whitelist => bestaande securityfouten

Belangrijke backendvereisten:

- valideer pad via bestaand `path_guard`
- valideer dat het om een file gaat
- content-type bepalen op basis van extensie / bekende mapping
- `Range` request parsing ondersteunen
- response streamen vanaf filehandle, niet eerst volledig inlezen
- correcte headers:
  - `Accept-Ranges: bytes`
  - `Content-Range` bij partial content
  - `Content-Length`
  - passend `Content-Type`

Geheugenverbruik blijft laag door:

- file in chunks te lezen
- geen volledige buffering
- directe streamingresponse

## Frontend-impact

Aanbevolen richting:

- aparte video modal naast bestaande text `View` modal
- geen overbelasting van de huidige tekstviewer

Reden:

- tekst-view en video-view hebben ander gedrag
- regressierisico blijft lager als beide modaltypen gescheiden zijn

UI-richting:

- bestaand selectiemechanisme blijft
- open-actie detecteert videotype
- video opent in aparte modal met `<video controls>`

Dat laat de bestaande tekst-viewflow intact en voorkomt dat `View` v1 voor tekst regressies krijgt.

## MKV / Codec-realiteit

`mkv` als container betekent niet dat elke browser het bestand echt kan afspelen.

Belangrijke realiteit:

- browser support hangt af van codecs in de container
- bijvoorbeeld H.264/AAC in MP4 is meestal kansrijker
- MKV met niet-ondersteunde codecs kan ondanks correcte streaming nog steeds niet afspelen

Veilige v1-verwachting:

- server ondersteunt streaming van `mkv`
- browser probeert native playback
- als browser/codec-combinatie niet ondersteund wordt, toont de UI een nette melding dat afspelen in deze browser niet beschikbaar is

Dus:

- v1 belooft streaming
- v1 belooft geen universele codeccompatibiliteit

## Ondertiteling

Veilige v1-richting:

- geen ingebedde MKV subtitles
- eventueel later alleen losse subtitle-bestanden zoals `.vtt` of `.srt`

Waarom ingebedde subtitles buiten scope zijn:

- vereist parsing/extractie uit container
- verhoogt backendcomplexiteit duidelijk
- browsers ondersteunen losse tracks eenvoudiger dan container-interne subtitles

Conclusie:

- subtitles niet als kern van v1
- als later toegevoegd, begin met losse subtitle-bestanden

## Risico's

Belangrijkste risico's:

- correcte `Range` handling
- browser codec support
- grote files / seek-gedrag
- security op file access
- regressie op bestaande view/open-flow

Specifiek:

- foutieve range-implementatie breekt seeken
- te brede content-type toelating maakt gedrag onduidelijk
- combineren van tekst-view en video-view in één modal verhoogt regressierisico

## Teststrategie

Backend golden tests:

- video endpoint success voor ondersteund pad
- range request geeft partial content
- directory => `type_conflict`
- path not found
- traversal attempt
- invalid/non-video type indien endpoint daarop beperkt wordt

UI smoke/regressietests:

- video modal container aanwezig
- JS wiring voor dubbelklik / `Enter` op videobestand
- bestaande directory-open flow blijft bestaan
- bestaande tekst-viewflow blijft bestaan

Handmatige validatie:

- mp4 opent en speelt af
- seek werkt
- fullscreen werkt
- sluiten modal werkt
- mkv met browser-ondersteunde codec speelt
- mkv met niet-ondersteunde codec faalt netjes

## Aanbeveling

Aanbevolen v1-richting met laag regressierisico:

- nieuw backend endpoint `GET /api/files/video?path=...`
- read-only streaming met `Range` support
- aparte video modal in de frontend
- openen via:
  - dubbelklik op videobestand
  - `Enter` op geselecteerd videobestand
- `mp4` als primaire happy path
- `mkv` technisch toestaan, maar met expliciete verwachting dat browser/codec support kan verschillen
- geen subtitle-feature als kern van v1

Dit is de kleinste bruikbare stap die:

- goed past bij de huidige app
- bestaande security hergebruikt
- geen mediaserver-architectuur introduceert
- regressierisico op browse/view/edit laag houdt
