Merge branch 'master' into worktree-mosaic-library
# Conflicts: # docs/traceability.md
This commit is contained in:
@@ -328,7 +328,7 @@ Internal architecture, components, and application logic.
|
|||||||
| DR-168 | Pause and resume actually stop and restart the bytes. `pause_download` wrote `status = 'paused'` and did nothing else, and no cancellation existed anywhere in the download stack — no token, no flag, no abort — so the streaming task ran on, kept writing, and overwrote the row with `completed`/`failed` when it finished: the row flicked to "paused" and undid itself. `resume_download` had the mirror defect, flipping the row to `pending` without calling `pump_download_queue`; the pump runs when something calls it rather than polling, so a resumed download sat untouched until an unrelated event happened to pump the queue. A per-download stop flag (`download::stop`) is the missing half — a module-level registry because the two sides never meet, the command holding Tauri state and the worker running detached in `async_runtime::spawn`. The worker reads it between chunks and on retry (so a pause is not swallowed by a 45-second backoff), flushes, and returns `Stopped`, which is deliberately **not** retryable and **not** recorded as a failure: the `.part` file is left intact because that is exactly what the resume's Range request continues from. Registering returns a *fresh* flag, or a resumed download would inherit the pause that stopped it and halt instantly. Cancel and `clear_stale_downloads` signal it too, so neither deletes a file still being written | Downloads | UR-055 | Done |
|
| DR-168 | Pause and resume actually stop and restart the bytes. `pause_download` wrote `status = 'paused'` and did nothing else, and no cancellation existed anywhere in the download stack — no token, no flag, no abort — so the streaming task ran on, kept writing, and overwrote the row with `completed`/`failed` when it finished: the row flicked to "paused" and undid itself. `resume_download` had the mirror defect, flipping the row to `pending` without calling `pump_download_queue`; the pump runs when something calls it rather than polling, so a resumed download sat untouched until an unrelated event happened to pump the queue. A per-download stop flag (`download::stop`) is the missing half — a module-level registry because the two sides never meet, the command holding Tauri state and the worker running detached in `async_runtime::spawn`. The worker reads it between chunks and on retry (so a pause is not swallowed by a 45-second backoff), flushes, and returns `Stopped`, which is deliberately **not** retryable and **not** recorded as a failure: the `.part` file is left intact because that is exactly what the resume's Range request continues from. Registering returns a *fresh* flag, or a resumed download would inherit the pause that stopped it and halt instantly. Cancel and `clear_stale_downloads` signal it too, so neither deletes a file still being written | Downloads | UR-055 | Done |
|
||||||
| DR-169 | Partial files are actually reaped. The worker named its sidecar with `Path::with_extension("part")`, which *replaces* the extension — `movie.mp4` became `movie.part` — while every cleanup path deleted `"{file_path}.part"`, i.e. `movie.mp4.part`. The two never matched, so the partial file of every cancelled or failed download stayed on disk indefinitely, invisible to the disk-usage totals because no `downloads` row pointed at it. `partial_path` appends instead, is the single definition both the writer and the cleaners use, and incidentally removes a collision the old form had, where `movie.mp4` and `movie.mkv` mapped to one `movie.part` | Downloads | UR-055 | Done |
|
| DR-169 | Partial files are actually reaped. The worker named its sidecar with `Path::with_extension("part")`, which *replaces* the extension — `movie.mp4` became `movie.part` — while every cleanup path deleted `"{file_path}.part"`, i.e. `movie.mp4.part`. The two never matched, so the partial file of every cancelled or failed download stayed on disk indefinitely, invisible to the disk-usage totals because no `downloads` row pointed at it. `partial_path` appends instead, is the single definition both the writer and the cleaners use, and incidentally removes a collision the old form had, where `movie.mp4` and `movie.mkv` mapped to one `movie.part` | Downloads | UR-055 | Done |
|
||||||
| DR-170 | Downloads at a chosen bitrate are no longer corrupted by their own retries. Only the `original` preset asks for `Static=true`; every other rung requests a **transcode**, which Jellyfin serves chunked, with no `Content-Length`, and cannot byte-seek — so it ignores `Range` and answers `200` with the whole stream from the beginning rather than `206` with the requested tail. The worker sent the Range header whenever a `.part` existed and appended the body unconditionally, so each retry and each resume concatenated a fresh copy of the entire transcode onto the bytes already on disk: the file grew past its real size and would not play, which is why "downloads for different bitrates" stayed broken after the `videoBitRate` casing fix (DR-adc460f3) corrected the *request*. `resume_offset` makes the response decide — append only on a `206`, otherwise truncate and take the stream from the top — and the total size is computed from that offset rather than from a partial length the server never agreed to | Downloads | UR-071 | Done |
|
| DR-170 | Downloads at a chosen bitrate are no longer corrupted by their own retries. Only the `original` preset asks for `Static=true`; every other rung requests a **transcode**, which Jellyfin serves chunked, with no `Content-Length`, and cannot byte-seek — so it ignores `Range` and answers `200` with the whole stream from the beginning rather than `206` with the requested tail. The worker sent the Range header whenever a `.part` existed and appended the body unconditionally, so each retry and each resume concatenated a fresh copy of the entire transcode onto the bytes already on disk: the file grew past its real size and would not play, which is why "downloads for different bitrates" stayed broken after the `videoBitRate` casing fix (DR-adc460f3) corrected the *request*. `resume_offset` makes the response decide — append only on a `206`, otherwise truncate and take the stream from the top — and the total size is computed from that offset rather than from a partial length the server never agreed to | Downloads | UR-071 | Done |
|
||||||
| DR-171 | A downloaded video keeps audio the device can actually decode. `original` quality asked for `Static=true`, which hands back the source file byte-for-byte — E-AC-3/AC-3/DTS/TrueHD track included — and video is rendered on both platforms by the webview `<video>` element, which decodes none of them. Streaming already knew this: DR-149 judges the track the server would serve against `WEBVIEW_AUDIO_CODECS` and forces a transcode over Jellyfin's own direct-play offer, because 10.11.5 honours a `DirectPlayProfile`'s container and video codec but ignores its audio codec. The download path never consulted that policy, so the *same film* had sound when streamed and played as picture in silence once downloaded — and offline a download is the only source a video has, so there was no working path left to fall back to. The rule is now one rule: `served_audio_codec` picks the track the server will serve (the default, or the first when none is marked) and both callers judge it, the streaming verdict staying a bool and the download path needing the codec itself so it can say what to re-encode. Only the audio is re-encoded — `allowVideoStreamCopy=true` keeps an h264 source's picture byte-for-byte and no bitrate or resolution cap is added, so `original` still means original quality; a source the webview could not have rendered anyway (HEVC) becomes h264 as a side effect, which is the only form of it that would have played. The decision is per item rather than blanket because the transcode costs the byte-range resumability `Static=true` gives the download worker (see DR-170 for what a chunked, length-less response does to a resume), so a file whose audio already plays keeps the direct copy. An unknown codec — item not fetchable, or the server named none — changes nothing: the policy only ever *adds* a transcode, so it cannot make a working download worse. `resolve_video_download_url` is the single entrance for all three resolution sites (the frontend's per-item command, the bulk series/season enqueue, and the offline-queued resume), since the pure builder cannot look a codec up and a caller that forgets to is exactly how the silent downloads shipped. **Files already downloaded stay silent** — the bytes on disk are the wrong bytes and only a re-download replaces them | Downloads | UR-071, UR-004 | Done |
|
| DR-171 | A downloaded video keeps audio the device can actually decode. `original` quality asked for `Static=true`, which hands back the source file byte-for-byte — E-AC-3/AC-3/DTS/TrueHD track included — and video is rendered on both platforms by the webview `<video>` element, which decodes none of them. Streaming already knew this: DR-149 judges the track the server would serve against `WEBVIEW_AUDIO_CODECS` and forces a transcode over Jellyfin's own direct-play offer, because 10.11.5 honours a `DirectPlayProfile`'s container and video codec but ignores its audio codec. The download path never consulted that policy, so the *same film* had sound when streamed and played as picture in silence once downloaded — and offline a download is the only source a video has, so there was no working path left to fall back to. The rule is now one rule: `served_audio_codec` picks the track the server will serve (the default, or the first when none is marked) and both callers judge it, the streaming verdict staying a bool and the download path needing the codec itself so it can say what to re-encode. Only the audio is re-encoded — `allowVideoStreamCopy=true` keeps an h264 source's picture byte-for-byte and no bitrate or resolution cap is added, so `original` still means original quality; a source the webview could not have rendered anyway (HEVC) becomes h264 as a side effect, which is the only form of it that would have played. The decision is per item rather than blanket because the transcode costs the byte-range resumability `Static=true` gives the download worker (see DR-170 for what a chunked, length-less response does to a resume), so a file whose audio already plays keeps the direct copy. An unknown codec — item not fetchable, or the server named none — changes nothing: the policy only ever *adds* a transcode, so it cannot make a working download worse. The codec set judged against is the **webview's**, not the platform's, even though DR-161 made ExoPlayer the Android default: `experimentalNativeVideo` is a user setting, a downloaded file outlives whatever it was set to when the file arrived, and the narrow list is the only one that holds on both sides of it — at the cost of a Dolby-licensed device re-encoding a track its ExoPlayer could have played. `resolve_video_download_url` is the single entrance for all three resolution sites (the frontend's per-item command, the bulk series/season enqueue, and the offline-queued resume), since the pure builder cannot look a codec up and a caller that forgets to is exactly how the silent downloads shipped. **Files already downloaded stay silent** — the bytes on disk are the wrong bytes and only a re-download replaces them | Downloads | UR-071, UR-004 | Done |
|
||||||
| DR-162 | Video streams are opened against a **bandwidth ceiling the user chose**, instead of a fixed allowance nobody could change. Every video URL carried `MaxStreamingBitrate=20000000`/`VideoBitrate=18000000`, `PlaybackInfo` negotiated at 20 Mbps, and the device profile advertised `999999999` — so on a metered or slow connection the only lever was not watching. `StreamingQuality` is a ladder of ceilings (Original, 20/10/8/4/2/1 Mbps, 720 kbps) in which a step is not a label but a bundle of transcode parameters: the total ceiling, the audio share of it, and the resolution that budget can carry. It lives in Rust because those numbers are Jellyfin encoding vocabulary — the frontend names a variant and reads labels back over `player_get_streaming_qualities`, the same arrangement as the EQ preset curves. The video bitrate is the total *minus* the audio share, so the two together honour the cap rather than overshooting it by the size of the audio track, and `MaxHeight` falls with the ladder so a small budget is not spent on pixels it cannot afford. The cap has to reach the **negotiation**, not only the transcode URL: `max_static_bitrate` in the device profile is what makes the server refuse to direct-play a source fatter than the ceiling, and without it a 30 Mbps remux is handed over untouched and every URL parameter downstream is moot — which is why it is applied at all four places that decide bandwidth (the HLS builder, `PlaybackInfo`, `open_live_stream`, and the background-audio handoff, which takes the lower of the cap and its own 384 kbps). The ceiling is process-wide rather than a field on `OnlineRepository`, mirroring `INCLUDE_CATALOG_BROWSE`: it is a preference about *this device's connection*, it must survive a repository rebuilt on re-login, and every builder plus the negotiation have to agree on it or the cap leaks. Settings owns the durable default and is the only writer to `app_settings` — persisted unlike the rest of `VideoSettings`, because a limit set for a metered connection that silently reverts to uncapped on the next launch spends the user's data with no changed setting to show for it — and it is restored at startup from the async runtime, defaulting to uncapped if the read fails so a database problem degrades to the old behaviour rather than to an arbitrary limit. The in-player menu is the per-video override: a cap is a property of the stream the server is producing, so it cannot be applied to one already in flight — `player_set_stream_quality` re-opens the stream at the new quality and resumes at the current position, reloading a native backend itself and handing HTML5 a URL for the same `reloadSource` primitive the audio-track switch uses, so no strategy branch lives in the UI. It deliberately does not persist. This gives UR-070 its resume-at-the-same-point mechanism; the server-offered per-item rendition list that requirement also asks for remains proposed | Playback | UR-074, UR-070 | Done |
|
| DR-162 | Video streams are opened against a **bandwidth ceiling the user chose**, instead of a fixed allowance nobody could change. Every video URL carried `MaxStreamingBitrate=20000000`/`VideoBitrate=18000000`, `PlaybackInfo` negotiated at 20 Mbps, and the device profile advertised `999999999` — so on a metered or slow connection the only lever was not watching. `StreamingQuality` is a ladder of ceilings (Original, 20/10/8/4/2/1 Mbps, 720 kbps) in which a step is not a label but a bundle of transcode parameters: the total ceiling, the audio share of it, and the resolution that budget can carry. It lives in Rust because those numbers are Jellyfin encoding vocabulary — the frontend names a variant and reads labels back over `player_get_streaming_qualities`, the same arrangement as the EQ preset curves. The video bitrate is the total *minus* the audio share, so the two together honour the cap rather than overshooting it by the size of the audio track, and `MaxHeight` falls with the ladder so a small budget is not spent on pixels it cannot afford. The cap has to reach the **negotiation**, not only the transcode URL: `max_static_bitrate` in the device profile is what makes the server refuse to direct-play a source fatter than the ceiling, and without it a 30 Mbps remux is handed over untouched and every URL parameter downstream is moot — which is why it is applied at all four places that decide bandwidth (the HLS builder, `PlaybackInfo`, `open_live_stream`, and the background-audio handoff, which takes the lower of the cap and its own 384 kbps). The ceiling is process-wide rather than a field on `OnlineRepository`, mirroring `INCLUDE_CATALOG_BROWSE`: it is a preference about *this device's connection*, it must survive a repository rebuilt on re-login, and every builder plus the negotiation have to agree on it or the cap leaks. Settings owns the durable default and is the only writer to `app_settings` — persisted unlike the rest of `VideoSettings`, because a limit set for a metered connection that silently reverts to uncapped on the next launch spends the user's data with no changed setting to show for it — and it is restored at startup from the async runtime, defaulting to uncapped if the read fails so a database problem degrades to the old behaviour rather than to an arbitrary limit. The in-player menu is the per-video override: a cap is a property of the stream the server is producing, so it cannot be applied to one already in flight — `player_set_stream_quality` re-opens the stream at the new quality and resumes at the current position, reloading a native backend itself and handing HTML5 a URL for the same `reloadSource` primitive the audio-track switch uses, so no strategy branch lives in the UI. It deliberately does not persist. This gives UR-070 its resume-at-the-same-point mechanism; the server-offered per-item rendition list that requirement also asks for remains proposed | Playback | UR-074, UR-070 | Done |
|
||||||
| DR-172 | Tiles of mixed shapes are laid out **justified** rather than gridded. A CSS grid gives every cell one box, so on a page holding square music covers, 16:9 library backdrops and 2:3 posters at once, everything that is not the chosen shape is cropped to it — the home shortcut strip was explicitly forcing `aspect="video"` on music libraries for exactly this reason, which lined the row up by cutting the covers down. `layoutMosaic` packs tiles into rows of a **shared height** and gives each its own width from its own aspect ratio: it adds tiles to a row until the height needed to fill the container has fallen to the target, closes the row there (so rows land at or below the target, never above), and justifies the row to the container width by absorbing the rounding remainder into its widest tile, where a pixel is least visible. The last row is deliberately *not* justified — with one tile left over, filling the width would inflate it to a banner — so it sits at the target height, left-aligned. Ratios are clamped to a band, which costs a crop on genuine outliers and stops one panorama owning a row or one very tall image shrinking to a sliver. It is a pure module with no DOM: the component supplies only the two things the DOM knows — the measured container width, and the artwork's *decoded* aspect ratio, reported by `CachedImage` so the layout uses the shape an image actually has rather than the one its item type implies. Those measurements are committed in one debounced batch rather than per image, because artwork arrives over several hundred milliseconds and re-packing on each arrival would shuffle the grid under the pointer repeatedly. Labels are drawn *over* the bottom of each tile rather than beneath it: a caption below sits outside the computed box, and one that wraps to two lines would break the row alignment the layout exists to provide | UI | UR-075 | Done |
|
| DR-172 | Tiles of mixed shapes are laid out **justified** rather than gridded. A CSS grid gives every cell one box, so on a page holding square music covers, 16:9 library backdrops and 2:3 posters at once, everything that is not the chosen shape is cropped to it — the home shortcut strip was explicitly forcing `aspect="video"` on music libraries for exactly this reason, which lined the row up by cutting the covers down. `layoutMosaic` packs tiles into rows of a **shared height** and gives each its own width from its own aspect ratio: it adds tiles to a row until the height needed to fill the container has fallen to the target, closes the row there (so rows land at or below the target, never above), and justifies the row to the container width by absorbing the rounding remainder into its widest tile, where a pixel is least visible. The last row is deliberately *not* justified — with one tile left over, filling the width would inflate it to a banner — so it sits at the target height, left-aligned. Ratios are clamped to a band, which costs a crop on genuine outliers and stops one panorama owning a row or one very tall image shrinking to a sliver. It is a pure module with no DOM: the component supplies only the two things the DOM knows — the measured container width, and the artwork's *decoded* aspect ratio, reported by `CachedImage` so the layout uses the shape an image actually has rather than the one its item type implies. Those measurements are committed in one debounced batch rather than per image, because artwork arrives over several hundred milliseconds and re-packing on each arrival would shuffle the grid under the pointer repeatedly. Labels are drawn *over* the bottom of each tile rather than beneath it: a caption below sits outside the computed box, and one that wraps to two lines would break the row alignment the layout exists to provide | UI | UR-075 | Done |
|
||||||
| DR-173 | A library knows which favourites category it belongs to, and the frontend does not work it out. The mosaic offers a favourites tile per category beside its library, which needs a collection-type → category answer; deriving it in Svelte would have re-created the exact leak `SearchScope::item_types` was extracted to close (docs/specs/scoped-search-boundary.md) — one table of Jellyfin vocabulary, differing only in which vocabulary. `SearchScope::for_collection_type` maps `movies`/`tvshows`/`music` and returns `None` for everything else, so a Live TV or books library gets no tile at all rather than one opening an unfiltered list; `All` is never derived from a library, being the cross-library entry offered beside them rather than a property of one. `Library::new` stamps the result onto every library at construction — a constructor rather than a struct literal precisely so a derived field cannot be forgotten at one of the four sites — and it rides to the frontend as an optional `favoritesScope`, absent rather than null when there is none. The UI's remaining share is presentation only: what to call the tile, where to put it, and showing a category's tile **once** however many libraries share it, since two movie libraries have one favourites list between them | UI | UR-075, UR-067 | Done |
|
| DR-173 | A library knows which favourites category it belongs to, and the frontend does not work it out. The mosaic offers a favourites tile per category beside its library, which needs a collection-type → category answer; deriving it in Svelte would have re-created the exact leak `SearchScope::item_types` was extracted to close (docs/specs/scoped-search-boundary.md) — one table of Jellyfin vocabulary, differing only in which vocabulary. `SearchScope::for_collection_type` maps `movies`/`tvshows`/`music` and returns `None` for everything else, so a Live TV or books library gets no tile at all rather than one opening an unfiltered list; `All` is never derived from a library, being the cross-library entry offered beside them rather than a property of one. `Library::new` stamps the result onto every library at construction — a constructor rather than a struct literal precisely so a derived field cannot be forgotten at one of the four sites — and it rides to the frontend as an optional `favoritesScope`, absent rather than null when there is none. The UI's remaining share is presentation only: what to call the tile, where to put it, and showing a category's tile **once** however many libraries share it, since two movie libraries have one favourites list between them | UI | UR-075, UR-067 | Done |
|
||||||
|
|||||||
+202
-202
@@ -1,6 +1,6 @@
|
|||||||
# Code Traceability Matrix
|
# Code Traceability Matrix
|
||||||
|
|
||||||
**Generated:** 8/16/2026, 12:02:42 AM
|
**Generated:** 8/16/2026, 12:05:50 AM
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
@@ -163,15 +163,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
||||||
- **Line:** 2981
|
- **Line:** 2981
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L360)
|
|
||||||
- **Line:** 360
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L701)
|
|
||||||
- **Line:** 701
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2002)
|
|
||||||
- **Line:** 2002
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
||||||
- **Line:** 159
|
- **Line:** 159
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -187,6 +178,15 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
||||||
- **Line:** 218
|
- **Line:** 218
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L362)
|
||||||
|
- **Line:** 362
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L703)
|
||||||
|
- **Line:** 703
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2004)
|
||||||
|
- **Line:** 2004
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/commands/player/mod.rs`](src-tauri/src/commands/player/mod.rs#L223)
|
- **File:** [`src-tauri/src/commands/player/mod.rs`](src-tauri/src/commands/player/mod.rs#L223)
|
||||||
- **Line:** 223
|
- **Line:** 223
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -396,8 +396,8 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2413)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2413)
|
||||||
- **Line:** 2413
|
- **Line:** 2413
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L799)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L801)
|
||||||
- **Line:** 799
|
- **Line:** 801
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/adapters/index.ts`](src/lib/player/adapters/index.ts#L20)
|
- **File:** [`src/lib/player/adapters/index.ts`](src/lib/player/adapters/index.ts#L20)
|
||||||
- **Line:** 20
|
- **Line:** 20
|
||||||
@@ -790,24 +790,24 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2413)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2413)
|
||||||
- **Line:** 2413
|
- **Line:** 2413
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L351)
|
|
||||||
- **Line:** 351
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1969)
|
|
||||||
- **Line:** 1969
|
|
||||||
- **Context:** `function toggleSubtitleMenu() {`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2002)
|
|
||||||
- **Line:** 2002
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
||||||
- **Line:** 18
|
- **Line:** 18
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
||||||
- **Line:** 20
|
- **Line:** 20
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L353)
|
||||||
|
- **Line:** 353
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1971)
|
||||||
|
- **Line:** 1971
|
||||||
|
- **Context:** `function toggleSubtitleMenu() {`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2004)
|
||||||
|
- **Line:** 2004
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
||||||
- **Line:** 19
|
- **Line:** 19
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -887,8 +887,8 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2628)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2628)
|
||||||
- **Line:** 2628
|
- **Line:** 2628
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L799)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L801)
|
||||||
- **Line:** 799
|
- **Line:** 801
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
||||||
- **Line:** 19
|
- **Line:** 19
|
||||||
@@ -1403,9 +1403,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L283)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L283)
|
||||||
- **Line:** 283
|
- **Line:** 283
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/backgroundAudioHandoff.test.ts`](src/lib/components/player/backgroundAudioHandoff.test.ts#L11)
|
- **File:** [`src/lib/components/player/backgroundAudioHandoff.test.ts`](src/lib/components/player/backgroundAudioHandoff.test.ts#L11)
|
||||||
- **Line:** 11
|
- **Line:** 11
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -1415,6 +1412,9 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/backgroundAudioHandoff.ts`](src/lib/components/player/backgroundAudioHandoff.ts#L69)
|
- **File:** [`src/lib/components/player/backgroundAudioHandoff.ts`](src/lib/components/player/backgroundAudioHandoff.ts#L69)
|
||||||
- **Line:** 69
|
- **Line:** 69
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/backgroundAudio.commands.test.ts`](src/lib/player/backgroundAudio.commands.test.ts#L7)
|
- **File:** [`src/lib/player/backgroundAudio.commands.test.ts`](src/lib/player/backgroundAudio.commands.test.ts#L7)
|
||||||
- **Line:** 7
|
- **Line:** 7
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -2113,12 +2113,12 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 2 file(s)
|
**Locations:** 2 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
||||||
- **Line:** 21
|
- **Line:** 21
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-093
|
### DR-093
|
||||||
|
|
||||||
@@ -2189,9 +2189,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 4 file(s)
|
**Locations:** 4 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
||||||
- **Line:** 5
|
- **Line:** 5
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -2201,17 +2198,20 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
||||||
- **Line:** 21
|
- **Line:** 21
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-099
|
### DR-099
|
||||||
|
|
||||||
**Locations:** 2 file(s)
|
**Locations:** 2 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.touchScrub.test.ts`](src/lib/components/player/VideoPlayer.touchScrub.test.ts#L21)
|
- **File:** [`src/lib/components/player/VideoPlayer.touchScrub.test.ts`](src/lib/components/player/VideoPlayer.touchScrub.test.ts#L21)
|
||||||
- **Line:** 21
|
- **Line:** 21
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-100
|
### DR-100
|
||||||
|
|
||||||
@@ -3234,22 +3234,22 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 1 file(s)
|
**Locations:** 1 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L80)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L88)
|
||||||
- **Line:** 80
|
- **Line:** 88
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-149
|
### DR-149
|
||||||
|
|
||||||
**Locations:** 3 file(s)
|
**Locations:** 3 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L105)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L113)
|
||||||
- **Line:** 105
|
- **Line:** 113
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L127)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L135)
|
||||||
- **Line:** 127
|
- **Line:** 135
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
- **Line:** 144
|
- **Line:** 152
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-150
|
### DR-150
|
||||||
@@ -3402,8 +3402,8 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 1 file(s)
|
**Locations:** 1 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L103)
|
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L107)
|
||||||
- **Line:** 103
|
- **Line:** 107
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-162
|
### DR-162
|
||||||
@@ -3425,17 +3425,17 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L3091)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L3091)
|
||||||
- **Line:** 3091
|
- **Line:** 3091
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L249)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L251)
|
||||||
- **Line:** 249
|
- **Line:** 251
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L656)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L658)
|
||||||
- **Line:** 656
|
- **Line:** 658
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1932)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1934)
|
||||||
- **Line:** 1932
|
- **Line:** 1934
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2357)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2359)
|
||||||
- **Line:** 2357
|
- **Line:** 2359
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/index.ts`](src/lib/player/index.ts#L192)
|
- **File:** [`src/lib/player/index.ts`](src/lib/player/index.ts#L192)
|
||||||
- **Line:** 192
|
- **Line:** 192
|
||||||
@@ -3585,12 +3585,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 9 file(s)
|
**Locations:** 9 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
|
||||||
- **Line:** 144
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L212)
|
|
||||||
- **Line:** 212
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L210)
|
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L210)
|
||||||
- **Line:** 210
|
- **Line:** 210
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -3612,6 +3606,12 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
||||||
- **Line:** 2961
|
- **Line:** 2961
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
|
- **Line:** 152
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L220)
|
||||||
|
- **Line:** 220
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### DR-172
|
### DR-172
|
||||||
|
|
||||||
@@ -3741,15 +3741,15 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
||||||
- **Line:** 2981
|
- **Line:** 2981
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L701)
|
|
||||||
- **Line:** 701
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
||||||
- **Line:** 159
|
- **Line:** 159
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L183)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L183)
|
||||||
- **Line:** 183
|
- **Line:** 183
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L703)
|
||||||
|
- **Line:** 703
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/commands/player/mod.rs`](src-tauri/src/commands/player/mod.rs#L223)
|
- **File:** [`src-tauri/src/commands/player/mod.rs`](src-tauri/src/commands/player/mod.rs#L223)
|
||||||
- **Line:** 223
|
- **Line:** 223
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -4287,24 +4287,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/player/mod.rs`](src-tauri/src/player/mod.rs#L1535)
|
- **File:** [`src-tauri/src/player/mod.rs`](src-tauri/src/player/mod.rs#L1535)
|
||||||
- **Line:** 1535
|
- **Line:** 1535
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L29)
|
|
||||||
- **Line:** 29
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L40)
|
|
||||||
- **Line:** 40
|
|
||||||
- **Context:** `pub fn clamp_max_audio_channels(reported: Option<u32>) -> u32 {`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L80)
|
|
||||||
- **Line:** 80
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L105)
|
|
||||||
- **Line:** 105
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L127)
|
|
||||||
- **Line:** 127
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
|
||||||
- **Line:** 144
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L424)
|
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L424)
|
||||||
- **Line:** 424
|
- **Line:** 424
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -4314,6 +4296,24 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2903)
|
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2903)
|
||||||
- **Line:** 2903
|
- **Line:** 2903
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L29)
|
||||||
|
- **Line:** 29
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L40)
|
||||||
|
- **Line:** 40
|
||||||
|
- **Context:** `pub fn clamp_max_audio_channels(reported: Option<u32>) -> u32 {`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L88)
|
||||||
|
- **Line:** 88
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L113)
|
||||||
|
- **Line:** 113
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L135)
|
||||||
|
- **Line:** 135
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
|
- **Line:** 152
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UR-013
|
### UR-013
|
||||||
|
|
||||||
@@ -4444,9 +4444,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L1518)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L1518)
|
||||||
- **Line:** 1518
|
- **Line:** 1518
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/backgroundAudioHandoff.test.ts`](src/lib/components/player/backgroundAudioHandoff.test.ts#L11)
|
- **File:** [`src/lib/components/player/backgroundAudioHandoff.test.ts`](src/lib/components/player/backgroundAudioHandoff.test.ts#L11)
|
||||||
- **Line:** 11
|
- **Line:** 11
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -4456,6 +4453,9 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/backgroundAudioHandoff.ts`](src/lib/components/player/backgroundAudioHandoff.ts#L69)
|
- **File:** [`src/lib/components/player/backgroundAudioHandoff.ts`](src/lib/components/player/backgroundAudioHandoff.ts#L69)
|
||||||
- **Line:** 69
|
- **Line:** 69
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/backgroundAudio.commands.test.ts`](src/lib/player/backgroundAudio.commands.test.ts#L7)
|
- **File:** [`src/lib/player/backgroundAudio.commands.test.ts`](src/lib/player/backgroundAudio.commands.test.ts#L7)
|
||||||
- **Line:** 7
|
- **Line:** 7
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -4936,12 +4936,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/MiniPlayer.svelte`](src/lib/components/player/MiniPlayer.svelte#L1)
|
- **File:** [`src/lib/components/player/MiniPlayer.svelte`](src/lib/components/player/MiniPlayer.svelte#L1)
|
||||||
- **Line:** 1
|
- **Line:** 1
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L799)
|
|
||||||
- **Line:** 799
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
||||||
- **Line:** 5
|
- **Line:** 5
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -4963,6 +4957,12 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/videoFit.ts`](src/lib/components/player/videoFit.ts#L7)
|
- **File:** [`src/lib/components/player/videoFit.ts`](src/lib/components/player/videoFit.ts#L7)
|
||||||
- **Line:** 7
|
- **Line:** 7
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L801)
|
||||||
|
- **Line:** 801
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
||||||
- **Line:** 19
|
- **Line:** 19
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -5219,24 +5219,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L2981)
|
||||||
- **Line:** 2981
|
- **Line:** 2981
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L351)
|
|
||||||
- **Line:** 351
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L360)
|
|
||||||
- **Line:** 360
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L701)
|
|
||||||
- **Line:** 701
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1969)
|
|
||||||
- **Line:** 1969
|
|
||||||
- **Context:** `function toggleSubtitleMenu() {`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2002)
|
|
||||||
- **Line:** 2002
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
||||||
- **Line:** 18
|
- **Line:** 18
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -5255,6 +5237,24 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
||||||
- **Line:** 218
|
- **Line:** 218
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L353)
|
||||||
|
- **Line:** 353
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L362)
|
||||||
|
- **Line:** 362
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L703)
|
||||||
|
- **Line:** 703
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1971)
|
||||||
|
- **Line:** 1971
|
||||||
|
- **Context:** `function toggleSubtitleMenu() {`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2004)
|
||||||
|
- **Line:** 2004
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
- **File:** [`src/lib/player/adapters/html5Adapter.ts`](src/lib/player/adapters/html5Adapter.ts#L19)
|
||||||
- **Line:** 19
|
- **Line:** 19
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -6363,12 +6363,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/media_server.rs`](src-tauri/src/media_server.rs#L567)
|
- **File:** [`src-tauri/src/media_server.rs`](src-tauri/src/media_server.rs#L567)
|
||||||
- **Line:** 567
|
- **Line:** 567
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
|
||||||
- **Line:** 144
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L212)
|
|
||||||
- **Line:** 212
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L210)
|
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L210)
|
||||||
- **Line:** 210
|
- **Line:** 210
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -6393,6 +6387,12 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
||||||
- **Line:** 2961
|
- **Line:** 2961
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
|
- **Line:** 152
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L220)
|
||||||
|
- **Line:** 220
|
||||||
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/storage/schema.rs`](src-tauri/src/storage/schema.rs#L813)
|
- **File:** [`src-tauri/src/storage/schema.rs`](src-tauri/src/storage/schema.rs#L813)
|
||||||
- **Line:** 813
|
- **Line:** 813
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -6416,17 +6416,17 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L3091)
|
- **File:** [`src/lib/api/bindings.ts`](src/lib/api/bindings.ts#L3091)
|
||||||
- **Line:** 3091
|
- **Line:** 3091
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L249)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L251)
|
||||||
- **Line:** 249
|
- **Line:** 251
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L656)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L658)
|
||||||
- **Line:** 656
|
- **Line:** 658
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1932)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1934)
|
||||||
- **Line:** 1932
|
- **Line:** 1934
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2357)
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2359)
|
||||||
- **Line:** 2357
|
- **Line:** 2359
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/player/index.ts`](src/lib/player/index.ts#L192)
|
- **File:** [`src/lib/player/index.ts`](src/lib/player/index.ts#L192)
|
||||||
- **Line:** 192
|
- **Line:** 192
|
||||||
@@ -7040,8 +7040,8 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L4)
|
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L4)
|
||||||
- **Line:** 4
|
- **Line:** 4
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L103)
|
- **File:** [`src/lib/utils/pictureInPicture.ts`](src/lib/utils/pictureInPicture.ts#L107)
|
||||||
- **Line:** 103
|
- **Line:** 107
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UR-042
|
### UR-042
|
||||||
@@ -7338,6 +7338,14 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 1 file(s)
|
**Locations:** 1 file(s)
|
||||||
|
|
||||||
|
- **File:** [`src/lib/services/offlineCatalog.reload.test.ts`](src/lib/services/offlineCatalog.reload.test.ts#L11)
|
||||||
|
- **Line:** 11
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
|
### UT-138
|
||||||
|
|
||||||
|
**Locations:** 1 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/services/offlineCatalog.reload.test.ts`](src/lib/services/offlineCatalog.reload.test.ts#L11)
|
- **File:** [`src/lib/services/offlineCatalog.reload.test.ts`](src/lib/services/offlineCatalog.reload.test.ts#L11)
|
||||||
- **Line:** 11
|
- **Line:** 11
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -7362,15 +7370,29 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 3 file(s)
|
**Locations:** 3 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L351)
|
|
||||||
- **Line:** 351
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
||||||
- **Line:** 18
|
- **Line:** 18
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
||||||
- **Line:** 20
|
- **Line:** 20
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L353)
|
||||||
|
- **Line:** 353
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
|
### UT-144
|
||||||
|
|
||||||
|
**Locations:** 3 file(s)
|
||||||
|
|
||||||
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
||||||
|
- **Line:** 18
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
||||||
|
- **Line:** 20
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L353)
|
||||||
|
- **Line:** 353
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UT-146
|
### UT-146
|
||||||
|
|
||||||
@@ -7390,15 +7412,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 8 file(s)
|
**Locations:** 8 file(s)
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L360)
|
|
||||||
- **Line:** 360
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L701)
|
|
||||||
- **Line:** 701
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2002)
|
|
||||||
- **Line:** 2002
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L159)
|
||||||
- **Line:** 159
|
- **Line:** 159
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -7414,6 +7427,26 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L218)
|
||||||
- **Line:** 218
|
- **Line:** 218
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L362)
|
||||||
|
- **Line:** 362
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L703)
|
||||||
|
- **Line:** 703
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L2004)
|
||||||
|
- **Line:** 2004
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
|
### UT-149
|
||||||
|
|
||||||
|
**Locations:** 2 file(s)
|
||||||
|
|
||||||
|
- **File:** [`src/lib/player/adapters/adapterSelection.test.ts`](src/lib/player/adapters/adapterSelection.test.ts#L4)
|
||||||
|
- **Line:** 4
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/player/adapters/index.ts`](src/lib/player/adapters/index.ts#L20)
|
||||||
|
- **Line:** 20
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UT-151
|
### UT-151
|
||||||
|
|
||||||
@@ -8236,8 +8269,8 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 1 file(s)
|
**Locations:** 1 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L80)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L88)
|
||||||
- **Line:** 80
|
- **Line:** 88
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UT-145
|
### UT-145
|
||||||
@@ -8430,14 +8463,14 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 3 file(s)
|
**Locations:** 3 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L105)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L113)
|
||||||
- **Line:** 105
|
- **Line:** 113
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L127)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L135)
|
||||||
- **Line:** 127
|
- **Line:** 135
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
- **Line:** 144
|
- **Line:** 152
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UT-150
|
### UT-150
|
||||||
@@ -8590,12 +8623,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
|
|
||||||
**Locations:** 7 file(s)
|
**Locations:** 7 file(s)
|
||||||
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L144)
|
|
||||||
- **Line:** 144
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L212)
|
|
||||||
- **Line:** 212
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L345)
|
- **File:** [`src-tauri/src/repository/mod.rs`](src-tauri/src/repository/mod.rs#L345)
|
||||||
- **Line:** 345
|
- **Line:** 345
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
@@ -8611,6 +8638,12 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
- **File:** [`src-tauri/src/repository/online.rs`](src-tauri/src/repository/online.rs#L2961)
|
||||||
- **Line:** 2961
|
- **Line:** 2961
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L152)
|
||||||
|
- **Line:** 152
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src-tauri/src/repository/device_profile.rs`](src-tauri/src/repository/device_profile.rs#L220)
|
||||||
|
- **Line:** 220
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UT-167
|
### UT-167
|
||||||
|
|
||||||
@@ -8736,56 +8769,6 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **Line:** 1
|
- **Line:** 1
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
### UR-061
|
|
||||||
|
|
||||||
**Locations:** 4 file(s)
|
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
|
||||||
- **Line:** 1
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
|
||||||
- **Line:** 5
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.touchScrub.test.ts`](src/lib/components/player/VideoPlayer.touchScrub.test.ts#L21)
|
|
||||||
- **Line:** 21
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
|
||||||
- **Line:** 21
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
|
|
||||||
### UT-138
|
|
||||||
|
|
||||||
**Locations:** 1 file(s)
|
|
||||||
|
|
||||||
- **File:** [`src/lib/services/offlineCatalog.reload.test.ts`](src/lib/services/offlineCatalog.reload.test.ts#L11)
|
|
||||||
- **Line:** 11
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
|
|
||||||
### UT-144
|
|
||||||
|
|
||||||
**Locations:** 3 file(s)
|
|
||||||
|
|
||||||
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L351)
|
|
||||||
- **Line:** 351
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.test.ts`](src/lib/components/player/subtitleTracks.test.ts#L18)
|
|
||||||
- **Line:** 18
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/components/player/subtitleTracks.ts`](src/lib/components/player/subtitleTracks.ts#L20)
|
|
||||||
- **Line:** 20
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
|
|
||||||
### UT-149
|
|
||||||
|
|
||||||
**Locations:** 2 file(s)
|
|
||||||
|
|
||||||
- **File:** [`src/lib/player/adapters/adapterSelection.test.ts`](src/lib/player/adapters/adapterSelection.test.ts#L4)
|
|
||||||
- **Line:** 4
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
- **File:** [`src/lib/player/adapters/index.ts`](src/lib/player/adapters/index.ts#L20)
|
|
||||||
- **Line:** 20
|
|
||||||
- **Context:** `Unknown`
|
|
||||||
|
|
||||||
### UR-043
|
### UR-043
|
||||||
|
|
||||||
**Locations:** 2 file(s)
|
**Locations:** 2 file(s)
|
||||||
@@ -8820,4 +8803,21 @@ JA-001, JA-002, JA-003, JA-004, JA-005, JA-007, JA-008, JA-010, JA-011, JA-012,
|
|||||||
- **Line:** 3
|
- **Line:** 3
|
||||||
- **Context:** `Unknown`
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
|
### UR-061
|
||||||
|
|
||||||
|
**Locations:** 4 file(s)
|
||||||
|
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.tapSurface.test.ts`](src/lib/components/player/VideoPlayer.tapSurface.test.ts#L5)
|
||||||
|
- **Line:** 5
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.touchScrub.test.ts`](src/lib/components/player/VideoPlayer.touchScrub.test.ts#L21)
|
||||||
|
- **Line:** 21
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/tapGestures.ts`](src/lib/components/player/tapGestures.ts#L21)
|
||||||
|
- **Line:** 21
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
- **File:** [`src/lib/components/player/VideoPlayer.svelte`](src/lib/components/player/VideoPlayer.svelte#L1)
|
||||||
|
- **Line:** 1
|
||||||
|
- **Context:** `Unknown`
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,10 +65,18 @@ const FALLBACK_AUDIO_CODEC: &str = "aac";
|
|||||||
/// play the **video** can decode.
|
/// play the **video** can decode.
|
||||||
///
|
///
|
||||||
/// The platform list comes from `MediaCodecList`, which describes ExoPlayer —
|
/// The platform list comes from `MediaCodecList`, which describes ExoPlayer —
|
||||||
/// but video does not play through ExoPlayer. Both Android and Linux render it
|
/// but the webview `<video>` element may be what renders the video, and
|
||||||
/// in a webview `<video>` element, and Chromium/WebKit decode a much smaller set
|
/// Chromium/WebKit decode a much smaller set than the platform does. Advertising
|
||||||
/// than the platform does. Advertising the raw list makes Jellyfin direct-play a
|
/// the raw list makes Jellyfin direct-play a track the webview cannot decode, and
|
||||||
/// track the webview cannot decode, and the user gets picture with no sound.
|
/// the user gets picture with no sound.
|
||||||
|
///
|
||||||
|
/// Which renderer gets it is not fixed: Linux is always the element, and Android
|
||||||
|
/// follows `experimentalNativeVideo`, which took ExoPlayer as its default in
|
||||||
|
/// DR-161 but is a user setting either way. So the *narrow* list is the only one
|
||||||
|
/// that holds on both sides of that switch. The cost is a Dolby-licensed Android
|
||||||
|
/// device transcoding an E-AC-3 track its ExoPlayer could have direct-played;
|
||||||
|
/// the alternative is silence for everyone the switch lands the other way, which
|
||||||
|
/// is the bug this exists to prevent.
|
||||||
///
|
///
|
||||||
/// The gap is widest on devices whose vendor licenses Dolby: a phone with
|
/// The gap is widest on devices whose vendor licenses Dolby: a phone with
|
||||||
/// `c2.dolby.eac3.decoder` reports `eac3`, so it — and only it — gets a silent
|
/// `c2.dolby.eac3.decoder` reports `eac3`, so it — and only it — gets a silent
|
||||||
|
|||||||
@@ -120,10 +120,12 @@
|
|||||||
* Keep native's picture-in-picture state in step with the `<video>` element.
|
* Keep native's picture-in-picture state in step with the `<video>` element.
|
||||||
*
|
*
|
||||||
* PiP is driven by the Activity, and it only ever knew about the native
|
* PiP is driven by the Activity, and it only ever knew about the native
|
||||||
* ExoPlayer surface — a path behind `experimentalNativeVideo`, which defaults
|
* ExoPlayer surface — a path behind `experimentalNativeVideo`, which at the
|
||||||
* to off. So in the shipping configuration nothing satisfied its "is a video
|
* time defaulted to off. So in the then-shipping configuration nothing
|
||||||
* playing?" check and the PiP button did nothing at all. Reporting the element
|
* satisfied its "is a video playing?" check and the PiP button did nothing at
|
||||||
* gives it a surface it can shrink into. (UR-041, DR-160)
|
* all. Reporting the element gives it a surface it can shrink into, and still
|
||||||
|
* has to: the flag defaults to on now (DR-161) but a user who turns it off is
|
||||||
|
* back on the element. (UR-041, DR-160, DR-161)
|
||||||
*/
|
*/
|
||||||
function reportPipVideoState() {
|
function reportPipVideoState() {
|
||||||
if (!useHtml5Element || !videoElement) {
|
if (!useHtml5Element || !videoElement) {
|
||||||
|
|||||||
@@ -73,7 +73,11 @@ function createExperimentalNativeVideoStore() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** User opt-in for the native Android video path. Default off. */
|
/**
|
||||||
|
* User opt-out for the native Android video path. **Defaults to on** since
|
||||||
|
* DR-161 — see `load()`. The name still says "experimental" because the flag
|
||||||
|
* remains a suppressor of Rust's backend choice, not a promoter of it.
|
||||||
|
*/
|
||||||
export const experimentalNativeVideo = createExperimentalNativeVideoStore();
|
export const experimentalNativeVideo = createExperimentalNativeVideoStore();
|
||||||
|
|
||||||
function createNativeVideoActiveStore() {
|
function createNativeVideoActiveStore() {
|
||||||
|
|||||||
@@ -89,14 +89,18 @@ export function setAutoEnterEnabled(enabled: boolean): void {
|
|||||||
/**
|
/**
|
||||||
* Tell native that a WebView `<video>` is (or is no longer) the playback surface.
|
* Tell native that a WebView `<video>` is (or is no longer) the playback surface.
|
||||||
*
|
*
|
||||||
* This is what makes PiP work at all in the shipping configuration. The native
|
* This is what makes PiP work on the HTML5 path. The native side only ever knew
|
||||||
* side only ever knew about the ExoPlayer surface, and that path is behind
|
* about the ExoPlayer surface, and that path is behind `experimentalNativeVideo`,
|
||||||
* `experimentalNativeVideo`, which defaults to off — so `canEnterPip` was always
|
* which defaulted to off when this was written — so `canEnterPip` was always
|
||||||
* false and pressing the button did nothing. Reporting the element's state gives
|
* false and pressing the button did nothing. Reporting the element's state gives
|
||||||
* native a surface it can legitimately shrink into, plus the intrinsic size it
|
* native a surface it can legitimately shrink into, plus the intrinsic size it
|
||||||
* needs for the PiP window's aspect ratio and the play state for its play/pause
|
* needs for the PiP window's aspect ratio and the play state for its play/pause
|
||||||
* action.
|
* action.
|
||||||
*
|
*
|
||||||
|
* The flag defaults to **on** now (DR-161), so Android normally shrinks the real
|
||||||
|
* ExoPlayer surface instead; this remains the path for Linux and for anyone who
|
||||||
|
* turned the flag off.
|
||||||
|
*
|
||||||
* Pass `active: false` when the element goes away, or PiP would be offered over a
|
* Pass `active: false` when the element goes away, or PiP would be offered over a
|
||||||
* video that is no longer there.
|
* video that is no longer there.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user