Repository navigation
Releases
genrewatch for Fire TV 1.0.0
The first Fire TV build of genrewatch: a leanback WebView shell for genrewatch.com.
- Package
com.genrewatch.tv1.0.0 (versionCode 1), minSdk 22 (Fire OS 5), target 34 - Signed with the release key in vault
profullstack/genrewatch-firetv--signing— cert SHA-2565bea52f64d592bc793dc697a018a4275fae110672cd4bf3f87ff6f064bf7253b - APK sha256
276d8afbce2488c6433b017990ab5122c07a3d599420b6ba80b4e596cf4b70c8 - The D-pad drives the page through
assets/tv.js; the Menu key searches/search?q= - Icons and banner are the site's own artwork from
apps/web/public - Verified on an Android TV (API 30) emulator
Shipped alongside the sRGB fallbacks for the site's oklch() palette, without which the page renders black-on-black in a Fire OS WebView.
genrewatch for Android 1.0.0
The first Android build of genrewatch: a WebView shell for genrewatch.com.
- Package
com.genrewatch.app1.0.0 (versionCode 1), minSdk 24, targetSdk 35 genrewatch.aabis the Play bundle;genrewatch.apkis for sideloading and testing- Signed with the upload key in vault
profullstack/genrewatch-android--signing— cert SHA-2567cd465b6dd22959657acf9df9e0499b89ca3568353505324c916f96e4e5013f8. Play App Signing holds the real signing key once enrolled, so this one is recoverable - AAB sha256
da19269e56b39bed9df9b2460b7cea8f5b7a7d967c39fcef75f113d9e23db576 - Verified on a phone emulator (API 30, 1080x2280): installs, launches, holds focus, no crash
Earns its place next to the website: genrewatch.com App Links, system Back through page history, working file inputs, getUserMedia bridged to Android's permission prompt, full-screen video, offline screen.
Not on Google Play yet — the Play Console account (anthony@profullstack.com) still has to clear its verification and tester gate.
v0.13.0: the line provider on @profullstack/stream-providers
The ArgonTV reseller client comes from @profullstack/stream-providers (#73) and authenticates with X-ApiKey (the bearer was refused).
v0.10.0 — films play through the house player
Films now play through @profullstack/player's native engine (attachSource, kind mp4) from the vendor-ads.js bundle the film path already loads. No demuxer is fetched for a film and iPhone native MP4 playback is unchanged. Every playback path on genrewatch is now the house player. #58
v0.9.0 — live channels play through the house player
Live channels deliver through @profullstack/player 0.16.0 (attachSource, transport stream engine). vendor-mpegts.js and the direct mpegts.js dependency are gone; the bundle is vendor-player-ts.js. Proxy status messages and stop/retry rules unchanged; films and breaks unchanged. #57
v0.8.1 — the push key is served, not baked in
Web Push now runs on @profullstack/notifications: the server serves its public key at /api/push/vapid-public-key, the browser says the real reason push is unavailable, and web-push is gone. (#37)
v0.8.0 — copy the address of the thing you are watching
Three buttons sit beside a title on your own list, and every one of them removes itself on some device.
VLC and Infuse are deep links. vlc-x-callback:// and infuse:// are the schemes those two apps register, so a tap on a phone opens the app already on the file. On a desktop they mean nothing: VLC opens, is handed the whole scheme string as its media address, and reports that it cannot open it. So app.js takes both away there, because a button that looks live and then fails is worse than no button at all.
The .m3u download is the mirror image. Right on a desktop, where it downloads and opens and plays. A trap on iOS, where Safari either offers to save the playlist or follows it and offers to save a .ts file, and neither plays. So that button goes on a phone.
Add the two rules together and the result is the thing nobody had noticed. On any given device one of the two ways out of this site is already gone. A desktop reader has a download. A phone reader has two deep links. Neither has ever had the address itself, and the address is exactly what you need if the player you want is not one of the two we can name: mpv, ffmpeg, a set-top box, a Plex box, VLC on a second machine. Until now the answer for all of those was to download the .m3u and open it in a text editor.
There is a Copy URL button now, in two places. Beside the player buttons on a row, where it hands over the same string the VLC link beside it already carries. And under the inline player once something is playing, because by then the row has scrolled off on a phone and the video is fullscreen on a desktop, so this is a second place to press the same control rather than a second control.
The rule that shaped both is the one that already governed VLC: the address IS the credential. On a line you bought, the stream URL contains your own provider username and password, which is why the VLC button may hand it over at all. But a title on our managed line is our reseller credential rather than yours, and a title from somebody else's shared list is their subscription. Those rows have never carried VLC, Infuse or a download, and they do not carry Copy URL either. The new button appears under exactly the condition the old three do and disappears under exactly the condition they do.
The wording follows the row, because this catalogue is mostly files rather than channels: a film says "copy the address of this file", a live channel says "stream".
One last case. navigator.clipboard does not exist outside a secure context and can be refused even inside one. A dead button that swallowed the address would be the worst of the possible endings, so a refusal drops the URL into a field, selected, one keystroke from copied.
Ported from tipoffwatch v0.19.0, where the same change also covers the multiview grid and the news channel player. This site has neither, so this is the part that applies. genrewatch shares no git history with tipoffwatch at all, so shared work arrives here by hand rather than by merge.
Also in this tag, released here for the first time
The last tag was v0.3.0, so everything below shipped to production on merge but was never tagged. Listed by its own commit rather than described second-hand.
- 0.7.1 — Show the password sign-in form instead of folding it away (#29)
- 0.7.0 — Every line gets a card, not just the first (#28)
- 0.6.0 — Say what else we run, in every footer (#27)
- 0.5.0 — Say where a film can be watched, and mean everywhere (#26)
- 0.4.0 — More than one provider per reader (#25)
- Store a list of any size, instead of guessing how big one can be (#24)
- Restart a container whose pool has stopped serving (#23)
v0.3.0 — /diag
A page that reports what a browser can actually do, measured on the device rather than guessed from its name.
A Fire TV shows no notification toggle here and on the sibling brand, and nothing published about Silk settles why: its Chromium version varies by device and by year, and Amazon does not document whether web push exists on it at all.
/diag reports the push manager, which is exactly what hides that toggle; MediaSource and every codec the player might need; both kinds of picture-in-picture; and whether the engine can even parse the syntax app.js is written in. It logs what a remote sends, key by key. It never requests a permission, so opening it cannot put a prompt on a television, and it shares no script and no stylesheet with the pages it measures.
Open it on the device and press Send; the report lands in the server log.
v0.2.0 — Live TV passes
A pass buys time on a line of our own, and that line arrives as a managed list, so the title page, the subject page, the probes and Play all work on it unchanged.
A week is a dollar, a month is ten, a year is forty-eight and is sold as four a month. Every price is configuration, read by the page and the checkout from one function.
What a managed list withholds is the point. The address is never revealed, the rows offer no VLC, Infuse or .m3u, both .m3u routes and both share routes refuse, and a stream on it needs an active pass on every start. The provider is never named to a reader anywhere.
Provisioning is explicit: after a settled payment, outside the webhook's transaction so a slow provider cannot fail the webhook, and behind a button on /live when it did not finish. The scheduled tick only ever takes lapsed lists down, handing back whatever list the reader had before.
Needs IPTV_ARGON_API_KEY and IPTV_ARGON_TEMPLATE_ID on the service before anything is on sale.
v0.1.1 — streams survive a flaky provider line
First tagged release. Everything before this shipped untagged; the version now matches package.json.
Fixed: streams that stopped after a minute or two
Three separate causes, each on its own enough to end a stream that was basically healthy. All three are ported from tipoffwatch, which hit them first.
The reconnect budget was spent by failures rather than by failures to recover. It refilled only after thirty unbroken seconds, so three hiccups inside half a minute spent the whole allowance and the entry was given up on for good — even though every restart had worked and the picture was back within seconds. It now refills the moment there is a picture.
Every refusal from the provider was final. A line that permits one connection answers 403 to the second, which is to say it answers 403 exactly when the reader is already watching — including the moment after a dropped stream, when the panel has not yet noticed the old session is gone. That arrived at the player as a dead entry. Only the statuses that mean the slot is really gone are final now; a busy line is reconnected from, and is no longer written down as a channel that does not work.
The desktop player buffered nothing and closed drift by seeking. Every gap in the provider's pacing was an underrun, every underrun a seek, every seek a rebuffer — and each hitch was a chance to spend a restart. Both screens now read ahead and neither seeks.
Full detail in #5. bun test: 690 pass, 0 fail.