• JellyTau v0.14.0
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 7m22s
    📱 Test APK / Build test APK (push) Successful in 23m39s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 3m36s
    Traceability Validation / Check Requirement Traces (push) Successful in 10s
    Build & Release / Run Tests (push) Successful in 10m16s
    Build & Release / Build Linux (push) Successful in 14m14s
    Build & Release / Build Windows (push) Successful in 11m32s
    Build & Release / Build Android (push) Successful in 20m33s
    Build & Release / Create Release (push) Successful in 44s
    Stable

    dtourolle released this 2026-09-25 08:19:11 +00:00 | 0 commits to master since this release

    Video on the desktop is played by mpv, on Linux and now on Windows, and the
    built-in web player is gone from every platform. Windows gets real audio
    playback too.

    🔒 Security

    • A track title can no longer run a command on Linux. mpv was handed stream
      URLs and downloaded-file paths as a single command string, in which ; starts
      a new command — so a file whose title tag carried one could run a program
      when it played. Every mpv command now passes its arguments separately.
      (DR-298)
    • mpv checks the server's certificate. It did not by default, and the
      addresses it opens carry your login token, so anyone able to intercept the
      connection could read it. It also no longer hands a failed address to
      youtube-dl. (DR-299)
    • The app's web page can no longer reach the network. It needed that only
      for the web video player; everything now goes through the backend, so the
      permission was just a way out for anything injected into the page.

    ✨ Features

    • mpv plays all video on Linux and Windows. On Windows it draws into the app
      window under the controls; on Linux it no longer needs the experimental
      switch. Video still arrives transcoded to h264 for now — asking the server for
      the original file is the next step. (DR-235, DR-237)
    • Windows plays audio through mpv, so volume, the equalizer, volume
      normalization and gapless playback now work there. The installer ships
      mpv's LGPL-licensed library and its licence text. (DR-237)

    🐛 Fixes

    • Subtitles and audio-track switching work in desktop video. mpv now loads
      the subtitle list and switches subtitles and audio tracks itself; before this
      they did nothing once mpv drew the picture. (DR-023, DR-024)
    • Downloaded songs with a space in their title play offline on Linux.
      (DR-298)
    • A queued download on Windows keeps the path it was saved under, rather
      than having its separators rewritten. (DR-211)

    🧹 Removed

    • The built-in web video player and the "Native Video" setting. There is
      nothing left to switch between: every platform plays video natively.
      (DR-235)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.13.3
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 3m57s
    📱 Test APK / Build test APK (push) Successful in 20m27s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 3m45s
    Traceability Validation / Check Requirement Traces (push) Successful in 11s
    Build & Release / Run Tests (push) Successful in 10m38s
    Build & Release / Build Linux (push) Successful in 14m21s
    Build & Release / Build Windows (push) Successful in 10m47s
    Build & Release / Build Android (push) Successful in 20m26s
    Build & Release / Create Release (push) Successful in 43s
    Stable

    dtourolle released this 2026-09-24 11:40:35 +00:00 | 5 commits to master since this release

    🐛 Fixes

    • Coming back to the app no longer replaces the page with "Failed to load
      item".
      After a few minutes in the background, resuming the app on a series
      page could swap the whole page for that error, and it stayed until you
      navigated away. The page refreshes itself on resume; a refresh that fails now
      leaves what you were looking at on screen, and the error clears as soon as a
      load succeeds. When a page genuinely cannot open, it now says why instead of
      the generic message. (DR-297)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.13.2
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 4m15s
    📱 Test APK / Build test APK (push) Successful in 20m30s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 3m46s
    Traceability Validation / Check Requirement Traces (push) Successful in 14s
    Build & Release / Run Tests (push) Successful in 10m32s
    Build & Release / Build Linux (push) Successful in 14m6s
    Build & Release / Build Windows (push) Successful in 10m50s
    Build & Release / Build Android (push) Successful in 20m20s
    Build & Release / Create Release (push) Successful in 37s
    Stable

    dtourolle released this 2026-09-24 02:47:07 +00:00 | 7 commits to master since this release

    A series opens with its episodes in under a second. v0.13.1 fixed the season
    list; the episode list below it still took about five seconds on a Fairphone.

    ⚡ Performance

    • The episode list no longer waits for the server. It used to wait for
      "Next Up" and your resume point, fetched from the server first, although every
      episode was already on the device. The list now shows as soon as it is
      loaded, and Next Up answers from the device first like everything else.
      (DR-101, DR-295)
    • A page loads once. Opening a series loaded it six times over, putting
      about seventy requests in flight at once. It now loads once, and re-loads only
      when something actually changed (reconnecting, marking watched). (DR-295)
    • The local database finds things by index instead of reading everything.
      Each item now records the one container it is listed under, so a series,
      season or album page is a single index lookup — under a millisecond on a
      100,000-item library, where it used to scan the whole catalogue. The update
      converts an existing library in well under a second, once. (DR-012, DR-013)

    🐛 Fixes

    • A series lists its seasons, not every episode as well. Both the library
      view and the Downloads view mixed a series' episodes in with its seasons.
      (DR-013)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.13.1
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 3m56s
    📱 Test APK / Build test APK (push) Canceled after 9m51s
    Publish Documentation / Build & publish docs to gitea-pages (push) Canceled after 0s
    Traceability Validation / Check Requirement Traces (push) Successful in 13s
    Build & Release / Run Tests (push) Successful in 10m30s
    Build & Release / Build Linux (push) Successful in 14m30s
    Build & Release / Build Windows (push) Successful in 10m56s
    Build & Release / Build Android (push) Successful in 20m10s
    Build & Release / Create Release (push) Successful in 33s
    Stable

    dtourolle released this 2026-09-24 01:59:10 +00:00 | 10 commits to master since this release

    Pages answer from the cache again. Found on a Fairphone, where opening a
    series took one to ten seconds even though everything on it was already cached.

    ⚡ Performance

    • Series and library pages load from the cache. Frasier's season and
      episode lists now appear in 34–133 ms on a Fairphone 5; they took 600–1030 ms
      each, waiting on the server. Three causes stacked up. Every database read
      waited behind every write, because one connection served the whole app. The
      listing query scanned the entire cached catalogue whatever page it was for.
      And a cache answer that took longer than 100 ms was ignored until the server
      replied. Reads now have their own connections, the query uses its indexes
      (about 50× faster on a 100k-item cache), and the cache and the server race:
      whichever answers first with something to show wins. (DR-012, DR-013)
    • A series page walks its seasons once, in parallel. It used to walk all of
      them twice, one after another. (DR-295)

    🐛 Fixes

    • Coming back from background audio opens the right episode. If an episode
      ended while the app was in the background, returning to it reloaded the
      previous episode at the new one's position. (DR-296)
    • Offline changes keep their own identity. Two favourites or progress
      updates queued at the same moment could be handed each other's queue entry,
      so syncing one marked the other as done. (DR-014)
    • Catalog caching no longer switches off data-integrity checks for the rest
      of the app
      while it saves a page. (DR-012)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.13.0
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 1m23s
    📱 Test APK / Build test APK (push) Successful in 58m53s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 10m51s
    Traceability Validation / Check Requirement Traces (push) Successful in 29s
    Build & Release / Run Tests (push) Successful in 10m38s
    Build & Release / Build Linux (push) Successful in 14m27s
    Build & Release / Build Windows (push) Successful in 16m56s
    Build & Release / Build Android (push) Successful in 20m4s
    Build & Release / Create Release (push) Successful in 31s
    Stable

    dtourolle released this 2026-09-23 02:24:26 +00:00 | 14 commits to master since this release

    Android plays and downloads the original file, and offline mode works without
    a network. Found on a tablet with no Dolby decoder, where nearly every film was
    being transcoded by the server — slowly, and unresumably — just for its audio.

    ✨ Features

    • Dolby and DTS audio play on every Android device. Android ships no AC-3,
      E-AC-3, DTS or TrueHD decoders — they exist only where a manufacturer paid for
      them. The player now decodes them itself (FFmpeg), so these films stream and
      download as the original file instead of a server transcode: direct play when
      streaming, and a download that runs at full speed, shows a real percentage,
      and resumes after a dropped connection. Measured: a 910 MB E-AC-3 5.1 episode
      in 94 seconds, where a transcode managed about 1 MB/s. (DR-293)

    🐛 Fixes

    • Downloaded films play offline. Playing a download asked the server for
      details it did not need, so with no network it waited seven seconds, failed,
      and never opened the file on disk. It now answers from the download itself.
      (DR-294)
    • "Failed to load item" offline. Opening a downloaded show's details could
      fail while the app was writing to its database (the catalog sync at every
      launch, a download finishing): the cached answer was thrown away for being
      slow, and the server — unreachable — was reported instead. The library list,
      genres, playlists, search and favourites had the same flaw. They now wait for
      the cache. (DR-294)
    • The TV page no longer blanks offline. Its "Next Up" row was server-only,
      and its failure took the whole page with it. It now falls back to the cache.
      (DR-294)

    🔧 Changes

    • Native video is no longer optional on Android. The built-in web player
      cannot decode Dolby or DTS audio, so with original files downloaded it would
      play them silent. The "Native Video" switch is gone from Android settings (it
      remains on Linux, beside mpv native video).
    • Licence. The Android app now bundles a GPL-3.0 component (the FFmpeg audio
      decoder), so the distributed APK carries GPL-3.0 terms; JellyTau's source stays
      MIT. See THIRD_PARTY_NOTICES.md.

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.12.2
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 27s
    📱 Test APK / Build test APK (push) Successful in 32m30s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m56s
    Traceability Validation / Check Requirement Traces (push) Successful in 13s
    Build & Release / Run Tests (push) Successful in 16m28s
    Build & Release / Build Linux (push) Successful in 21m48s
    Build & Release / Build Windows (push) Successful in 19m42s
    Build & Release / Build Android (push) Successful in 32m19s
    Build & Release / Create Release (push) Successful in 33s
    Stable

    dtourolle released this 2026-09-21 09:19:32 +00:00 | 21 commits to master since this release

    Two download fixes, found together on a tablet whose films all needed their
    audio re-encoded. Downloads that took longer than five minutes were being cut
    off and restarted, and the progress bar sat on "0%" for the whole of a
    transcode.

    🐛 Fixes

    • Downloads longer than five minutes no longer fail. The download worker's
      HTTP client carried a total request deadline of five minutes — from
      connect until the last byte — so every transfer longer than that was cut off
      mid-body and retried. A transcode cannot be resumed (the server ignores
      Range and starts over), so each retry threw away what had been fetched, hit
      the same deadline, and after three attempts the download failed. No feature
      film at transcode speed could complete; a large direct copy limped through in
      five-minute slices with a backoff between each. The deadline is now a
      30-second connect timeout plus a 60-second stall timeout that resets on
      every chunk: a dead connection is still caught, a healthy transfer can run as
      long as it needs. Present since the first release. (DR-289)

    ✨ Improvements

    • The progress bar moves during a transcode download. A transcode is
      produced as it is sent, with no Content-Length, and the bar had nothing to
      measure against — it read "0%" until the file completed. The backend now
      predicts the size when it resolves the download: the source's size for
      original (the picture is copied byte-for-byte; only the audio changes), or
      bitrate × runtime for a quality preset. The bar shows the estimate as
      "~42%" and caps at 99% until the last byte lands; the server's own figure is
      used whenever it gives one; and when there is no prediction at all the bar
      is a moving band with the bytes so far, rather than a false "0%". (DR-290)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.12.0
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Failing after 53s
    📱 Test APK / Build test APK (push) Successful in 54m6s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 8m54s
    Traceability Validation / Check Requirement Traces (push) Successful in 18s
    Build & Release / Run Tests (push) Successful in 23m38s
    Build & Release / Build Linux (push) Successful in 31m12s
    Build & Release / Build Windows (push) Successful in 32m21s
    Build & Release / Build Android (push) Successful in 49m32s
    Build & Release / Create Release (push) Successful in 1m24s
    Stable

    dtourolle released this 2026-09-19 10:23:41 +00:00 | 26 commits to master since this release

    JellyTau works against Jellyfin 12. Jellyfin 12.0 shipped on 2026-09-08 and
    turns off, by default, the two ways every earlier JellyTau build identified
    itself to a server — including on servers that were upgraded rather than freshly
    installed. An app that was not changed for it stops signing in the day the server
    updates. This release is changed for it, and still works against 10.11, so the
    app can be updated first and the server whenever it suits.

    There is no Jellyfin 11. The project dropped the leading 10 from its version
    scheme: what would have been 10.12.0 shipped as 12.0. Anything that compares
    Jellyfin version numbers needed to learn that, and this app now has.

    ✨ Changes

    • Signing in survives a server upgrade to Jellyfin 12. The server used to be
      told who was asking through a header and a URL parameter that 12.0 disables by
      default — a migration disables them on upgraded servers too, so nothing in an
      admin's hands changes the outcome. The replacement spellings are accepted by
      10.11 and 12 alike, so this is one way of identifying the app that works
      everywhere, not a switch between two. The URL half matters more than it
      sounds: video and audio are streamed by the device's media player, which cannot
      send headers at all, so the URL parameter is the only way playback can
      authenticate. A test now refuses any request built with the old spellings,
      because the failure is silent right up until a server upgrades.
      (UR-085 → DR-287)

    • Browsing a library returns the same things on both server versions. 12.0
      changed what a filtered library listing means — asked for the films in a
      library, 10.11 returned the folder's immediate contents and 12.0 returns
      everything beneath it, and nothing in the reply says which rule applied. The
      app now says which it wants, so both servers answer the same way, and the
      answer is the one it always had. (UR-085 → DR-288)

    • The app knows what server it is talking to, once, and adapts. The server
      version was already fetched at sign-in and then thrown away. It is now
      resolved into a small set of named capabilities that every version-dependent
      decision reads from, rather than the version number being compared wherever
      somebody needed it — which is unreadable by the second occurrence and cannot
      express a backport. A server newer than this build is treated as the newest
      one it knows and keeps working; refusing it would make every release expire
      the moment the server updated. Only a server older than 10.10 is refused, and
      the sign-in screen says so and names the minimum. (UR-085 → IR-035, DR-280,
      DR-286)

    • The cached library re-fetches itself after a server upgrade. Nothing had
      recorded which server version wrote the cached catalog, so a server upgraded
      underneath the app kept serving rows read under the old rules. The generation
      is now recorded, and a change clears the cache so it fills back under the new
      one. The first launch of this version records and clears nothing — an
      existing install is not charged a full re-download to defend against an
      upgrade that has not happened. (UR-085 → DR-284)

    🛠 Development

    • Every route the app speaks lives in one place. Fifty-seven inline URL
      strings across the server adapter became one module of route functions, each
      taking the resolved capabilities. Both shapes of the item routes Jellyfin has
      deprecated are built and tested, though nothing selects the second yet — the
      family still works on 12.0, and 12.0's written policy that unlisted endpoints
      may go in any major release is why having the alternative ready costs less
      than needing it. (UR-085 → DR-279, DR-282)

    • The server adapter is tested against a server. There was no HTTP mocking
      in the Rust tree at all: every test of the adapter asserted on a URL string it
      had built, and none exercised a reply. A fake Jellyfin now answers over real
      HTTP and reports whichever version a test asks for, so the same assertions run
      against both generations through the production resolution path. The one
      file that had tried this before reimplemented the URL builders inside its own
      mock and asserted against itself — and had never compiled, and had once
      stayed green while the real code shipped a download endpoint that 404s. It is
      deleted, and the rule it teaches is written at the top of its replacement.
      (UR-085 → DR-281)

    • A Jellyfin URL was being built in the interface layer — the last one,
      and, it turned out, unused. Deleted rather than moved. (UR-085 → DR-285)

    ⚠️ Known limits

    Every cross-version assertion runs against a fake server built from a
    source-level diff of the two Jellyfin releases, not against a running 12.0. Two
    things that diff could not settle: whether remote control and casting behave
    identically, and whether the audio-codec check that forces a transcode on 10.11
    is still needed on 12 — it is left on, which errs toward an unnecessary
    transcode rather than silent playback. Both resolve with a real 12.0 server;
    reports welcome.

    Upgrading: install this version before upgrading the server, not after.
    It works against both; an older JellyTau does not work against 12.

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • JellyTau v0.11.6
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 4m4s
    📱 Test APK / Build test APK (push) Successful in 48m6s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 9m17s
    Traceability Validation / Check Requirement Traces (push) Successful in 20s
    Build & Release / Run Tests (push) Successful in 22m27s
    Build & Release / Build Linux (push) Successful in 31m18s
    Build & Release / Build Windows (push) Successful in 30m1s
    Build & Release / Build Android (push) Successful in 45m53s
    Build & Release / Create Release (push) Successful in 1m15s
    Stable

    dtourolle released this 2026-09-07 20:30:29 +00:00 | 34 commits to master since this release

    Found by an audit of the stack's most fragile seams rather than by hitting them,
    so most of these are faults that had not yet been reported — several could only
    be reached on a bad day, and the worst of them only once.

    🐛 Fixes

    • An interrupted update can no longer stop the app from ever opening again.
      Changes to the local database were applied one statement at a time with no way
      to undo a half-finished one. If an update was interrupted partway — a full
      disk, the phone reclaiming memory, the app being killed mid-launch — the
      earlier statements stuck while nothing recorded that the change had happened.
      On the next launch it started again from the beginning, immediately hit the
      part that was already done, and gave up; and since the app treats a database
      it cannot prepare as fatal, it stopped opening at all, on every launch, with
      the only way out being to clear its data and lose downloads and sign-ins. Each
      change is now all-or-nothing, so an interrupted one leaves no trace and the
      next launch simply tries again. (UR-002 → DR-012)

    • The app no longer vanishes without trace when the player hits trouble.
      The parts of the Android player that report back into the app — position,
      state changes, errors, the end of a track — had no protection around them, and
      a failure inside one killed the whole app instantly: no error, no message, not
      even a crash report worth sending. One such failure was reachable in ordinary
      use, on the position report that fires four times a second: under memory
      pressure the app could fail to build the small worker it needs to send that
      report, and that alone was enough to take everything down. A dropped position
      report is now just a dropped position report. (UR-005 → DR-052)

    • One internal failure no longer disables the whole app until it is restarted.
      Every part of the app that reads or writes local data shares a single gate to
      it. If anything failed while holding that gate, the gate stayed jammed: from
      then on every library page, download, setting and sign-in returned an error for
      the rest of the session, and only quitting and reopening cleared it. The gate
      now recovers instead of jamming. (UR-002 → DR-012)

    • Browsing offline no longer reports a network error over content already on
      the device.
      A read of local data was given a tenth of a second to answer and
      otherwise abandoned and treated as "nothing stored". That is easily exceeded
      on phone storage whenever something else is writing — a sync catching up, a
      batch of artwork being saved — and offline, where there is no server to fall
      back to, the result was a network error shown over a library that was sitting
      on disk. Worse, the abandoned read kept running and kept the storage busy,
      making the next one slower still. A slow read is now waited for rather than
      thrown away, and a fast one still answers immediately as before. (UR-002 →
      DR-013)

    • A download that arrived empty is no longer presented as ready to play. If
      the server answered a download with nothing at all — an error page, a
      conversion that produced no output — the empty file was moved into place and
      the item was marked available offline. Opening it then hung: the app's own
      media server promised one byte of it and sent none, so the player waited
      forever with nothing on screen to say why. An empty download is now treated as
      the failure it is, keeping the partial file so it can resume, and a request for
      an empty file gets an honest refusal instead of a promise. (UR-019, UR-071 →
      DR-168, DR-137)

    • Renaming your computer no longer signs you out. On systems without a
      password manager, sign-in tokens are kept in a file whose key was rebuilt from
      the machine's name and the current username each time the app started. Rename
      the machine, or launch it from somewhere the username is not set, and the key
      came out different, the file could no longer be read, and the app treated that
      as never having been signed in — with nothing shown to explain it. The key is
      now made once, kept, and unaffected by what the machine is called. Existing
      saved sign-ins are carried over automatically. This file has never been a
      substitute for a real password manager, and the app now says so plainly rather
      than implying otherwise. (UR-012 → IR-014)

    • The player's internal locking is now checked rather than merely careful.
      The playback controller coordinates seventeen separate pieces of shared state
      across the audio engine, the lock screen, timers and every screen in the app.
      Nothing stopped two of them being taken in opposite orders by different parts
      of the code, which freezes playback outright with no error anywhere — a fault
      this part of the app has produced before. The correct order is now written down
      and enforced automatically, so a future change cannot quietly reintroduce it.
      No such fault existed; this keeps it that way. (UR-005 → DR-052)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads
  • latest c44070e720

    Latest build (master)
    🏗️ Build and Test JellyTau / Run Tests (push) Successful in 24m28s
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 55s
    📱 Test APK / Build test APK (push) Successful in 51m15s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 9m8s
    Traceability Validation / Check Requirement Traces (push) Successful in 15s
    🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 7m9s
    Pre-Release

    dtourolle released this 2026-09-05 15:41:49 +00:00 | 46 commits to master since this release

    Automatic build of master at a67452bc — not a release.

    Installs as JellyTau Debug (com.dtourolle.jellytau.debug), alongside a
    normal install and with its own separate data. It cannot replace or upgrade a
    real install, and uninstalling it does not touch one.

    R8-minified like a real release, but signed with a debug key — so Android will
    warn about an unknown source. That is expected.

    Variant: side-by-side-release · ABI: aarch64

    This release is refreshed on every push; the download link stays the same.

    Downloads
  • JellyTau v0.11.5
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 3m41s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m20s
    Traceability Validation / Check Requirement Traces (push) Successful in 11s
    Build & Release / Run Tests (push) Successful in 14m44s
    Build & Release / Build Linux (push) Successful in 20m30s
    Build & Release / Build Windows (push) Successful in 15m38s
    Build & Release / Build Android (push) Successful in 30m30s
    Build & Release / Create Release (push) Successful in 37s
    Stable

    dtourolle released this 2026-08-27 15:58:12 +00:00 | 56 commits to master since this release

    🐛 Fixes

    • A video in a picture-in-picture window stays a video. Watching in a PiP
      window would sometimes drop to audio only, and the audio would pick up from
      wherever the video had been when the window opened — while the picture itself
      had carried on well past that. Two faults, both needed to produce it. The
      player's idea of where it is in the video is kept by a loop that only runs
      while the app is drawing to the screen, and behind a PiP window it is not:
      the position quietly stopped advancing the moment the window opened, and the
      one other source that could have kept it current had been written to switch
      itself off during playback. Separately, PiP and the "keep the audio playing in
      the background" toggle are meant to be alternatives, but only the toggle
      enforced that — the PiP button could still be pressed with both armed, and the
      single moment-in-time check meant to tell them apart is not always right about
      whether a window is open. Opening PiP now turns background audio off, the app
      trusts its own record of the window as well as the system's, and the position
      keeps advancing whether or not anything is being drawn. The frozen position
      also affected the seek bar, resume points and watch progress reported to the
      server for as long as a PiP window was open. (UR-004, UR-040, UR-041 →
      DR-265, DR-266)

    Downloads

    Platform File
    Linux (portable) *.AppImage — chmod +x and run
    Linux (Debian/Ubuntu) *.deb — sudo dpkg -i
    Linux (Fedora/openSUSE) *.rpm — sudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

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

    Downloads