byob - Bring Your Own Binge version history - 25 versions
byob - Bring Your Own Binge by Joe
Be careful with old versions! These versions are displayed for testing and reference purposes.You should always use the latest version of an add-on.
Latest version
Version 6.8.63
Released May 4, 2026 - 84.72 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: pausing the popup briefly triggered an internal state resync that flipped the ready count from "1/2" to "0/2 needs to hit play" until you refreshed the byob page. Sync itself was always fine — only the status display was wrong. The background now tracks ready tabs alongside open tabs and includes both in the resync payload, so the server can re-assert readiness symmetrically instead of half-rebuilding the state.Source code released under MIT License
Older versions
Version 6.8.54
Released May 2, 2026 - 83.1 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: extension popup sometimes got stuck on "connecting" — the page placeholder stuck on "Waiting for external player…" — when the background channel happened to be reconnecting at the moment the video hooked. The hook event was dropped silently and never retried, so the popup never received its initial sync state. Now the popup re-requests sync once the channel is ready, and the background tracks the hooked tab locally even before the channel is up.Source code released under MIT License
Version 6.8.52
Released May 2, 2026 - 82.68 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: closes the last two paths where "ExtensionUser" could still slip into the activity log — the background channel surviving a refresh with the old auth token, and the content script racing the page's token-update event. Background now reconnects when it notices a new token, and the content script waits for the live token before announcing itself. Combined with the previous fixes, all paths now land on your real username.Source code released under MIT License
Version 6.8.51
Released May 2, 2026 - 82.21 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: actual root cause of the "ExtensionUser" ghost — the auth token sent by the page to the extension was being generated with the wrong user_id (the session-only one, not the per-tab one), because the corrected version was hidden inside aphx-update="ignore"subtree and never reached the DOM. The page now pushes the live token directly after connecting, so the extension joins as the right user and the button label finally tracks the popup correctly.Source code released under MIT License
Version 6.8.50
Released May 2, 2026 - 82.21 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: rewrote popup tracking to use the owner's user_id directly instead of the username-based system. The "Focus / Open Player Window" button now reads a server-pushed boolean derived from a stable user_id check, not a string comparison against a stale dataset attribute. Eliminates the whole class of bugs we kept patching (stuck "Focus" labels, "ExtensionUser" ghosts, post-rename inversions). Refresh should now flip to the right label instantly.Source code released under MIT License
Version 6.8.48
Released May 2, 2026 - 81.94 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: the extension was joining the room as "NeatEagle13" (or whatever your auto-generated session name was) instead of your renamed username. Root cause was a staledata-usernameattribute being shipped from the page to the background on every action — the signed auth token already pins the connection to your session, so the username field is dropped entirely and the server resolves your real current name from the token. Should also fix the stuck "Focus Player Window" label on refresh as a side effect.Source code released under MIT License
Version 6.8.47
Released May 2, 2026 - 81.83 KBWorks with firefox 140.0 and later, android 142.0 and laterFix (real root cause this time, confirmed by the activity-log screenshot showing "ExtensionUser joined"): on quick refreshes, the extension's background channel could join the room before the byob page had registered the user, so it fell back to the literal "ExtensionUser" name and ended up tracked as a separate human from "joe" — which is why the placeholder button stayed "Focus" no matter how many resyncs fired. Server now retroactively heals the username when the byob page lands, so the ext peer always matches its owner.Source code released under MIT License
Version 6.8.46
Released May 2, 2026 - 81.8 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: refreshing the byob room now shows "Open Player Window" instantly when no popup is open, instead of briefly flashing "Focus" while server state catches up. The button label is now gated on a per-tab session flag, so the dance with the server happens in the background instead of being visible.Source code released under MIT License
Version 6.8.45
Released May 2, 2026 - 81.8 KBWorks with firefox 140.0 and later, android 142.0 and laterFix (real root cause this time): when the background service worker had been suspended, the socket was dead and the resync request silently no-oped — the stale "Focus Player Window" label survived every refresh, and you couldn't click "Open" to recover. The byob page now hands the background the room/token alongside the request, so it can re-establish the connection and push the resync. Should finally clear the stuck label on plain refresh.Source code released under MIT License
Version 6.8.44
Released May 2, 2026 - 81.19 KBWorks with firefox 140.0 and later, android 142.0 and laterFix (real follow-up to 6.8.43): plain refresh now actually clears the stuck "Focus Player Window" label. The previous attempt fired its resync request before the extension's content script was attached, so the message was dropped on refresh but worked on back/forward (where the content script was already loaded). Moved the trigger into the content script itself so it runs the moment the script initializes, no race.Source code released under MIT License
Version 6.8.43
Released May 2, 2026 - 80.97 KBWorks with firefox 140.0 and later, android 142.0 and laterFix (follow-up to 6.8.42): the placeholder now requests a tab-state resync from the background on every mount, so a refreshed byob room actually reconciles server state — closing the stuck "Focus Player Window" label that survived page refreshes when no popup was open.Source code released under MIT License
Version 6.8.42
Released May 2, 2026 - 80.61 KBWorks with firefox 140.0 and later, android 142.0 and laterFix: "Focus Player Window" stuck after refreshing the byob room when no popup actually exists. BG now sends an authoritative tab resync on every channel rejoin, so any popup that closed while the service worker was suspended gets cleaned up server-side instead of leaving a stale entry that survives across page loads.Source code released under MIT License
Version 6.8.37
Released May 2, 2026 - 79.81 KBWorks with firefox 140.0 and later, android 142.0 and laterThe wrong-user bug had a deeper architectural cause beyond the
v6.8.36 channel-reuse race: the extension was passingusername
through as the only identifier tying its peer to the human, with
no link back to the byob session. Random usernames if dataset was
stale, collisions when two humans share a username, no way to
prove the extension peer is the same person as the byob page.
Fix: the signed extension token now encodes{room_id, owner_user_id}instead of justroom_id. OnExtensionSocket.connect/2, the extension's user_id is derived
deterministically as"ext:" <> owner_user_id— provably the
same human's session, immune to renames, no username-as-identity
dependence. The owner is also exposed in socket assigns so the
channel can look the owner up inRoomServerstate.Source code released under MIT License
Version 6.8.36
Released May 2, 2026 - 79.81 KBWorks with firefox 140.0 and later, android 142.0 and later• Extension was joining the room as the wrong user.
When opening a new player window, the BG was reusing a stale
channel from a previous session that had been joined under
the previous user's name — every play/pause/seek/window-close
event for the new popup got attributed to that ghost identity.
Fix: synchronously tear down the stale channel + socket
before opening the new popup, so the new window joins fresh
as the correct user.Source code released under MIT License
Version 6.8.35
Released May 2, 2026 - 79.81 KBWorks with firefox 140.0 and later, android 142.0 and later• Extension was joining the room as the wrong user.
When opening a new player window, the BG was reusing a stale
channel from a previous session that had been joined under
the previous user's name — every play/pause/seek/window-close
event for the new popup got attributed to that ghost identity.
Fix: synchronously tear down the stale channel + socket
before opening the new popup, so the new window joins fresh
as the correct user.Source code released under MIT License
Version 6.8.33
Released May 2, 2026 - 79.15 KBWorks with firefox 140.0 and later, android 142.0 and later• Previously, opening multiple
Crunchyroll videos in succession (or having a stale opener
entry from a previous session) could make the extension adopt
the WRONG room's identity — showing join/leave/window-close
events under a different person's username. The Firefox URL
fallback now picks the freshest matching pending open and
prefers exact-URL match over hostname match.Source code released under MIT License
Version 6.8.32
Released May 2, 2026 - 78.83 KBWorks with firefox 140.0 and later, android 142.0 and later• Fixes Firefox external-window close detection. The "Open Player
Window" button label sometimes stayed on "Focus" after the popup
was closed because Firefox MV3 skips chrome.tabs.onRemoved for
popups closed via their own window close button — only
chrome.windows.onRemoved fires. Added a windows.onRemoved
fallback that walks hooked tabs and notifies the server when
any went missing. Diagnostic logs on all close paths.
• Connected clients in the byob "Stats for nerds" panel now show
one row per username (your byob.video tab and your extension
tab collapse into a single row instead of showing as two
separate peers).
• "Waiting for room…" pill while a new video loads. Previously
the YouTube embed sat on a black frame for a few seconds with
no visual cue during the ready-then-play handshake.
• Live-stream banner in Stats for nerds. When the current media
is a live stream (YouTube live, Twitch), the panel now shows a
"LIVE" badge with the explanation that position-based sync is
disabled — drift / seek metrics aren't meaningful for live
content.
• URL parser accepts schemeless URLs. Pasting
www.youtube.com/watch?v=… or youtu.be/… (without https://)
now works.
• Bottom-right "Syncing" pill picks up the byob brand purple
(instead of generic dark) and the copy is "Syncing" rather
than "Re-syncing" everywhere.Source code released under MIT License
Version 6.8.27
Released May 2, 2026 - 78.22 KBWorks with firefox 140.0 and later, android 142.0 and later• Fixes: Open Player Window now works on Firefox.
The previous build relied on sender.tab.openerTabId to link the
new player window back to its byob room session, but Firefox
MV3 doesn't set that field for windows opened via window.open()
from a content script (Chrome does). The new tab couldn't claim
its session, the content script stayed dormant, and no byob bar
/ sync ever appeared.
Now the background script falls back to matching the new tab's
URL hostname against any pending "open external" request from
the byob room when the openerTabId path is unavailable. The
content script also passes its own URL explicitly as a backup.
• Better diagnostic logging in the background and content
consoles for the activation handshake (claimedFrom = opener |
url | managed | none) so future activation issues are easier to
triage from about:debugging.Source code released under MIT License
Version 6.8.23
Released May 1, 2026 - 77.44 KBWorks with firefox 140.0 and later, android 142.0 and laterv6.5.43 → v6.8.23
Full rewrite of the room-sync engine.
• Server-authoritative sync. The extension measures drift, ships
it to the server, and executes the pre-computed seek targets
the server pushes back — no more local guessing.
• Adaptive seek-latency learning. Each sync seek measures how
long the player took to resume; the server uses that to
pre-compensate the next one so a single seek usually lands
on target.
• Per-peer personalised seeks. When someone scrubs, each peer
gets their own pre-shifted target so everyone lands together
instead of triggering a cascading correction loop.
• Ready-then-play on new videos. The room holds at paused while
every client loads, then everyone starts in lock-step — no
load-delay drift. Autoplay-blocked tabs are released from the
hold on player-ready so they don't strand the room.
• Quiet pause + no seek dance. Paused tabs stop reporting fake
drift; the room clock freezes for 5 s after a user seek so a
slow originator can't drag everyone else into re-seeking.
• Faster cascade convergence. Drift reports 2 Hz, cooldown ladder
500 ms / 1 / 2 / 4 / 5 s, immediate post-seek measurement.
• Live content (YouTube live, Twitch) skips position-based sync.
UX
• Compact "Re-syncing…" pill in the player corner instead of a
full-screen dim, with stickiness across cascading seeks.
• Stats for nerds revamp: per-peer drift sparklines, multi-peer
drift chart, correction-bands diagram, learned-seek-lag column.
• Tab-title notification badge while backgrounded.
Several iOS / autoplay / clock-sign / panel-flicker fixes.Source code released under MIT License
Version 6.5.43
Released Apr 28, 2026 - 76.39 KBWorks with firefox 140.0 and later, android 142.0 and laterWhen two videos were queued behind a playing one, finishing the current would intermittently skip the first in queue and play the second. Reproducible if a second tab was backgrounded while the first played to its end: the throttled tab's 500 mssetIntervalwould fire late, push a stale:video_endedafter the queue had already advanced, and the server would happily start a second 5 s countdown — so B played for ~6 seconds before being kicked over to C.
The server-side validation was matching by queue index, butcurrent_indexis always 0 after each advance, so the check was effectively a no-op. Switched both the extension and the in-page player to send the server-assigned item id with every end-of-video push; server now rejects pushes whose id doesn't match the currently-playing item.Source code released under MIT License
Version 6.5.42
Released Apr 28, 2026 - 76.18 KBWorks with firefox 140.0 and later, android 142.0 and later6.5.42 — Live content support (YouTube live, Twitch)
Live streams used to break the time-based sync: the server-pushed seek events would knock peers off the live edge, drift correction kept fighting the player's own live management, and end-of-video detection never fired because live duration grows with wall-clock time. Twitch in particular was unusable.
The extension now auto-detects live vs VOD from the hooked<video>element (video.duration === Infinity/NaNis the HLS live signal), tells the server, and disables time-based reconciliation while live. Only play / pause continue to sync between peers — that's the only state a live stream actually shares. Detection is bidirectional: when a broadcast ends and duration stabilizes, the extension flips back to VOD mode automatically and the queue advances normally.
No new permissions. No URL allowlist changes. The detection runs on the same<video>reference the extension already has hooked.
6.5.41 — Only hook tabs opened from a byob room
Previously the content script's activation gate read achrome.storage.localconfig keyed by URL: any tab landing on a matching URL within 30 minutes was claimed by the extension. A stale entry from an earlier byob session could activate sync on a Crunchyroll tab opened by a different tool — even when the user wasn't in any byob room at the time.
Replaced the URL-based handoff with per-tab background-script tracking. The byob.video page asks the extension to mark itsopenerTabId; the new tab's content script then asks the BGbyob:check-managedand only activates if itsopenerTabIdmatches a recently-recorded mark from a real byob.video tab.chrome.tabs.onRemovedcleans up when the tab closes; long-lived state lives inchrome.storage.sessionso service-worker restarts don't lose it mid-session.
Net effect: stale state can no longer leak across tabs, and only tabs the user explicitly opened from a byob room ever get sync injected.
6.5.40 — Drop unusedtabspermission
Thetabspermission was added in 6.5.30 alongside the popup-focus self-heal path. That code path callschrome.tabs.get(tabId)but only readstab.windowId— a non-sensitive Tab property that is available without thetabspermission. None of the otherchrome.tabs.*calls in the service worker (onRemoved,remove,update) requiretabseither, and no code path readsurl,title,favIconUrl, orpendingUrlfrom a Tab object.
Permission removed from bothmanifest.jsonandmanifest.firefox.json. No functionality changes.Source code released under MIT License
Version 6.5.30
Released Apr 25, 2026 - 73.93 KBWorks with firefox 140.0 and later, android 142.0 and laterFixed- "Focus Player Window" button stuck after the popup actually closed. If Chrome / Firefox suspended the extension's service worker while the player popup was being closed, both
port.onDisconnectandchrome.tabs.onRemovedcould fire while the worker was paused and miss the close. The server kept thinking the user had a popup open, so the button on byob.video stayed on "Focus Player Window" forever and clicking it tried to focus a tab that no longer existed. Thebyob:focus-externalhandler now verifies each tracked tab viachrome.tabs.getbefore focusing — any entry whose tab no longer exists is dropped, and avideo:tab_closedis sent to the room so the button flips back to "Open Player Window" and the next click opens a fresh popup.
Unchanged- No new permissions, no new host matches, no new data collection.
- Same content scripts (
<all_urls>for the sync engine,*.crunchyroll.comfor the Bitmovin page-world bridge). - Privacy posture identical to 6.5.19 — all data flows are between the user's browser and the user's byob room server only.
Source code released under MIT License
- "Focus Player Window" button stuck after the popup actually closed. If Chrome / Firefox suspended the extension's service worker while the player popup was being closed, both
Version 6.5.19
Released Apr 25, 2026 - 73.7 KBWorks with firefox 140.0 and later, android 142.0 and laterThis release rolls together everything since 5.0.2 (66 patch releases + 4 minor + 1 major):
New features- Set room to this page. When your tab leaves the room's video (autoplay to next episode, manual nav), a persistent toast offers Back to room video (reload the room URL) or Set room to this page (redirect the room to what you're watching). Other users' extension tabs follow automatically on third-party → third-party.
- Tab reuse between external sites. The popup stays open and navigates in place when the room moves between sites (Crunchyroll ep 1 → 2) — no more close-and-reopen.
- Queue-finished UX. Tab no longer slams shut when the queue ends; sync bar flips to "Queue finished" and you keep browsing.
- Embed-blocked YouTube fallback. Age-restricted / embed-disabled videos get Open in player window that launches the popup with full room context preloaded.
- SponsorBlock skip toast with Undo on the main player.
- Toasts stack instead of overlapping, on both the main page and the in-page sync bar.
Sync engine- Adaptive drift offset. Each client learns its structural playback latency and treats it as neutral, so clients with different baselines converge on the same wall-clock moment.
- NTP-style clock sync everywhere. Drift correction with rolling median, direction-stable hysteresis, hard-seek with mini-resync confirmation.
- Bitmovin API on Crunchyroll instead of
<video>.currentTimewrites that wedged the MSE pipeline. - 1.5 s grace period before honoring a leave. Brief socket drops no longer pause the room or spam left/joined toasts.
- Hooking gated on URL match. Browsing to the next episode while one's still playing can't corrupt room state.
- Server-authoritative popup state. Focus / Open player window reads the room's per-user ready-count instead of
WindowProxy.closed(YouTube's COOP makes it lie). - YouTube end-card Replay now cancels the autoplay countdown.
Polish- Username + truncated extension ID in the Details for nerds panel.
- Smart Forget cleared popups — only shown when there's actually a dismissed dialog.
- YouTube URL matching collapses
/watch?v=…&list=…,youtu.be/…,/shorts/…,/embed/…to canonical/watch?v=ID. - Per-tab user IDs so a single browser with two app tabs counts as one human for ≤1-user pause.
Permissions- Adds
tabs— used to detect popup closes reliably (chrome.tabs.onRemoved) and to focus an existing popup (chrome.tabs.update+chrome.windows.update). No content inspection.
Privacy unchanged- No analytics or fingerprinting. Extension presence is only signalled to byob.video / localhost / pages that explicitly identify themselves as the byob app via a root attribute.
Per-version breakdown: <https://github.com/joegoldin/byob/blob/main/CHANGELOG.md>Source code released under MIT License
Version 5.0.2
Released Apr 23, 2026 - 58.7 KBWorks with firefox 58.0 and laterSummary of changes since v4.0.1:
Sync Engine
- Reverted to proven v3.6.3 suppression-based sync. The v4.x reconcile loop caused issues on DRM-heavy streaming
sites.
- 250ms drift tolerance with proportional playback rate correction (0.9–1.1x). Hard seek for >3s drift.
- 1s correction interval for tight sync between clients.
- Follower mode: Joining clients are read-only until stable (3 consecutive ticks matching server state). Prevents
join process from disrupting existing clients.
- Deterministic seek protection: Stale server corrections ignored until server confirms user's seek position. No
timer-based suppression.
- State-change-only filter: Only play/pause events that change state are sent to server. DRM transitions that
match current state are silently dropped.
- Auto-play on join: Tries play() on incoming play command even during gesture-required state. Syncs immediately
if browser allows.
Ended Detection
- Position-based: Checks position >= duration - 3s every 500ms. Replaces unreliable browser ended event that
third-party sites don't fire reliably.
Ready Count
- Sent after follower mode exits (client proved stability), not on first sync.
- Capped to users with open tabs. Properly decreases when tabs close.
- Stale disconnected users cleaned on rejoin.
Tab Management
- Extension tabs close when queue advances after autoplay countdown or queue ends.
Sync Stats Panel
- "Details for nerds" in room settings: per-client drift (ms, color-coded), server position, play state. Live
updates.
Infrastructure
- All innerHTML replaced with DOM creation (AMO compliance).
- Persistence crash recovery for incompatible saved data.
- Computed position on sync (fixes late-joiner mismatch).
- Connection cooldown prevents reconnection storms.
- Sync correction interval reduced to 1s.
- Video element replacement guard prevents position corruption.Source code released under MIT License
Version 4.0.1
Released Apr 22, 2026 - 59.94 KBWorks with firefox 58.0 and later- Buffering overlay fix: Overlay never appeared on third-party sites because the video runs in an iframe but
the overlay only renders in the top frame. Added local buffering relay from iframe → service worker → top
frame for instant overlay display. - Buffering field forwarded: Service worker was stripping the buffering field when relaying video state to the
server. Other clients never received buffering notifications. - Buffering clear messages: Video canplay and command guard resolve now immediately send buffering:false so
the overlay clears promptly.
Source code released under MIT License
- Buffering overlay fix: Overlay never appeared on third-party sites because the video runs in an iframe but