-
JellyTau v0.11.0
StableBuild & Release / Create Release (push) Blocked by required conditionsPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 6m5sTraceability Validation / Check Requirement Traces (push) Successful in 19sBuild & Release / Run Tests (push) Successful in 15m20sBuild & Release / Build Linux (push) Waiting to runBuild & Release / Build Windows (push) Waiting to runBuild & Release / Build Android (push) Waiting to runreleased this
2026-08-23 09:53:57 +00:00 | 0 commits to master since this releaseVideo can play through the native renderer on Linux, and the machinery every
platform's playback goes through was rebuilt around one contract. Nine defects
fell out of doing it — each one a capability the code had written down as a
fact about the platform rather than asking the thing that would know.✨ Changes
-
Video can decode natively on Linux, without the server re-encoding it.
Until now every video played on the desktop was transcoded by Jellyfin to
h264 and handed to the browser engine, whatever the file actually was — so the
server burned CPU on every play, and quality was capped by that conversion.
mpv can now draw the picture directly, composited beneath the interface so the
controls, subtitles and overlays still sit on top of it. Direct play means the
original file, hardware decoding, and no server work at all. This is off by
default while it settles: setJELLYTAU_NATIVE_VIDEO=1to try it. The browser
path is untouched and remains what you get otherwise. (UR-080 → DR-231 …
DR-237) -
Playback speaks one language across every player. Linux, Android and
Windows each drove their engine through a different set of calls, and a rule
learned on one did not reach the others — which is why several of the fixes
below existed on one platform and not another. All three now go through a
single contract, and one suite of behaviours runs against every engine,
including ExoPlayer on a real device. An engine is either correct or visibly
failing. Nothing about this is visible while it works, which is the point.
(UR-081 → DR-242 … DR-247)
🐛 Fixes
-
Resuming a film starts where you left it, instead of at the beginning.
Asking a player to open a file and asking it to start at a position were two
separate steps, and the second was issued before the first had finished — so
it failed, was discarded, and playback began at zero. It affected resume and
any skip on a stream the server was converting. The position is now part of
opening the file, so there is no gap for it to fall into. (DR-241) -
Skipping works on films the server is converting. A skip was routed by the
shape of the stream rather than by what the player could do with it. That
happened to be right while one particular player handled those streams and
became wrong the moment another did — after which skipping simply did nothing,
silently. Players now say what they can do and are asked. (DR-238, DR-246) -
The play and pause button follows the player again. The code that reacted
to pausing was never subscribed to the event it was waiting for, so the button
stayed where it was while playback did something else. (DR-239) -
Fullscreen fills the screen. It expanded the page rather than the window,
which was invisible while the picture was drawn inside the page and obvious as
soon as it was not. (DR-240) -
The seek bar knows how long the film is. A player that had not yet worked
out the duration reported zero, and zero was believed — leaving the bar with
no scale and nothing to drag against, even though the length had been known
since the library listed it. (DR-251) -
Leaving the player stops the sound. The stop was aimed at whichever
renderer the app believed was in charge. Enabling background audio hands over
to a different one, so afterwards the app stopped something that was no longer
playing and the film carried on as an audio track in the mini player. Closing
now stops everything, regardless of who was in charge. (DR-250) -
Coming back from background audio no longer leaves a black screen. The
stream that plays while the app is hidden has no fixed length, and the value a
player uses to say so is a very large negative number. Converting it crashed
the playback engine outright, which looked like a dead player with no
controls. (DR-252) -
Android builds again. A rule that only applied to Linux stayed attached to
code that had stopped being Linux-only, and the Android build had not compiled
since. (DR-247)
🧹 Under the hood
-
The conformance suite can be run on its own:
bun run test:playerfor the
desktop engines,bun run test:player:androidfor ExoPlayer on a connected
device. Both build a test fixture rather than carrying media in the
repository. -
docs/native-player-verification.md
records what to check before a release, including the exact sequences that
found two of the defects above — both of which passed every automated test.
Known limitations
- Resume reads progress saved on the device, not from the server, so a fresh
install or a second device will not offer to resume something watched
elsewhere. - Native video on Linux is opt-in and is not yet the default.
Downloads
Platform File Linux (portable) *.AppImage—chmod +xand runLinux (Debian/Ubuntu) *.deb—sudo dpkg -iLinux (Fedora/openSUSE) *.rpm—sudo rpm -iWindows *-setup.exe(NSIS). Unsigned — SmartScreen may warn on first run.Android *.apksideload, or*.aabfor Play ConsoleDesktop builds check for updates from here and can install a new
version in place, verifying its signature first.Verifying your download
sha256sum -c SHA256SUMSSHA256SUMScovers 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.10.1
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 18m44s🏗️ Build and Test JellyTau / Supply Chain (push) Failing after 49sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m27sTraceability Validation / Check Requirement Traces (push) Successful in 10sBuild & Release / Run Tests (push) Successful in 14m48s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m19sBuild & Release / Build Linux (push) Successful in 20m20sBuild & Release / Build Windows (push) Successful in 15m36sBuild & Release / Build Android (push) Successful in 30m46sBuild & Release / Create Release (push) Successful in 38sreleased this
2026-08-22 08:10:12 +00:00 | 6 commits to master since this releaseA single fix, for something that had been quietly overriding a choice you made.
🐛 Fixes
- Locking the screen no longer keeps playing a video's audio unless you asked
it to. The player has a background-audio button: turn it on and the sound
carries on when you lock the screen or leave the app, turn it off and playback
stops. It stopped working when video moved to the native renderer — which plays
through a media service designed to keep going while the app is hidden — and
nothing was left to stop it. So the audio continued whether the button was on
or off, and there was no way to make it behave otherwise. The button governs it
again: with it off, locking the screen pauses the video and unlocking resumes
where you were; with it on, the audio continues as before. Music is untouched —
it keeps playing when backgrounded, as a music player should — and a video in a
picture-in-picture window keeps playing too, because the window is still on
screen. If you had already paused before locking, it stays paused.
(UR-040 → DR-224)
Downloads
Platform File Linux (portable) *.AppImage—chmod +xand runLinux (Debian/Ubuntu) *.deb—sudo dpkg -iLinux (Fedora/openSUSE) *.rpm—sudo rpm -iWindows *-setup.exe(NSIS). Unsigned — SmartScreen may warn on first run.Android *.apksideload, or*.aabfor Play ConsoleDesktop builds check for updates from here and can install a new
version in place, verifying its signature first.Verifying your download
sha256sum -c SHA256SUMSSHA256SUMScovers 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
- Locking the screen no longer keeps playing a video's audio unless you asked
-
JellyTau v0.10.0
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 15m52s🏗️ Build and Test JellyTau / Supply Chain (push) Failing after 29sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m35sTraceability Validation / Check Requirement Traces (push) Successful in 11sBuild & Release / Run Tests (push) Successful in 14m53s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m22sBuild & Release / Build Linux (push) Successful in 20m53sBuild & Release / Build Windows (push) Successful in 15m41sBuild & Release / Build Android (push) Successful in 30m46sBuild & Release / Create Release (push) Successful in 38sreleased this
2026-08-22 00:52:36 +00:00 | 7 commits to master since this releaseTwo things you can see, and a great deal of work on how this project builds and
ships itself. The app can now update itself, and it can tell you what it did
when something goes wrong — both of which existed as gaps rather than as bugs,
which is why they lasted so long.✨ Changes
-
JellyTau can update itself. Anyone who installed an AppImage or ran the
Windows installer was frozen on that version permanently: nothing in the app
ever mentioned that a newer one existed, and the release page was the only
announcement. Settings → Updates now checks, shows what changed, and installs
and restarts on request. Each download is verified against JellyTau's signing
key before anything is installed, so a substituted file is refused rather than
run. Android is deliberately not wired to this — an app may not replace its own
APK, that is the system installer's job — and is given a link to the releases
page instead of a button that would fail. (UR-077 → DR-217) -
You can export a diagnostics bundle. Until now the app forgot everything it
had done the moment it closed. Logs went to standard output, which nobody sees
when launching from a desktop icon, and on Android went nowhere at all — so the
backend was invisible on the platform where the hardest playback bugs live. A
crash left nothing behind. Logs are now kept in a size-capped file that
survives a restart, a crash is recorded before the app dies, and Settings →
Diagnostics exports the lot as one file to attach to a bug report. Access
tokens and passwords are stripped before anything is written to disk, not
merely before it is exported. Nothing is transmitted anywhere; you attach the
file yourself. (UR-078 → DR-218) -
Linux gets an AppImage again. The release notes have advertised one for
months while the build never produced it — the packaging step looked for the
file, found nothing, and said nothing. (DR-217)
🐛 Fixes
-
Releases no longer ship every Windows installer ever built. Every release
from v0.1.0 to v0.8.2 carried its predecessors': sixteen installers on v0.8.2,
thirteen of them stale, and a download list on v0.5.0 reaching back to 0.1.0.
The build directory is never cleaned and the build machine reuses it, so each
release collected whatever was left behind. It went unnoticed for eight months
because nothing looked wrong — the files were real and the page merely looked
busy. The stale files have been removed from the published releases, the build
now clears that directory first, and a check refuses to publish a release
containing an artifact from a different version. (DR-220) -
Release notes now say what changed. All 35 previous releases published the
same block of generic install instructions, whose "What's New" section was a
link to a file that does not resolve from a release page. Every release page
now carries its own entry from this changelog, and the past ones have been
filled in. (DR-219)
🔒 Security and supply chain
-
Dependencies are now checked against a vulnerability database on every
build. They never had been. The first run found eight vulnerabilities and one
unsoundness in the Rust dependency graph — all of them fixed by an update
nobody had a reason to run. Licences are checked against an allow-list too, so
nothing gets redistributed inside a release that does not permit it.
(DR-216) -
Every release publishes checksums and a bill of materials.
SHA256SUMS
lets you verify a download (sha256sum -c SHA256SUMS); the SBOM lists what
went into the build, so "does this release contain ?" has
an answer that is not "rebuild it and find out". (DR-216) -
Builds are reproducible again. Every CI job named a container image tag
that was rewritten in place, so rebuilding an old release did not necessarily
rebuild the same thing. Jobs now pin an immutable tag. The one dependency that
comes from a git branch rather than a package registry is pinned to an exact
revision, closing a path by which new upstream code could arrive unreviewed in
a library linked into the player. (DR-216)
🧹 Under the hood
-
Formatting, linting and type-checking now run in CI. All three were configured
and enforced by nothing: 199 files did not match the project's own formatter, a
type error could sit on the main branch until somebody cut a release, and the
test-coverage command had been broken for months by a dependency mismatch.
Coverage now has a floor that only moves up. (DR-215) -
The traceability matrix counts requirements implemented by configuration.
Several carried the necessary annotations and were being counted as uncovered
because the extraction tool only read source files. (DR-215) -
The project now has a security policy, contribution guide, code of conduct,
issue and pull-request templates, and an operations document covering the
builder image, the release secrets, and what losing the signing key would mean. -
The app framework moved from Tauri 2.9.5 to 2.11.5. Nothing about this is
visible in use, but it is worth recording that it did not go quietly: the
windowing layer beneath Tauri quietly stopped publishing the Android JavaVM
and application handle that this app's credential storage had been reading for
its whole life. Nothing here had changed; a side effect several dependencies
down had simply gone away, and the app aborted on launch on every Android
device. JellyTau now sets that handle itself rather than relying on someone
else to do it. Caught by installing on a real tablet before release — no test
suite runs the app. (UR-012 → DR-223)
Downloads
Platform File Linux (portable) *.AppImage—chmod +xand runLinux (Debian/Ubuntu) *.deb—sudo dpkg -iLinux (Fedora/openSUSE) *.rpm—sudo rpm -iWindows *-setup.exe(NSIS). Unsigned — SmartScreen may warn on first run.Android *.apksideload, or*.aabfor Play ConsoleDesktop builds check for updates from here and can install a new
version in place, verifying its signature first.Verifying your download
sha256sum -c SHA256SUMSSHA256SUMScovers 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.9.1
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 13m55sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m22sTraceability Validation / Check Requirement Traces (push) Successful in 16sBuild & Release / Run Tests (push) Successful in 14m0s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m9sBuild & Release / Build Linux (push) Successful in 16m39sBuild & Release / Build Windows (push) Successful in 20m42sBuild & Release / Build Android (push) Successful in 29m18sBuild & Release / Create Release (push) Successful in 13sreleased this
2026-08-21 11:34:28 +00:00 | 29 commits to master since this releaseA one-line fix to the home screen, released on its own because it is the kind of
small wrongness you notice every time.🐛 Fixes
- Swiping the hero banner now buys you a full six seconds. The rotation
timer was started once when the banner appeared and then left alone, so a
swipe, arrow or dot tap inherited whatever was left of the running countdown
— swipe five and a half seconds in and the banner moved on half a second
later, before you had read the title. Any manual change now restarts the
countdown from that moment. (UR-034 → DR-038)
Downloads
Platform File Linux (Fedora/openSUSE) JellyTau-0.9.1-1.x86_64.rpm—sudo rpm -iLinux (Debian/Ubuntu) JellyTau_0.9.1_amd64.deb—sudo dpkg -iWindows JellyTau_0.9.1_x64-setup.exe(NSIS installer)Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exe
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
- Swiping the hero banner now buys you a full six seconds. The rotation
-
JellyTau v0.8.2
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 24m47sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m40sTraceability Validation / Check Requirement Traces (push) Successful in 20sBuild & Release / Run Tests (push) Successful in 25m19s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 11m18sBuild & Release / Build Linux (push) Successful in 30m51sBuild & Release / Build Windows (push) Successful in 14m55sBuild & Release / Build Android (push) Successful in 32m54sBuild & Release / Create Release (push) Successful in 20sreleased this
2026-08-19 15:29:42 +00:00 | 78 commits to master since this releaseA single fix, for Android background audio.
🐛 Fixes
- Listening to a video in the background no longer jumps back to where you
started. Handing a video off to background audio streams a live mp3
transcode, which is chunked — no length, and no duration the player can read.
ExoPlayer resumes a failed load in place only when it knows one of those two
things; with neither it assumes the source is live and re-requests the URL from
the beginning. That URL starts at the moment you locked the screen, so a
network blip left a retry armed, and when the buffer eventually ran dry —
minutes later, with nothing in between — playback silently resumed from the
handoff point and carried on. No error was raised and nothing ended, so none of
the existing stream-recovery paths could see it; the only sign was a position
that went backwards, which is why it looked random. The player is now refused
its own retry for exactly that kind of stream, so the failure surfaces and the
backend re-opens the stream at the position playback actually reached, keeping
your selected audio track. Music and video are untouched: both declare their
timeline, and the player resumes them where the load stopped.
(UR-040, UR-004 → DR-203)
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.8.2_amd64.deb—sudo dpkg -iWindows jellytau_0.8.2_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
- Listening to a video in the background no longer jumps back to where you
-
JellyTau v0.8.0
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 25m14sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m47sTraceability Validation / Check Requirement Traces (push) Successful in 36sBuild & Release / Run Tests (push) Successful in 26m3s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 11m2sBuild & Release / Build Linux (push) Successful in 32m23sBuild & Release / Build Windows (push) Successful in 14m59sBuild & Release / Build Android (push) Successful in 31m22sBuild & Release / Create Release (push) Successful in 31sreleased this
2026-08-16 22:00:10 +00:00 | 85 commits to master since this releaseA security and correctness release, from an audit of the codebase against its own
requirements and against current Android/Tauri practice. Most of it is invisible
in use; three things change behaviour you can see, listed first.✨ Changes
-
The app no longer backs its data up to your Google account. It never
should have:allowBackupwas on by default, which sent the library catalogue
and watch history off the device — and the credentials went with it in a form
that could never be read again, because they are encrypted under an Android
Keystore key and Keystore keys are never backed up. Restoring onto a new phone
therefore produced ciphertext with no key: an authentication failure with no
explanation. Backup is now off, for device-to-device transfer as well as cloud
(a separate channel with the identical failure), and an unreadable credential
blob is now treated as "logged out" rather than an error, so the next sign-in
repairs it. (UR-012 → DR-135) -
The app no longer offers itself as an Android TV app. (This is about the
app icon on a TV device's home screen — your TV shows library is untouched.)
It advertised a leanback launcher entry without any of what makes a TV app work — no D-pad focus model,
no banner, and a missing touchscreen declaration that fails Play's TV
validation. Launching it on a TV would have landed you in a UI you could not
navigate. It can be re-declared when TV support is actually built. -
Lockscreen skip scrubs a film instead of leaving it. While a video's audio
plays in the background, the skip buttons jump 30 seconds forward and 10
seconds back, rather than advancing to the next episode. There is no "next
track" inside a film, and pressing skip to re-hear a line should not eject you
from what you are watching. Music is unchanged: skip still moves through the
queue. (UR-040, UR-006 → DR-201)
🔒 Security
-
The webview now runs under a Content-Security-Policy. It had none, so any
script reaching the web layer inherited the full IPC surface.script-srcis
now'self'with no inline or eval, and plugins and frames are refused
outright. (UR-071 → DR-198) -
The webview stops undoing the network security config. It set a blanket
cleartext opt-in by hand, along with file and content access it never used —
defeating the config that exists to block exactly that, and whose own comment
warned against it. (UR-071 → DR-199) -
The asset protocol no longer reaches the database or the credential store.
Its scope was the whole app data directory; it is now the one subdirectory it
serves. (UR-012, UR-071 → DR-198)
🐛 Fixes
- A credential store that could not be read is now recoverable. The decrypt
failure surfaced as a hard error rather than a logged-out state, so the app got
stuck instead of offering the login screen. (UR-012 → DR-135)
🔧 Internal
- CI now enforces the checks the contributor rules already required —
cargo fmt --checkand clippy — neither of which had ever run there. The
traceability gate was also raised from 50% to 82%, a floor low enough that half
the matrix could rot before it fired, and a new check fails the build on a
requirement ID that no longer exists. - Twelve requirements marked "Done" carried no implementation trace at all;
they are now tagged, and stale integration requirements that named a backend
never built have been re-scoped to the ones that actually deliver them.
Coverage moved 86% → 90%. - The Rust lint backlog is cleared (51 warnings → 0), and a flaky test that
intermittently reddened CI is fixed — it was paying a cold module-transform
cost inside a test body, not waiting on a timer.
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.8.0_amd64.deb—sudo dpkg -iWindows jellytau_0.8.0_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
-
-
JellyTau v0.7.0
StablePublish Documentation / Build & publish docs to gitea-pages (push) Canceled after 0s🏗️ Build and Test JellyTau / Run Tests (push) Successful in 21m50sTraceability Validation / Check Requirement Traces (push) Successful in 44s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 10m50sBuild & Release / Run Tests (push) Successful in 18m46sBuild & Release / Build Linux (push) Successful in 30m52sBuild & Release / Build Windows (push) Successful in 15m13sBuild & Release / Build Android (push) Successful in 31m53sBuild & Release / Create Release (push) Successful in 12sreleased this
2026-08-16 20:28:16 +00:00 | 101 commits to master since this release✨ Changes
- Native Android video is now the default. Video decodes on the device's
hardware decoder instead of the built-in web player, which is easier on the
battery and lets picture-in-picture show the video rather than the app. The
default had been held back deliberately since the picture defects were fixed,
because returning from background audio left playback dead on that path; both
blockers below are fixed and verified on a device, which is the standard this
default has been held to since it last shipped early. The Settings toggle
remains, now as the fallback to the web player, and an explicit choice still
wins in both directions — anyone who turned it off keeps it off.
(UR-003, UR-004 → DR-188)
🐛 Fixes
-
The letterbox bars stop showing things that are no longer there. With
native video on, the padding around the picture kept whatever had last been
drawn in it: the previous frame flashing on rotation, a ghost copy of the
control bar stranded at the top of the screen, each new clock digit drawn over
the one before it, and the sleep-timer and quality menus leaving their imprint
after closing. One cause under all of it — nothing painted those bars. The
window surface is opaque, and for an opaque surface Android's renderer skips
clearing the damaged region and assumes the view hierarchy covers every pixel;
the video view covers only the letterboxed rect, so the bars were the window
background's alone to paint, and enabling compositing had cleared that
background to transparent. Three earlier attempts missed because they aimed at
the window's rotation animation and at video-frame retention — which is also
why the artefact reproduced standing still, with no rotation involved.
(UR-003, UR-066 → DR-194) -
Returning from background audio brings the picture back. On the native
path, coming back from the lockscreen left a black screen: a play overlay
pinned at 0:00 and a play button that did nothing. Nothing had crashed — the
transition was simply dropped. The two render paths resume by different means,
and only one of them was performed: the web player reloads from its stream URL,
while the native player owns no element and nothing watches that URL on its
behalf, so it has to be handed the item again explicitly. It now is, at the
position the audio reached. (UR-040, UR-003 → DR-196) -
Next Up stops repeating what Continue Watching already shows. The same
episode could occupy both home rows at once. (UR-023 → DR-197)
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.7.0_amd64.deb—sudo dpkg -iWindows jellytau_0.7.0_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
- Native Android video is now the default. Video decodes on the device's
-
JellyTau v0.6.0
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 22m57sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m50sTraceability Validation / Check Requirement Traces (push) Successful in 24sBuild & Release / Run Tests (push) Successful in 7m21s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 10m3sBuild & Release / Build Linux (push) Successful in 20m32sBuild & Release / Build Windows (push) Successful in 14m29sBuild & Release / Build Android (push) Successful in 31m5sBuild & Release / Create Release (push) Successful in 12sreleased this
2026-08-16 19:24:34 +00:00 | 107 commits to master since this release🐛 Fixes
-
Android native video actually shows a picture. It shipped once as audio
with no picture and was reverted with the compositing named as the suspect
(DR-172). The compositing was not at fault; five independent defects sat
between ExoPlayer and the screen, each able to produce that symptom alone. The
app shell painted over the video surface through a CSS rule targeting
[data-app-shell], an attribute no component had ever set in any commit
(DR-185). The poster/title card had no way to lift on a path that renders no
<video>element, so a black card covered the surface for the whole session
(DR-182). The JavaScript bridges were installed by a 500 ms tree walk that
raced the page load — and lost permanently when it lost, because the
re-injection guard then declined to retry — sosetTransparent(true)could
never arrive (DR-183). TheSurfaceViewwas never detached, leaking one per
video and leaving picture-in-picture's gate stuck open (DR-184). Verified on a
device: logcat now carriesWebView transparent = trueand
Marking media readywith video on screen, the pair the original
investigation went looking for and could not find.
(UR-003, UR-004, UR-041 → DR-182, DR-183, DR-184, DR-185) -
Play and pause reach the player that is actually rendering. Transport did
nothing on the native video path — from the on-screen tap, from the control
bar, and from a direct command invocation — while seek and skip kept working,
because those decide elsewhere. Rust routes play/pause to the webview<video>
whenever it believes one is active, and the player route mirrored element state
into that belief unconditionally, including from a ten-second progress
interval. So on the native path the frontend re-declared every ten seconds that
an element was playing when none existed, and every intent was emitted at
something that was not there. The mirror now lives whereuseHtml5Elementis
known. This also explains the flashing transport controls, since they key off
the play state that was being contradicted on every tick.
(UR-005, UR-003 → DR-193, DR-195) -
The player's controls hide themselves on a touchscreen. The auto-hide timer
was armed only frommousemove, which a touch device never fires, so the
control bar stayed over the video for the whole film. It is now armed on entry
and on every touch, and pinned open while paused, seeking, or with a menu open.
(UR-003, UR-066 → DR-189) -
The system bars go away with the player. Immersive mode had exactly one
caller — the fullscreen button — so opening a video left the status and
navigation bars painted over it until the user pressed a control most never
press. (UR-066, UR-003 → DR-187)
🔬 Internal
-
Native video presents through a
TextureViewrather than aSurfaceView. A
SurfaceView renders on its own layer outside the app window and punches a
transparent region through it, and Android's own graphics documentation warns
that overlays do not composite reliably above one. (UR-003, UR-004 → DR-192) -
Native Android video remains opt-in, and is not yet the default. Turning it
on surfaced a further unverified path: returning from background audio is
implemented only for the webview element, so playback stays dead on the native
path (DR-190, proposed). Rotation still needs device confirmation (DR-194).
(UR-003 → DR-188)
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.6.0_amd64.deb—sudo dpkg -iWindows jellytau_0.6.0_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
-
-
JellyTau v0.5.2
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 10m7sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m28sTraceability Validation / Check Requirement Traces (push) Successful in 19sBuild & Release / Run Tests (push) Successful in 7m35s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 3m2sBuild & Release / Build Linux (push) Successful in 20m0sBuild & Release / Build Windows (push) Successful in 8m36sBuild & Release / Build Android (push) Successful in 30m30sBuild & Release / Create Release (push) Successful in 21sreleased this
2026-08-13 05:48:01 +00:00 | 145 commits to master since this release🔧 Internal
- Gradle ships in the builder image instead of being downloaded per build.
The release APK job died at the Gradle wrapper step after the 11-minute Rust
compile had already succeeded, on a socket exception mid-transfer.
tauri android initregenerates a wrapper pointing at services.gradle.org, so
every Android job re-downloaded ~130MB — slow on a good day, a hard build
failure when the CDN drops the connection, and a standing violation of the rule
that every build tool already lives in the image. The sync script now repoints
the regenerated wrapper at the local distribution, parsing the version the
wrapper actually requests so a future Tauri bump logs a miss instead of pointing
at a missing file. Dev machines are untouched.
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.5.2_amd64.deb—sudo dpkg -iWindows jellytau_0.5.2_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
- Gradle ships in the builder image instead of being downloaded per build.
-
JellyTau v0.5.0
Stable🏗️ Build and Test JellyTau / Run Tests (push) Successful in 6m55sPublish Documentation / Build & publish docs to gitea-pages (push) Successful in 5m21sTraceability Validation / Check Requirement Traces (push) Successful in 15sBuild & Release / Run Tests (push) Successful in 7m36s🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 2m57sBuild & Release / Build Linux (push) Successful in 20m4sBuild & Release / Build Windows (push) Successful in 8m42sBuild & Release / Build Android (push) Successful in 30m30sBuild & Release / Create Release (push) Successful in 17sreleased this
2026-08-11 19:22:21 +00:00 | 157 commits to master since this release✨ Features
-
Android video can render on the device's own video surface. Settings →
Video Playback → Native Video (experimental, off by default) hands
decoding to ExoPlayer, which draws into a surface composited behind a
transparent WebView, with the player controls layered on top of it.The backend had reported "this platform has a native video surface" on Android
all along, but the frontend threw that answer away in two separate places, so
the path had never actually run. Both are lifted. The setting can only ever
suppress the backend's choice, never override it upward: turning it off
forces the web player even where native is available, and turning it on does
nothing on platforms whose backend never offered it — Linux cannot composite
behind its webview, so it stays on the web player either way.Verified playing on a physical device. Still unverified: the mini-player
transition, audio-track switching on the native path, and whether hardware
decoding measurably improves battery or CPU — so the toggle stays off by
default. (UR-003, UR-004 → DR-150)
🐛 Fixes
-
The video surface now reaches the screen at all. The player built its
video surface, handed it to ExoPlayer, and then never added it to the view
hierarchy, because the Activity reference it needed was never supplied — so
native video would have decoded to a surface nobody could see, whatever else
was fixed. This also silently disabled picture-in-picture for video, which
gated on that same never-attached surface. (UR-003, UR-041 → DR-151) -
Platform playback support is no longer guessed from the browser user
agent. The frontend re-derived "does this platform decode audio natively" by
string-matchingnavigator.userAgent— a second copy of a decision the
backend already makes, free to drift out of step with the backends it was
describing. The backend now reports its own capabilities and the frontend
consumes them. (UR-003, UR-005 → DR-152)
🔧 Internal
- The git tag is now the single source of truth for a release version. The
version lived in four files that had to be edited in lockstep, and the release
workflow rewrote exactly one of them — so a tagged build produced an installer
named for the tag wrapped around package metadata naming the previous
release, and the Linux job, which had no version step at all, shipped whatever
happened to be committed.scripts/set-version.shnow writes all four from
one argument and every release job calls it with the tag. The Android
versionCodeis derived in the same place, guarded by tests for the property
that actually matters: it must increase monotonically and stay above the value
already installed in the field, or Android silently refuses the update.
(DR-153)
Downloads
Platform File Android jellytau-release.apk— sideload oradb installWindows (portable) jellytau.exeLinux (Debian/Ubuntu) jellytau_0.5.0_amd64.deb—sudo dpkg -iWindows jellytau_0.5.0_x64-setup.exe(NSIS installer)
Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues
Downloads
-