• v0.4.6 1b70926c36

    JellyTau v0.4.6
    🏗️ Build and Test JellyTau / Run Tests (push) Successful in 20m34s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 6m6s
    Traceability Validation / Check Requirement Traces (push) Successful in 18s
    Build & Release / Run Tests (push) Successful in 20m26s
    🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 10m3s
    Build & Release / Build Linux (push) Successful in 37m59s
    Build & Release / Build Windows (push) Successful in 23m0s
    Build & Release / Build Android (push) Successful in 40m26s
    Build & Release / Create Release (push) Successful in 1m20s
    Stable

    dtourolle released this 2026-08-09 14:38:47 +00:00 | 174 commits to master since this release

    Features

    • Downloaded video plays offline. Four separate defects each stopped it on
      their own. A completed download's file_path is already absolute — the worker
      rewrites it on completion — but the player rooted it a second time and handed
      the webview /data/user/0/app//data/user/0/app/videos/x.mp4; audio was
      unaffected because it resolves the same column through Rust, which is why this
      read as a video-only fault (DR-133). The asset protocol was never enabled at
      all: convertFileSrc rewrites a path to asset.localhost unconditionally, but
      Tauri only answers that origin when the cargo feature and the config are both
      present, and neither was — which also silently defeated the cached-thumbnail
      path, whose soft fallback to the server copy hid the breakage whenever the
      server was reachable (DR-134). Tauri's asset protocol then answers a range-less
      request by reading the whole file into memory and only advertises
      Accept-Ranges from inside its range branch, so the first request never learns
      ranges exist and Chromium gave up after ~31s; local media now comes from a
      loopback HTTP server streaming bounded 4 MiB chunks, confined by a per-session
      token and to the app data directory, because loopback is shared between apps on
      Android (DR-137). And release builds set usesCleartextTraffic=false, so
      Android rejected the request before any I/O — a network-security config now
      exempts 127.0.0.1 only, and a remote server must still be HTTPS (DR-138).

      Known limitation: a download taken at original quality is a byte copy, so it
      can be any container — an AVI holding XVID is served correctly and refused by
      the webview regardless.

    🐛 Fixes

    • A video queued from a media card no longer downloads as audio.
      download_item never recorded media_type, and the reconnect resolver read
      that NULL as 'audio', so a movie's URL was resolved by the audio builder and
      completed as an audio-only transcode. The item's own type now decides, and rows
      already downloaded that way are requeued on reconnect — prevention alone leaves
      them reading "downloaded" and still unplayable. (DR-135, DR-136)

    • Some videos no longer play with no sound. Jellyfin's MediaStream.Index is
      global across every stream in a media source, so index 0 is the video stream on
      virtually all files — and AudioStreamIndex=0 was sent as "the first audio
      track" on the HLS transcode URL, the background-audio handoff URL, the
      direct-play fallback and the negotiation body, asking the server to use the
      video stream as audio. Servers that honour it produce a picture with no sound;
      only those that silently correct the index hid it, which is why it surfaced as
      "some videos have no audio". The parameter is now omitted unless a track was
      actually chosen. (DR-140)

    • A multichannel track is no longer direct-played to a two-channel sink.
      MediaCodecList answers "can this device decode 5.1", which is not the question
      that decides whether anything is audible: a phone decodes AC-3 5.1 happily and
      still has two channels to play it out of. The profile carried no
      MaxAudioChannels, so the server was free to hand over the multichannel track —
      silence, or dialogue folded into surround channels that go nowhere. The route's
      actual channel count now bounds the profile; no codec is ever removed, so a
      device with genuine surround output keeps direct-playing it. (DR-141)

    • Video waits for audio focus instead of rolling silently. Video manages focus
      by hand, and all three outcomes of the request were treated as success —
      including REQUEST_DELAYED, which means the system is withholding our audio
      until it calls back. The picture rolled with no sound, indistinguishable from a
      broken stream. (DR-145)

    • The no-audio fallback picks a track the device can decode. When ExoPlayer
      selected no audio track, recovery forced group 0 / track 0 unconditionally — but
      the most likely reason nothing was selected is that this very track cannot be
      decoded here, so the override reinstated the silence it was meant to fix.
      (DR-146)

    Downloads

    Platform File
    Android jellytau-release.apk — sideload or adb install
    Windows (portable) jellytau.exe
    Linux (Debian/Ubuntu) jellytau_0.4.6_amd64.debsudo dpkg -i
    Windows jellytau_0.4.6_x64-setup.exe (NSIS installer)

    Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues

    Downloads