Repository navigation
Releases: Braedennn/streamed-arena
Release list
Streamed Arena v1.7.0
The rows show up as soon as the provider publishes
The server list came late. The resolver believed the provider's "this feed is
live" flag and skipped the probe when the flag was off — but the flag is the
provider's bookkeeping, and the playlist is the truth. The app waited for the
flag, then for its own 15 s cache, then for the next 15 s poll: half a
minute of empty list after the media was already there.
The playlist is probed now whatever the flag says, the pool is remembered for
5 s while there is no media instead of 15 s, and the page checks again every
5 s instead of every 15 s. The rows appear as soon as the provider publishes,
and a feed that is up while the flag is still off is played right away.
The provider itself publishes late for some games — that part is its own, and
no app can be earlier than it.
A feed the arena does not carry
The provider names no broadcaster anywhere: not in its board, not in its
sources API, not in /get-stream-key/, not on its embed pages. A feed is
recognised by the names it does print, and the rules now live in one place
(lib/broadcasters.ts): a broadcaster's own name wherever it appears, and a
competition whose only feed that broadcaster serves.
SkyCast is the other way round — ESPN names it and the provider does not.
ESPN's watch schedule lists the games it offers as SkyCast: the college
football alternate with the picture and the crowd but no announcers.
What the provider actually serves was checked, not assumed. For the two games
ESPN offered as SkyCast, the provider's picture carried the network's own bug
(ESPN on abc, ESPN) and the audio had the commentators — the speech band
holds the same share of the energy as an ordinary broadcast. The provider
takes the primary feed of such a game.
So only a game ESPN lists as SkyCast and under no other name is refused —
with no regular listing there is nothing else the provider could be serving.
A feed the provider labels Skycast is refused outright, whatever ESPN says.
A refused feed never reaches the player: it is left out of the board, the
watch page says it is not carried here, and the pool is not polled again.
Also
- The board is read once for every match instead of once per match.
- 51 resolver checks and 28 media checks, up from 29 and 28.
The installer is Streamed.Arena.Setup.exe; its Ed25519 signature is in
Streamed.Arena.Setup.exe.sig.
Streamed Arena v1.6.10
Streamed Arena v1.6.10
The five-second stutter is finally gone for real - and your app no longer carries your video.
The last release tried to fix the stutter by telling the player that every
segment was a new timeline. That was the wrong lever, and it is what caused
the "freezes slightly every five seconds" you reported. This release removes
it and fixes the thing that was actually broken.
- The stutter is gone. v1.6.9 marked every single segment of the playlist
as a discontinuity. That switch turned off hls.js's own gap correction: the
provider cuts its segments from the running stream and stamps them with
their real timestamps, but the media inside is a fraction of a second
shorter than the playlist claims, and hls.js normally closes that gap
itself. With the switch on, every boundary left a hole - and a hole makes
hls.js nudge the playhead, which is exactly the little hiccup you saw.
The playlist is now passed through untouched, so the player closes the
gaps the way it is meant to.
Measured on the same build, the same feed and the same minute: 14
picture freezes in 150 seconds before, 0 after - and no jumps, no holes
in the buffer, no slow segments. - The app no longer relays your stream. The app's server now does the
scraping and nothing else: it reads the board, the embed pages and the
playlist, and hands the player a playlist whose segments point straight at
the provider. The provider's own doors answer any Referer and reflect the
browser's Origin header, so the video travels provider -> player directly.
Your app's server carries a couple of kilobytes of text and not a single
byte of video. The segments also arrive about three times faster
(400 ms instead of 1.1-1.5 s each), which leaves far more room in the
buffer for a busy network. - The lag numbers in the server list were wrong. Every door stamps the
same file with the same time, but each door was measured against its own
clock - and probing a door means downloading several megabytes, which takes
longer than the segment being measured is old. Whichever door was checked
last therefore looked like the laggiest one. All doors are now compared
against the freshest one, so the list tells the truth about which mirror is
ahead. - A backwards-wobbling live edge no longer drags the picture back. The
provider's playlist sometimes comes back older than the one before it. The
player believed it and seeked back with it - that is the backwards jump.
The app now keeps the newest playlist it has seen for a mirror and does not
hand out an older one.
Also in this release:
scripts/media-check.mjsis new: it checks the whole media path against a
running app - no discontinuity left in the playlist, every segment pointing
at the provider, and every segment really downloading as media with the
browser's own Origin header- the server resolver now compares mirrors by their own timestamps instead of
by the order they happened to be probed in
Verified on American Football (Notre Dame vs Navy, the busiest live grid
right now), every mirror in turn, in the browser: 0 picture freezes, 0
playhead jumps, 0 holes in the buffer, buffer 10-22 s ahead, and the
playhead running exactly in real time - 119.7 s of football in 119.7 s of
wall clock.
Upgrade: the updater picks this up within a minute of it being published.
Streamed Arena v1.6.9
Streamed Arena v1.6.9
The player no longer wakes up for a hiccup, and the picture stops stuttering.
Two things annoyed you in the last build, and both came from the same place:
the player treated every small lag like the stream had ended.
- A lag no longer un-idles the player. The control bar and the cursor used
to come back the moment the video element reported a buffering event - and a
live feed reports those every few seconds, even though the picture never
actually stops. The bar now follows your pointer, not the feed: a hiccup
leaves it exactly where it is and the cursor stays out of the way. The small
spinner only appears when a stall lasts longer than a moment, and
"Locking feed" never flashes mid-game. - The stutter is gone. The provider cuts its segments from the running
stream and stamps them with their real timestamps, but the media inside is
a little shorter than the playlist claims - every boundary drops a frame or
two. hls.js kept those timestamps for a live stream, so the gaps landed in
the picture as holes, and hls.js reacts to a hole by nudging the playhead.
That nudge was the little jump you saw every ten seconds or so. The app's
own manifest proxy now places every segment on the playlist timeline, which
is continuous by construction - the holes are gone and the picture holds
still. - Three direct servers again, and this time all three work. The
provider's "External" door answers with a placeholder picture instead of
video, so choosing it could only ever fail. It has been replaced by the
provider's mirror host, which serves the very same match. A normal feed now
lists CDN / Origin / Mirror - three working mirrors - and the resolver
looks at the first bytes of every segment, so a door that serves pictures
can never reach the list again.
Also in this release:
scripts/resolver-check.mjsgrew to 23 checks, including the new
"is this actually media?" test- every provider door is now asked with the referer that door wants, instead
of the main site's
Verified by throttling the connection until the feed really stalled: the
control bar stayed hidden and the cursor stayed out of the way through the
whole stall, the playhead never jumped, and the feed came back on its own.
Across basketball, Formula 1, cricket and RedZone the picture now plays
through without a single stutter.
Upgrade: the updater should offer this within a minute.
Streamed Arena v1.6.8
Streamed Arena v1.6.8
The provider changed its API under us - a live match said "has not started".
The provider now sends its source lists as objects ({quality, url}) instead
of plain URL strings. Every list in the app was filtered for strings, so the
lists came back empty - silently. The app then believed the match had no
pages and no live source, and told you the feed "has not started yet":
no servers, no video, while the provider was streaming the game and the board
showed it as live.
v1.6.8 fixes that, and hardens it:
- both shapes are read the same way now (
lib/sources.ts), so the next
format change on the provider's side cannot empty the lists again - a match is only called "has not started" when the per-match endpoint
and the board endpoint agree. They do not always agree, and believing
the wrong one is what produced the false "not started" - only the pages the provider marks as live are probed - a published page
that is not live has no media behind it. Fewer probes, faster resolves - the server list shows the mirrors again: three of them for a normal
feed (CDN / Origin / External), so you can pick between them exactly like
before. The list is capped so the rail stays short; the mirrors that do not
fit stay behind the scenes for automatic failover - a match that really has not started shows the "starting soon" panel
instead of the provider's own player, which only loads ads and an offline
message
Also in this release:
scripts/resolver-check.mjsgrew to 18 checks: the source-list shapes, the
duplicate-mirror case, the live-page rule and the fallback when the API
cannot be read
Verified on the packaged app: a live match shows three direct servers and
plays; the player does not restart when the pool refreshes; a match that has
not started says so and keeps checking every 15 s.
Upgrade: the updater should offer this within a minute. If you are on v1.6.0,
install manually - that release's crashed renderer blocked the in-app updater.
Streamed Arena v1.6.7
Streamed Arena v1.6.7
The server list is fixed - one row per feed, and it loads in a second.
The provider started publishing a page per quality for the same feed slot
(...1080p and ...2160p), and every one of those pages carries a token map
for all qualities. The resolver walked the pages one by one, so it probed the
same mirror several times and listed it several times: one match showed twelve
rows for six mirrors, and the list took almost seven seconds to appear.
What v1.6.7 does:
- the pool is built per (slot, quality, backend) - a mirror is never
listed twice, and the token of a quality comes from the page that is that
quality - a slot the provider has not switched on is not probed at all
- the watch page shows one row per feed - the mirror that is playing - and
says how many backup mirrors are behind it (+4 backup mirrors - failover is automatic). The other mirrors are still there; the app just fails over to
them on its own instead of listing the same feed three times - a resolve now takes about a second instead of almost seven (fewer probes,
shorter probe timeouts, more probes in parallel) - the rows keep their place when the measured lag wobbles, so the list no
longer shuffles itself on every health check
Also in this release:
scripts/resolver-check.mjs- a regression check that compiles the resolver
and verifies the candidate list against the provider's real page layout
(one candidate per mirror, no duplicate ids, dead slots left alone)
Upgrade: the updater should offer this within a minute. If you are on v1.6.0,
install manually - that release's crashed renderer blocked the in-app updater.
Streamed Arena v1.6.6
Streamed Arena v1.6.6
A match that has not started yet now says so — and starts itself.
The provider switches a match's feed on shortly before kick-off. Until it does
there is no media at all: every candidate manifest 404s. The app used to report
that as an empty, failed-looking server list ("No direct mirror answered"),
which reads like the resolver was broken rather than like a game that had not
begun.
The provider actually says what is going on, twice — live_sources in the
sources API and the IS_LIVE flag on the embed page. v1.6.6 reads both:
- the server list says "The feed has not started yet" instead of pretending
the resolver failed - nothing is probed while there is no media, so an idle watch page costs one
cheap lookup instead of two dozen requests (a resolve went from 1428 ms to
316 ms) - the page keeps checking every 15 s and flips to the direct mirror by
itself the moment the feed goes live — no reload, no clicking through the
provider's embed player - the pool is resolved for upcoming matches too, so the switch happens the
moment the provider goes live rather than when the board catches up
Also in this release:
- matches the provider hosts on a third-party site are resolved too: the app
follows the provider's own pointer to the external manifest and mirrors that
one the same way. The HLS proxy relays an approved external origin only —
loopback and private addresses are refused - the live/starting-soon signal is now authoritative in one place (the sources
API), with the embed page's flag as a fallback, so a stale cache can no
longer make a live match look like a dead one /api/serversreturns astate(ready/waiting/unknown) next to
the ranked list
Upgrade: the updater should offer this within a minute. If you are on v1.6.0,
install manually — that release's crashed renderer blocked the in-app updater.
Streamed Arena v1.6.5
- The player chrome no longer gets stuck — if you clicked a control (fullscreen, quality, mute…) the control bar could refuse to fade away, and the only ways out were to unpause/repause or click somewhere else. The cause was a
focus-withinrule on the bar: clicking a button parks the keyboard focus on it, the bar stayed "focused" and pinned itself open. Now a mouse click hands the keyboard focus back, so the idle timer works normally again and the bar (plus the cursor) disappear a few seconds after you stop moving the mouse. Keyboard users are unaffected: tabbing into the controls still keeps them open for as long as the focus sits there. The hover-revealed toolbar of the multi-view tiles had the same trap and is fixed the same way — an open channel menu still keeps its tile visible. - Your volume follows you between streams — a new stream no longer opens at 100 % (which is how a game used to start with a blast in your ears). The level you last chose is remembered and every stream you open afterwards starts there, including the tiles of the multi-view wall. Muting is remembered as well, so a muted stream stays quiet instead of waking the next one up. The setting survives a reload and a restart of the app.
Verified in the real renderer: before the fix the bar stayed at full opacity for 12+ seconds after a click with the focus parked on the button; after the fix it fades out again on schedule with the focus released, the multi-view tile toolbar releases itself the same way, and the volume carries over from one live stream to a different one and through a full reload. The six-page regression and the 90-second playback soak both stay clean — no console errors, no restarts.
Upgrade: download Streamed.Arena.Setup.exe below and run it — it replaces your install in place. Settings and favorite teams are kept.
Streamed Arena v1.6.4
- Updates are noticed within a minute now, not two hours — the app used to poll the GitHub Releases API every 2 hours, so a new release could sit unnoticed for a long time (and if the app was outdated or broken, that delay hurt). It now watches the repository's release feed every minute: that is a plain web request with no rate limit, and a published release shows up on it within seconds. Only when the feed actually changed does the app ask the Releases API for the details, because that API is limited to 60 calls an hour (and even a
304"not modified" answer counts against the limit) — so the app no longer burns its own rate limit just to be polite. A 15-minute backstop covers the unlikely case that the feed cannot be reached, and the app also checks when the window regains focus. - The popup appears the moment a release is found — it no longer waits for the ~124 MB installer to finish downloading. You get a Downloading vX.Y.Z notice right away, and when the download is finished and the signature has been verified, the popup turns into Restart to update. Downloading in the background never blocks the app.
- A failed download is retried quietly instead of being attempted over and over, and the popup says so whenever a new attempt starts.
Verified against the real repository: the feed is parsed correctly, an unchanged feed makes zero API calls, a changed feed triggers the lookup, and a full run against the published v1.6.3 announced Downloading 1.1 seconds after the check began — before a single byte of the installer had arrived — and Ready only after the payload was downloaded, size-checked and its Ed25519 signature verified.
Upgrade: download Streamed.Arena.Setup.exe below and run it — it replaces your install in place. Settings and favorite teams are kept.
Streamed Arena v1.6.3
- The player no longer restarts itself — this was the "it keeps switching and says Locking feed" bug from v1.6.2, and it had two causes. First, the stream URL carried the provider's access token, and that token rotates on every health check — so every 30 seconds the source URL changed, the player remounted and went back to Locking feed while you were watching. Mirrors are now addressed by a stable id and the token is resolved server-side per request, so the URL never changes. Second, the app re-picked the "best" mirror on every refresh, and the ranking moves constantly as the measured lag shifts — the feed under you changed because the ranking changed, not because anything was wrong. The running mirror is now sticky: it only changes when it actually fails.
- The server list stops shuffling — rows keep their position (lag is compared in 2-second buckets, previous order breaks ties), so the list no longer reorders under your cursor. The lag badges still update live, so you can see which mirror is sharpest at any moment.
- Player chrome gets out of the way — the control bar fades out after 3 seconds of pointer idle, even while your mouse is still resting on the video, and the cursor disappears with it. Any mouse movement brings both back instantly. A paused player keeps its controls and the cursor (you need them), and the quality menu holds the bar open while it's open.
- A buffering hiccup no longer looks like a failure — Locking feed is now only shown while the player first attaches to a stream. A later stall shows a quiet spinner instead of the big banner, because the stream is live, it just needs a moment.
Verified in the real renderer over a 90-second session: the playback clock runs continuously across four health-check refreshes (46s → 124s with no restart), the server rows hold their order, the controls and cursor disappear on idle, and there are no console errors.
Upgrade: download Streamed.Arena.Setup.exe below and run it — it replaces your install in place. Settings and favorite teams are kept.
Streamed Arena v1.6.2
- Every match now has a pool of servers — and they are checked before you see them. StreamFree's public API only advertises two embed pages per match and says nothing about whether they work. The app now does the work itself: it reads the real delivery matrix behind those embeds (up to four qualities × two independent source slots × three CDN backends), probes every single candidate and measures it — HTTP latency, whether the newest segment still downloads, and how far behind the live edge it actually is (the CDN stamps segments with
Last-Modified, so a segment's age is its lag). Only feeds that answer are offered, ranked best first, so a server in the list is known to work and known to be close to the action — no more dead links and no more "is it just me or is this feed 40 seconds behind?" — the lag is shown right on the button (LIVE/+3s). - Your own scraper, built in — the resolution runs on the app's server (
/api/servers), not in the browser: embed pages are parsed for their token map, manifests are fetched for every quality/slot/backend combination, and the newest segment of each is probed. A match with a healthy second source slot (a completely independent upstream feed) can yield six servers instead of two. - Playback goes direct — cleaner and faster. The app plays the raw HLS feed through its own same-origin proxy (
/api/hls/manifest,/api/hls/segment) instead of dropping you into the provider's iframe: no ad frames, no popups, no third-party scripts, and no ad-break stutter. The provider's embeds are still there as a fallback. - Automatic failover — if a feed dies mid-match, the player retries three times, then moves to the next healthy mirror on its own; the embeds are the last resort. You can also pick a specific server by hand and the app remembers your choice for that match.
- Both surfaces benefit — the watch page and every tile of the 4-screen multistream wall use the same pool, so one dead feed no longer breaks the grid.
- Built to stay up — upstream calls now run through a dedicated HTTP client with its own socket pool, hard deadlines and retries; the app server no longer degrades into hanging requests after a while (a long-running desktop process has to survive hours), and the last working server list is kept through a brief upstream hiccup instead of emptying out.
Upgrade: download Streamed.Arena.Setup.exe below and run it — it replaces your install in place. Settings and favorite teams are kept.