Chaturbate Enhanced Plus

Seekable live playback for Chaturbate: a DVR-style buffer of several minutes (rewind, scrub, timeshift) from a single stream, a full player bar with preview frames, zoom, speed, quality, snapshot and recording, a multi-cam viewer, hover previews, chat translation, notes, live notifications, dark theme and site cleanup. Desktop and phones. Not affiliated with Chaturbate.

These are versions of this script where the code was updated. Show all versions.

  • v2.2.2 21. 09. 2026

    ### Fixed
    - **Memory leak: every rebuilt player left four listeners, and its whole control bar, behind.** The player's box belongs to the site and lives as long as the page; our controls are rebuilt (on a phone, each time a tab comes back after a while). Each rebuild added four listeners to the box and never removed them, and each of those kept its old controls alive. Presses and moves inside the player already reach the auto-hide logic through the page-wide listener, so only "the pointer left the player" is attached to the box now, once, and it looks at whatever controls are current.
    - **Chat translation: in a busy room, or while the service held us back, new lines were silently dropped for good.** A line was ticked off as handled before it was queued, oldest first, and a full queue simply refused newcomers: every line that arrived then was marked as done without ever being translated, while the queue kept working through lines that had long scrolled away. The 2.1.7 pacing (one request a second) made a full queue more likely. Now the newest lines go to the front of the queue, and when there are more than it holds (40) it is the oldest that are let go, so what you are looking at is translated first and nothing new is lost because old lines are waiting.
    - **Picture in picture on iPhone.** Only the standard call was tried. iPhones that lack it have had WebKit's own for years; that is used as the fallback, and it toggles back. A refusal from the standard call arrives through its promise, not as an exception, so it was never reported; it is now.
    - **"Picture in picture controls" was a switch that did nothing.** Nothing read the setting. It now shows or hides the entry in the player menu (Tools) and enables or disables Alt+P, and its row says so.

    ### Removed
    - **The slim bar, completely.** It was retired in 2.1.3 by making its condition always false, which left about 80 lines that could never run: its gesture handling, the code that lifted it over the site's controls, its styles, its tier, its setting and the check for a changed setting on every player pass.
    - A bar tier that was never set any more ("tiny") and the style selectors that named it.
    - A menu class that was only ever removed, never added; a lookup in the settings panel for a note that does not exist; two variables that were assigned and never read; a one-line wrapper function; a leftover `typeof` test for a variable that always exists.

    ### Faster
    - **Dragging the resize handle** asked the browser a dozen times per frame what lies over the player. That cannot change while a finger drags, so the last answer is used during the drag.
    - **A drag on the volume slider** wrote a log line per step and pushed everything else out of the 400-line diagnostics log. Sound changes are logged in quarter steps.

    ### Looked at and left alone
    - Global listeners (6 on resize, 5 on keydown, 4 on visibility change and so on): each belongs to a separate feature and does next to nothing per event. A registry would add code without saving work.
    - The repeating timers: all stop with their player or end with the page.
    - 102 settings: every one except the picture-in-picture switch is read, most through rule tables rather than by name.

  • v2.2.1 21. 09. 2026

    ### Added
    - **Sound controls in the main settings.** The Sound tab of the settings panel now has everything the player's gear > Sound menu has: Boost, Voice boost, Even out the volume, Tip volume, "Mute when this tab is hidden" and "Only one tab plays sound", next to the two switches that were already there. They act at once, both places write the same values and each shows what the other changed, and "Reset" on the tab covers the sliders too. A note under the controls says when they cannot apply (no room open, a player whose stream is not routed through the page, a browser without a compressor).
    - **The backup now contains your saved multi cam sets** (and where the floating button sits). More > Language and backup > Export wrote settings, the multi cam room list, hidden elements, blocked rooms, notes, alerts, hidden countries and the "seen online" history, but not the named sets saved in the multi cam viewer. On import, sets are merged by name, so restoring a backup never deletes a set made since.

    ### Fixed
    - **One player with Boost or Even out the volume on, then back to the site's own stream: silence.** With one player the routed video is the site's, and it returns to the site's native stream when the script lets go (the Site pill, a fallback to the overlay player, a room that ends). A native cross-origin stream that runs through Web Audio is silence unless the element asked for it with CORS. A routed video now asks for it (`crossorigin="anonymous"`) on every way a native address can reach it. The stream server answers CORS, or hls.js could not fetch from it.
    - **A routed video can always reach the speakers again.** A media element can be given a Web Audio source node once in its life; a second attempt throws, and the element stays routed into the first. The node is now kept on the element, so a video that was unplugged (it left the page for a minute) and came back is plugged in again instead of staying silent, even when every sound option has been turned off since (as a straight pass-through).
    - **Quick repeated taps on the player's buttons no longer zoom the page.** iOS reads two fast taps as "double-tap to zoom"; tapping -10 s a few times in a row could zoom the whole page. The bar and its buttons, the centre button, the Fit button, the sound pill, the floating buttons, and the buttons of the panel and the player menu now tell the browser that taps on them are taps.
    - **The timeline's preview on a very narrow bar** is centred, instead of being pinned to the left and hanging over the right edge.

    ### Changed
    - **A stream address the server refuses goes straight to a fresh start.** On HTTP 401, 403 or 410 (a signed address that ran out, a session that ended) the player used to ask the same address five more times with growing waits, about twelve seconds of black, before it fetched a fresh address and started again. It does that at once now. A 404 on a live segment is still just retried; that is ordinary at the live edge. A fresh start loses the rewind window: hls.js cannot be given a new address without re-attaching the video, which empties the buffer.
    - **Keyboard shortcuts stay out of the way of typing more reliably.** Besides inputs and editable elements, a caret inside an editable container (checked explicitly, not only through the inherited property), a `role="textbox"` / searchbox / combobox, the site's chat input marker and a field inside a component's shadow root all count as typing.
    - The `currentTime` descriptor is also looked for on `HTMLVideoElement.prototype` (a defensive fallback; no current browser needs it).

    ### Deliberately not changed
    - **The video found for a SourceBuffer is still decided once per buffer.** A SourceBuffer cannot outlive its video: moving a MediaSource to another element closes it, and closing removes its buffers. A "still on the page?" check there would only lose the answer in the one case where it matters, a video that is re-parented for a moment while a trim comes in.
    - **`preservesPitch` is not set.** It is on by default in every browser; setting it changes nothing.
    - **The connection's `effectiveType` does not switch the data saver on.** It does not exist on iPhone, and elsewhere it is a speed estimate that comes and goes, which would flip the quality cap on a briefly slow connection. Automatic quality already handles slow networks.

    ### Good to know
    - Once sound has been routed through the page for a video (Boost, Voice boost or Even out the volume), it stays routed until that video is replaced; a browser cannot undo it. Turning the options off takes the processing out of the path, not the routing.

  • v2.2.0 21. 09. 2026

    ### Added
    - **Even out the volume** (gear > Sound, off by default). A compressor pulls loud moments (tip sounds, music, a shout into the microphone) down towards the quiet ones and lifts the whole back up, so a whisper and a scream end up much closer together. It sits before Boost; a hard limiter after Boost keeps "levelled and boosted to 300%" from clipping. Works together with Boost and Voice boost, and recordings get the evened-out sound too. While it is off, neither node is in the sound's path; with all three sound options off nothing is routed through the page at all. A browser without a compressor says so in the menu. [2.1.9]
    - **Share diagnostics.** More > Advanced has a Share button that opens the phone's share sheet (Messages, Mail, Notes, Copy) with the report. Copy and Show are still there. [2.1.6]

    ### Fixed

    #### The phone player
    - **The bar on top of the chat tabs "after some time".** The handle holds the player taller; the tabs-and-chat panel is the site's, and when the site re-renders it, it loses the mark that keeps it under the handle, jumps back to where the site wants it, and covers the lower part of the player, with our bar drawn on top. The pair (container + panel) is now checked whenever that part of the page changes and in the routine pass: a lost mark is put back, a new panel element is marked, a rebuilt container gets the handle again, and if the stylesheet rule is out-ranked the position is set inline with priority. Independently of how the page is built, the bar asks the browser what lies over the lower part of the player and sits above it; a dialog over the whole page does not count. [2.1.6]
    - **Frozen or blank picture after coming back to a tab with sound on.** A phone does not let a page start sound by itself, and coming back to a tab is not a tap. The player was un-muted again on return, its `play()` was refused, and the recovery read "paused, has data" as "waiting for a tap" and stopped. A refused start now falls back to a muted picture that does play, with the "Tap for sound" pill: right on return, in the recovery ladder, and when a sleeping player wakes. [2.1.6]
    - **A pause by the system was recorded as yours.** Opening the tab overview pauses the picture well before the page is told it is hidden; that pause counted as "paused by the viewer" and nothing was restarted on the way back. A pause only counts as yours when you touched something just before it. [2.1.6]
    - **Sound gone after mute / un-mute.** Three likely causes, all handled and logged: with one player the element is also the site's and the site may write its own "muted" back (for 2.5 s after your choice anything else is put back); shaped sound runs through an AudioContext that a phone suspends and only a tap may resume; and un-muting twice within 8 s nudges the decoder with a tiny seek, which brings a silent MSE audio track back. Every sound change is written to the log (`sound: ...`). [2.1.6]
    - **Shaped sound going silent after a tab switch.** Boosted or evened-out sound runs through an AudioContext, which a phone suspends on its own (a tab in the background, a call, Siri). Any tap on the page now resumes it; coming back to a tab tries without a tap, and if the phone refuses, the "Tap for sound" pill appears. Boost and Voice boost had the same weakness. [2.1.9]

    #### Sound
    - **The sound options stopped working after a while (one audio context per video, never released).** Every `

  • v2.1.6 21. 09. 2026

    ### Fixed
    - **The bar on top of the chat tabs "after some time".** 2.1.5 handled a player that is taller than the container the handle holds. The screenshot showed the opposite case: the container (and the player in it) held taller by the handle, and the tabs-and-chat panel back where the site wants it, over the lower part of the player, with our bar drawn on top of it. The panel is the site's; when the site re-renders it, it loses the mark that keeps it under the handle. Now:
    - the pair (container + panel) is checked whenever that part of the page changes (a MutationObserver) and in the routine pass: a lost mark is put back, a new panel element is marked, a rebuilt container gets the handle again, and if the stylesheet rule is out-ranked the position is set inline with priority;
    - independently of how the page is built, the bar asks the browser directly what lies over the lower part of the player (`elementsFromPoint`) and sits above it. A dialog over the whole page does not count.
    - **Frozen or blank picture after coming back to a tab with sound on.** A phone does not let a page start sound by itself, and coming back to a tab is not a tap. The player was un-muted again on return, its `play()` was refused, and the recovery then read "paused, has data" as "waiting for a tap" and stopped. A refused start now falls back to a muted picture that does play, with the "Tap for sound" pill; it is tried right on return, in the recovery ladder, and when a sleeping player wakes.
    - **A pause by the system was recorded as yours.** Opening the tab overview pauses the picture well before the page is told it is hidden; after 0.9 s that pause counted as "paused by the viewer" and nothing was restarted on the way back. A pause only counts as yours when you touched something just before it (our own buttons and the headset handler set the flag themselves).
    - **Sound gone after mute / un-mute.** Three likely causes, all handled and logged: with one player the element is also the site's and the site may write its own "muted" back (for 2.5 s after your choice anything else is put back); a boost or a recording routes sound through an AudioContext that a phone suspends and only a tap may resume (every choice resumes it); and un-muting twice within 8 s nudges the decoder with a tiny seek, which brings a silent MSE audio track back. Every sound change is written to the log (`sound: ...`).

    ### Added
    - **Share diagnostics.** More > Advanced has a Share button that opens the phone's share sheet (Messages, Mail, Notes, Copy) with the report. Copy and Show are still there.

  • v2.1.5 20. 09. 2026

    ### Fixed
    - **Controls over the chat tabs after returning to a tab.** The height handle holds the outer container; the player itself lives in an inner box that the site sizes on its own, and does so again when a tab comes back or a stream restarts. When the inner box came out taller than the container, its lower part (and our button row with it) ended up underneath, and on top of, the tabs-and-chat panel. Three things now prevent that:
    - the controls end at the handle, whatever size the inner box has;
    - without a height of your own, the container follows the site (it is measured again and re-pinned); with one, the site is asked to lay its player out again (the same one-pixel change that makes it follow while the handle is dragged);
    - everything is measured afresh when a tab is shown again (at once and 1.6 s later), when the stream reports its size anew, and in the routine check.
    - **Black picture after a background tab woke up (one player).** Data flowing is not a picture: after a fresh engine goes under a video that sat in a background tab, WebKit sometimes plays (the clock runs) and paints nothing. The overlay player always had a check for this at its first start; the one-player path had none, and every return to a tab is such a start. Frames are now counted: three seconds of running clock without a new frame gets a small seek first (which usually wakes the decoder), then a fresh engine, and after that the overlay player takes over for the page. A start only counts as a success (and clears the failure count) once frames are actually painted.
    - **Drawer: the gear icon was oversized when the drawer was open.** It is 18 px again, like the other buttons.

  • v2.1.4 20. 09. 2026

    ### Changed
    - **Handle: up/down resizes, left/right moves the picture, in the same drag.** No hold and no release in between. Each direction wakes up after 10 px of its own movement, so a straight pull does not nudge the other one; a diagonal drag does both. The picture still stops at its real edge, measured against the height as it changes. Holding still first is still the joystick for every direction (up and down too, for a zoomed picture). Double-tap still resets.
    - **Drawer tab is bigger** (34 x 72 px with a 20 px icon, less transparent).

    ### Fixed
    - **Drawer: the buttons overlapped the gear on the first tap.** The pill and the two round buttons are placed from the gear's box at the moment the drawer opens, and that box was still animating from "tab" to "round button". The size no longer animates, the gear keeps the tab's vertical centre, and the placement runs once more on the next frame.
    - **Controls kept coming back while rewound or paused in fullscreen** (mainly desktop, since 2.1.0). The heartbeat that keeps the site's player from rebuilding sends made-up `playing` events every 4 s; 2.1.0 treated them as playback starting and showed the controls again. Only real events count now. The same check was added to the pause/play tracking.
    - **One player: a decoder error that hls.js recovers from could leave the picture paused**, because the site's video has no autoplay of ours. It is started again unless you paused it.
    - **Handle lost after the site re-rendered that part of the page** was not put back, and a stale forced height could stay on the old container. Both are handled.

    ### Smoother
    - **Layout measuring in the routine player pass is rare now.** That pass runs after every burst of page changes, several times a second in a busy room, and since 2.1.1/2.1.2 it re-measured the player and re-fitted the bar each time. The ResizeObserver already reports real size changes at once; the pass is now a safety net that measures at most every two seconds.
    - **Fitting the bar** only re-flows the button row when the visible width or the row's contents (quality label, record timer) changed.
    - **Showing and hiding the controls:** every pointer move inside the player used to cancel and start a timer (twice per event). A move now only pushes the deadline; one timer looks at it.
    - **The per-frame timeline loop** stops while paused (paused controls stay up, so it ran for nothing the whole time) and looks four times a second at live, where the thumb is pinned to the edge. It runs every frame only while you are actually behind live.
    - **No blur behind controls over the picture.** A backdrop blur re-blurs the video under it on every frame, which is costly on a phone. The Fit button and the in-player menu drawer use plain translucent backgrounds instead.
    - **Dragging the handle** applies height and pan once per frame instead of once per touch event, does not re-measure the site's own height during the drag, and remembers which ancestors clip for two seconds instead of asking two dozen computed styles per frame.

  • v2.1.3 20. 09. 2026

    ### Added
    - **Joystick in the resize handle.** Press the handle under the player and hold still for a moment: it turns into a joystick (the grip becomes a white dot) and the picture follows your finger in every direction, as far as there is picture outside the visible area: the sides the site crops off in a tall portrait player, or anything once you are zoomed in. It stops at the edge of the picture. Release to stop; the position is kept. If the whole picture is already in view it says so. Everything on the picture itself is unchanged: swipe seeks, hold is 2x, a drag moves a zoomed picture, two fingers zoom.
    - **Drawer for the floating buttons (touch).** The four floating buttons covered the picture in one place and the chat in another. They are now tucked behind a small see-through tab on the right edge. Tap the tab and they slide out; the gear then opens the panel as before. They go back after 5 seconds or a tap elsewhere. Drag the tab up or down to move it. Setting: More > "Tuck the floating buttons into a drawer (touch)". Desktop is unchanged.
    - **"All settings..."** in the player's gear menu opens the panel.

    ### Fixed
    - **The resize handle under the player is back.** Its code never changed; what changed is the page. The handle needs the container that sits directly above the site's tabs-and-chat panel. It used to assume that this is the box the player is mounted in. On the portrait layout the player is mounted in the inner, wider-than-the-screen wrapper (the one that cut the bar off in 2.1.1), which has no panel beside it, so the handle silently never appeared. The two are now found separately: the controls stay where they are, and the handle looks up to six levels higher for the container above the panel. If none is found, the log says what it looked at.
    - Nothing is resized until the handle is dragged: without a height of your own the box is pinned to exactly the height the site gives it, which only makes room for the handle. Double-tap the handle to go back to the site's height (this also centres the picture again).
    - A tap on the floating gear that wobbled a few pixels was treated as a drag and did nothing.

    ### Changed
    - **Record is always on the bar.** The fixed layouts are replaced by a priority order. Pause, mute, LIVE, record, the gear and fullscreen always show; -10/+10, quality and snapshot are added while they fit and go into the gear menu in the order snapshot, quality, -10/+10 when they do not. On a 430 px wide phone everything except snapshot fits. The bar is fitted again when the quality label or the record timer changes its width.
    - **The site's own controls are always hidden while rewind is on.** The "site's own controls plus a slim timeline" option is removed.
    - **Zoom column:** white instead of orange, quieter when idle (38% until touched), and the slider is drawn by the script, so it looks the same everywhere instead of showing the system's grey knob on iOS. The Fit button is a small frosted rounded rectangle.
    - **Toasts on a phone in a room** appear at the top of the player instead of over the message box.
    - Pan limits are measured against what is visible on screen, so a zoomed picture can be moved all the way to its real edges in the cropped portrait layout.

  • v2.1.2 20. 09. 2026

    Portrait phones: the bar was wider than the screen. Found from a screenshot of a room page on a 430 px wide iPhone.

    > Same caveat as before: checked against a simulated page built from the screenshot's measurements, not on the live site.

    ### Fixed
    - **Pause, fullscreen and half the gear were off the screen; the timeline looked empty.** In portrait the site fills its taller player by making the video, and the wrappers that share its size, wider than the screen and centring them inside a container that clips: a 16:9 picture 307 px tall is 546 px wide on a 430 px screen. Our block sits in that oversized box, so the bar was laid out 58 px past each edge. The pause button fell off the left, fullscreen and part of the gear off the right, and the live end of the timeline (thumb, fill, "live" label) was beyond the right edge, leaving only a faint empty track. This is also the real cause of the original "fullscreen icon missing" report; 2.1.0 sized the bar from the block's width, which was the wrong width.
    - The visible part of the block is now measured (its box cut down by every clipping ancestor and by the page width) and handed to the stylesheet as four insets. The bar, the zoom column, the centre button, the stats and stream-time badges and the sound pill all sit inside the visible part; the bar's tier is chosen from the visible width.
    - The gear menu hangs from the visible part of the player, so the drawer no longer starts past the right edge.

    ### Changed
    - Touch: the timeline track and the held band are brighter, so the drag area can be found on a dark picture.
    - Diagnostics report the block's visible size and insets; the log says when and by how much the block is cut off.

  • v2.1.1 20. 09. 2026

    ### Changed
    - **Our bar is the default again, everywhere.** With one player (and with the site's own hls.js player, where only hooks are installed) the enhanced bar in its self-sizing tiers is shown and the site's own controls are hidden. One timeline, one set of buttons. The slim bar over the site's controls is still there as a choice: Rewind → Controls with one player → "the site's own, plus a slim timeline".
    - **The site's controls are found by structure, not by class name.** Anything inside the player box that holds a button, a slider or a range input, does not hold the picture, and is not a block of text is treated as a control container; the outermost such container is hidden (transparent and untouchable, never removed, so the quality menu can still be driven through it). The old class-name rules only ever matched the desktop layout. A notice with a button in it (a private-show message, say) is left alone, and everything comes back the moment the player is released.
    - **Touch: a tap is only handed to the site when it lands on something pressable** (a button, a link, a role=button, an element with a pointer cursor). Handing it to a plain wrapper over the picture made the site toggle its own, now hidden, controls while ours never got to show or hide. Desktop is unchanged.
    - The slim bar, when chosen, measures the same detected controls (their buttons and sliders, not the layer that carries them) to decide how far to lift itself.
    - What was hidden is logged ("site controls hidden: …") and marked `[HIDDEN BY US]` in the diagnostics structure dump.

    ### If the two sets of controls still overlap
    More → Copy diagnostics on that page. The structure dump shows what the site's controls are made of, and the log says what was detected.

  • v2.1.0 20. 09. 2026

    ### Added

    #### One player: rewind inside the site's own video
    - New engine ("adopt"): hls.js is attached to the site's own `

  • v2.0.4 19. 09. 2026

    A phone-focused release: the multi cam tab opens reliably, zoom and drag no longer crop the picture, and streams come back by themselves after a tab has been in the background.

    ### Fixed

    **Multi cam**
    - **Multi cam opened the plain home page on phones.** Phone userscript managers often inject late, after the site has already tidied the address, so the `?cbx-multi=1#cbx-multi` flag was gone by the time the script looked. The tab is now also recognised by its window name, a short-lived stamp left by the opener, a per-tab session mark, and the address the document was originally loaded from (the browser's navigation entry). Typed, bookmarked and shared multi cam links benefit from the last one too.
    - The multi cam page puts its flag back in the address (so a reload or a restored tab lands there again) and re-mounts itself if the site re-renders ``.
    - **Tiles stayed black after the tab had been inactive.** While a tab is frozen, the tile's player ran out of retries and was destroyed for good. Tiles now restart from a fresh stream address; a watchdog first nudges a tile that stopped moving, then restarts it with a growing delay. Tiles show "Reconnecting" or "No connection" while this happens, and retry immediately when the connection returns.
    - "Reload all" left the old players running detached in the background (data and memory). They are now shut down first.
    - A pause you asked for (tile button or the enlarged view's own controls) is respected by the watchdog; a pause the browser applied because the tab was hidden is not.

    **Theatre pop-out**
    - Same home-page bug as multi cam, same fix: the room now also rides in the hash and the window name.
    - The pop-out restarts itself when its stream dies or stops moving, and asks an offline room again once a minute.

    **Zoom and drag**
    - **A taller picture box on phones cropped the picture and the cropped part could not be reached.** Filling the box used `object-fit: cover`, which crops inside the video element; dragging then slid an already-cropped picture around and showed black. The picture is now always contain-fit and filled by scale, so the whole frame is still there and the drag reaches every part of it.
    - **"Fit" in a taller box showed a shrunken cropped picture.** It now shows the whole frame.
    - A picture rotated 90° or 270° now fits the box and pans within the right limits.
    - Pan limits come from how far the picture really overhangs the box, so streams with other aspect ratios (4:3, portrait) pan correctly when zoomed.
    - Dragging past an edge and back no longer "sticks": the picture follows the finger back at once.
    - A drag that crosses the edge of the player box is no longer cut short.

    **Inactive tabs (room pages)**
    - The startup check judged a player in a hidden tab as a dead stream ("The stream server is not responding for this room") and switched rewind off for the rest of the page. Nothing is judged while the tab is hidden any more.
    - A site player that the script had parked itself (paused, clock running) was counted as a dead stream server when the rewind player was rebuilt. It no longer is.

    **Performance**
    - The page observer treated the script's own timeline, labels and menus as page changes. Every timeline repaint scheduled a full pass (cards, chat, player, bio, transform, audio), and that pass repainted the timeline: about five full passes a second for as long as a room was open. The observer now ignores the script's own UI; a slow pass every 3 seconds remains as a safety net.

    ### Added

    - **Pinch to zoom** on the picture: two fingers zoom around the point between them and move the picture with them. Landing close to Fit or Fill snaps to it; the finger that stays down carries on dragging. The zoom is remembered per room as before.
    - **Flick momentum** when dragging a zoomed picture; an edge stops it. Off when the system asks for reduced motion.
    - **Recover the video when you come back** (Playback → Background tabs, on by default). When a tab is shown again, restored from the back/forward cache, thawed by the browser, or the connection returns, the script walks back in steps, cheapest first:
    1. restart the loaders, catch up to live if that is where you were, press play;
    2. if the picture is still not moving, rebuild the rewind player from a fresh stream address;
    3. if even that fails while the room is live, reload the page once — never more than once in two minutes, never while you are typing, and not when the room is simply offline or private.

    A video you paused before leaving stays paused, and a picture that is only waiting for a tap (autoplay refused) is not treated as dead.
    - **Exit button** on the multi cam bar: leaves multi cam and goes to the home page.
    - **hls.js mirror fallback.** If the userscript manager installed the script without delivering the `@require` (a blocked or unreachable CDN), the same hls.js 1.5.17 file is requested from the page: jsDelivr, then unpkg, then cdnjs, each pinned to the exact bytes of the npm release (SRI, sha384). A failed round is retried after a minute.

    ### Changed

    - **Multi cam button re-uses the tab that is already open** instead of stacking new ones. If the browser blocks the new tab, multi cam opens in the current tab.
    - **Phones: muted multi cam tiles sleep while the tab is hidden** and wake when it is shown; after more than 20 seconds away they restart from a fresh address. A tile with sound keeps playing in the background unless "mute in background" is on.
    - **Phones: the rewind player is not started in a hidden tab** (the browser would not play it there anyway); it starts when the tab is shown.
    - Phones: multi cam tiles keep 15 s of back buffer instead of 120 s, and the theatre window 120 s instead of 600 s.
    - On phones the theatre pop-out opens as a normal tab rather than a sized popup.
    - The site's own page is hidden underneath the multi cam page (less layout and paint work on phones).
    - "Open room" from a tile and the theatre pop-out use the current origin instead of a hard-coded `chaturbate.com`.
    - Share links carry the room list in the hash as well as the query.
    - Zoom and drag paint once per animation frame from geometry measured once per gesture; the bar, labels and classes are synced when the gesture ends. The zoom slider paints the same way while it is dragged.
    - The pan uses sub-pixel positions while moving and whole pixels at rest.
    - "Start streams in background tabs" is gentler: the site's play button is clicked at most every 6 seconds, and phones wait for the tab instead of clicking at it in the background.
    - The multi cam page respects display safe areas (notches) and does not pass overscroll to the page beneath.

    ### Notes

    - Per-room zoom values saved by earlier versions keep their meaning; no settings need to be reset.
    - The hls.js mirror fallback runs inside the page, so a strict site content policy can still refuse it. It also cannot help a manager that refuses to install the script at all when a `@require` download fails (Violentmonkey's "Error loading dependencies"). In that case the fix is on the viewer's side: open the hls.js link directly to see whether the network, a DNS filter or an ad blocker is blocking jsDelivr, then retry the install.
    - A room that was *opened* in a background tab on a phone is handled by the new code paths, but that case could not be reproduced faithfully in testing. If a room still fails to start there, turn on debug in the panel and check the `[cep]` lines in the console.

  • v2.0.3 16. 09. 2026

    ## Phones

    - **Pan:** dragging the picture now moves it. The pan clamp zeroed every drag at zoom 1, which is where a cover-fit picture (Fill) sits on phones.
    - **Tap:** a swipe, press-and-hold or pan no longer ends in a pause/resume. The gesture end ran twice on touch (`pointerup`, then `pointerleave`) and the second pass cleared the tap guard before the click arrived. The guard is now a short timestamp, so a gesture that gets no click does not swallow the next real tap either.
    - **Fit:** the picture is only cover-fit (cropped sideways, pannable) when the box is taller than the stream. A portrait or 4:3 stream in the default 16:9 box was cover-cropped top and bottom with no pan and no way back; it now shows contain-fit at Fit. Refits when the stream's aspect becomes known or changes.
    - **Zoom:** double-tap the slider or its label to reset to Fit (`dblclick` never fires on touch). The second tap can't undo the reset, and the zoom column no longer triggers page zoom on iOS.

    ## Multi cam

    - The viewer opens on the current host instead of a hard-coded `chaturbate.com`. On phones the hop to `m.chaturbate.com` dropped the query and the tab was just the home page. The flag also rides in the hash as a fallback; share links and the theatre popup use the same host.

  • v2.0.2 16. 09. 2026

    - The multi-cam **viewer button** now appears beside the launcher on every page (home, room lists, followed, profiles), with its room count. The add/remove button appears only inside a room.
    - Listing description rewritten with seekable / DVR / timeshift wording; the in-file changelog block removed in favour of the page's history section.

  • v2.0.1 16. 09. 2026

    # Changelog

    ## 2.0.1 — release
    - Audit pass: no dead settings, functions or CSS; redundant keys folded (`dvrBuffer` into the rewind window, `showHealth` and `biggerCards` removed).
    - Multi cam Layout button keeps a short label (`Auto`, `4`, `4·F`) when the toolbar collapses to icons.

    ## 1.9.x — multi cam
    - **1.9.5** Toolbar labels collapse to icons under 1400 px so it stays one row; Layout button always readable.
    - **1.9.4** One Layout menu: columns 1–8 or auto, plus "Fill the screen" as a toggle in the same menu. Fullscreen keeps the toolbar in place (F10 hides it).
    - **1.9.3** Menus placed outside the scrolling toolbar (they were opening into a clipped area). Fill respects an explicit column count.
    - **1.9.2** One-row toolbar; columns as a dropdown up to 8; "Followed" refuses the public list you get when signed out and asks before adding more than twelve rooms.
    - **1.9.1** Double-click opens a lightbox in place (with a "Pop out" button for a separate window). Number keys 1–9 give a tile the sound, 0 mutes all. Named Sets (save, load, delete). "Followed" adds your followed rooms that are online. Private/away rooms stay in the grid with a badge and reload themselves when public again. Refined floating icons.
    - **1.9.0** Text back on the ambiguous toolbar buttons; shorter room field; segmented columns; Fill-screen mode; click an empty spot to mute all; tile buttons moved top-right (open in tab, pause, enlarge, remove); double-click theatre window; separate add/remove and open-viewer buttons beside the player. Cover-cropped pictures on phones can be panned sideways.

    ## 1.8.x — phones and polish
    - **1.8.2** Zoom bar speaks in effective terms: a taller phone box reads "Fill", presets and slider follow.
    - **1.8.1** Sideways panning of a cover-cropped picture (drag no longer pauses or seeks). Multi cam: icon toolbar, "Hide toolbar" removed, resizable tiles removed, tile pause/play and enlarge buttons, multi cam button on room pages.
    - **1.8.0** Phones: drag the handle under the picture to change its height (portrait; kept by CSS so the site's layout can't undo it), rotate to fullscreen (real fullscreen when allowed, full-viewport layout otherwise), landscape lock in manual fullscreen. ↑/↓ volume. Zoom remembered per room. "Reset this tab" on every settings tab. Header description and wording refreshed.

    ## 1.7.x — settings
    - **1.7.1** Player tab split into Rewind / Playback / Controls. Seven switches merged into three choices: data saver (off / cellular or low battery / always), background tabs (keep playing / drop quality / pause), previews (off / in thumbnail / corner box). Play-triangle pill.
    - **1.7.0** Settings regrouped into titled sections with the selects placed next to the switches they belong to; "Panel" tab renamed "More". Pill with a rewind glyph and fixed width.

    ## 1.6.x — cleanup
    - **1.6.4** One pill state everywhere: green **Rewind** or grey **Site**; the engine choice is no longer shown.
    - **1.6.3** Launcher icon forced to the filled cog.
    - **1.6.2** Quality is a text button (the native select was unreadable under the site's styling). Real cog icon. Fixed a global panel rule that turned bar spans into spacers (gap after mute, fullscreen pushed off phone bars). Thumb label only when behind. Live detection asks our engine for its live-sync position. Quality page reads once per opening (was recursing where no menu exists).
    - **1.6.1** Mute button back on phones; slider unfolds on tap; nine controls fit a 440 px bar.
    - **1.6.0** Retired settings and their migration removed; mode logic reduced to three one-liners; `dropSiteQuality`, `setPlayerMode`, `PARK_RATE`, hue/blur/sepia plumbing deleted. Center play button while paused. Frame loop sleeps while controls are hidden; bar press listeners passive.

    ## 1.5.x — the new bar
    - **1.5.9** Volume slider inline after the mute button, unfolding to the right, no background.
    - **1.5.8** Volume slider rebuilt from plain elements (a native range input was being suppressed on the page).
    - **1.5.3** Panning restored: drag a zoomed picture on mouse or touch, clamped at its edges; taps still pause.
    - **1.5.2** Zoom slider anchored top-left and shrinkable so it never reaches the bar; record badge top-right.
    - **1.5.1** Zoom label updates while dragging and cycles Fit → Fill → 1.5× → 2×; record glyph styled from mount; zoom slider a true vertical control (fixes the picture sliding left on phones).
    - **1.5.0** One bar: play, ±10, mute/volume, LIVE pill, time, snapshot, record, quality, gear, fullscreen. Gear menu with Speed, Quality, Picture, Sound, Record, Tools, Room pages (bottom sheet on phones). Toolbar under the player, frame step and hue/blur/sepia removed. Zoom slider on the picture. Record button with elapsed time and a persistent badge.

    ## 1.4.x — layout
    - **1.4.1** Timeline clicks and drags work (a capture-phase stop had swallowed them since 1.0.1); 12 px hit halo; hover marker with time caption and thumbnail; live thumb pinned at the right edge; per-frame smoothing.
    - **1.4.0** One overlay layout everywhere: the block never resizes the site's player box; controls float and fade. Box-growing code, drag grip, spacer, ancestor growing, ResizeObserver and zoom crop removed.

    ## 1.3.x — one stream on phones
    - **1.3.4** Re-fit on the site's box resize (superseded by 1.4.0).
    - **1.3.3** Site's picture stays visible until our player has a frame (no black start).
    - **1.3.2** Phones: the site's native player is parked — paused, with a running clock and fed watchdog — so only one stream is downloaded. Our engine no longer snaps a rewound player back to live. A failed start no longer leaves a black block.
    - **1.3.1** Phones: site player kept playing hidden (interim fix for the JPEG fallback).
    - **1.3.0** Single **Rewind** switch; the engine is chosen from the page. Manual deep-player switch and its settings retired. One rewind-window select. P toggles rewind on the current page.

    ## 1.2.x — the site-player rewind
    - **1.2.3** Heartbeat waits for the stream to start; room changes told apart from rebuilds.
    - **1.2.2** Hand-back when switching to the site player (seek to live, re-apply quality).
    - **1.2.1** Our overlay rules can no longer hide the site's picture.
    - **1.2.0** Bar wired to the site's player: transparent overlay block, idle-hide, multi-band timeline with holes shown as gaps, thumbnails, fullscreen on the site's box, tap-through to site prompts. Dock pill shows the engine.

    ## 1.1.0 — the site-player engine
    - Hooks on `SourceBuffer.remove`/`appendBuffer` keep the site's own buffer instead of trimming it; a seek guard drops the site's live-edge snaps while rewound; a heartbeat keeps its dead-man timer quiet. New settings: site rewind and window.

    ## 1.0.1 — initial release

  • v1.0.1 15. 09. 2026

    ### Phones
    - Fixed: at load the picture could come up cropped (zoomed) because the default height was computed before the player box had its width and before the stream's aspect ratio was known. The default now falls back to the screen width, uses the real aspect ratio once the video reports it, re-fits shortly after mount, and the letterbox/zoom state is re-checked every second.
    - Minimum picture height raised from 56 px to 120 px.
    - New "Phone picture height" setting (Video tab): whole frame 16:9 (default), 4:3 crop, half the screen, or most of the screen. Dragging the handle still overrides it per room; double-tap the handle to go back. Heights dragged with older builds are cleared once on upgrade.
    - Zoom slider is short on phones (no label or value); bookmark and loop are back on the first toolbar row next to 2× and snapshot.
    - The site is poked twice after a height change so debounced layouts still move the chat down.

  • v1.0.0 15. 09. 2026

    Player
    Fixed: parking the site player by pausing it made the site's own watchdog decide it was stuck and rebuild its player, which tore the rewind player down and re-attached it ("Video seems to be stuck, refreshing"). The hidden site player is now slowed to quarter speed instead, so it keeps ticking while fetching far less video. Setting renamed to "Slow the hidden site player".
    Fixed: touch-screen laptops and DevTools device mode on a wide window got the phone layout and the 480p cap. Phone rules now need a coarse pointer or a window under 900 px, and the layout switches when the window is resized.
    Phones
    Toolbar under the player is two rows: zoom, 2×, snapshot, record and a … menu on the first; Picture, Sound and Room on the second. The … menu holds frame step, slow motion, loop, bookmarks, save buffer, picture-in-picture, stats and recording options.
    Rooms and room lists
    Fixed: the ⋯ menu on room cards opened nothing on list pages (desktop and phones) because its stylesheet only loaded together with the player toolbar.
    Phones: card buttons are larger, respond on touch before the card's own link does, and tapping them no longer starts the press-and-hold preview.
    Fixed: menus closed themselves on the small page nudge a tap causes on phones; only a real scroll closes them now.

  • v0.9.9 15. 09. 2026

    Performance release; no new features.

    - One shared ticker drives the player bar, duration badge and recording indicator instead of separate timers, and everything pauses while the tab is hidden.
    - Hover previews keep their hls.js instance between cards and only swap the source; hls.js is warmed once the page settles, so the first preview starts faster.
    - Chat translation sends up to 8 messages per request and splits the result, with a per-message retry if the service merges lines.
    - Scrub preview frames share one sprite-sheet canvas instead of one canvas per frame.
    - Chat rules (muted users, highlights, tips-only, text size) live in their own style element, so chat toggles no longer restyle the whole page.
    - Card decoration runs during browser idle time on busy list pages.
    - Duration badge only checks the host's positioning once and only writes when the text changes.
    - Version number in the panel and console now comes from the script header.

  • v0.9.8 15. 09. 2026

    ### Player
    - Smoother playback: sits a few segments behind the live edge, drifts back at 1.05× instead of stalling, prefetches the first segment, and keeps a 20 s forward-buffer reserve. The watchdog only nudges the loader after a real stall, so the stop-and-reload every second is gone.
    - Timeline redesigned: runs left → right, right edge is live, grey shows the held range, orange runs from the start of the held range to the thumb, and the time label sits on the thumb.
    - Preview frames on the timeline (every 10 s) while hovering or dragging.
    - Frame step, ½× slow motion, A-B loop with timeline markers, bookmarks with `[` `]` navigation, tip marks.
    - Instant clip can save only the A-B range.
    - Stats overlay (`I`) and an optional buffer-health readout (seconds ahead, stall count).
    - Controls auto-hide in fullscreen.
    - Media Session: play/pause/seek from the lock screen and headphones.
    - Data saver, manual or automatic on cellular / save-data / low battery.
    - Dock pill shows "Native" when the browser has no Media Source support.

    ### Controls
    - Primary bar trimmed to play, mute, volume, ±10 s, Live, quality, fullscreen, with more spacing. Snapshot, save buffer and picture-in-picture moved to the toolbar, which gained a playback group (frame step, ½×, 2×, loop, bookmark).

    ### Phones
    - Fixed: controls and toolbar under the player were not shown on some mobile layouts. The toolbar now mounts inside the player block, and an in-flow spacer pushes the chat down instead of covering it when you drag the height handle.
    - Height is remembered per room.
    - Swipe the video to scrub; press and hold for 2×.
    - Floating button starts above the browser toolbar and saved positions are clamped to the visible viewport.
    - Deep rewind pins 480p by default (switch: "Full quality for deep rewind on phones").

    ### Chat
    - Muted users, keyword highlight, tips-only view, chat text size.

    ### Settings
    - Mobile panel has a fixed height so switching tabs no longer jumps.
    - "Keep buffer for saving" renamed to "Instant clip of the rewind window", with a note explaining the difference from Record.
    - New switches: swipe to rewind, hold for 2×, full quality on phones, buffer health, stats overlay, preview frames, hide controls in fullscreen, lock-screen controls, data saver (manual and automatic), tips only, tip marks.

    ### Performance
    - Chat traffic only triggers translation and chat tools; card, bio and player work runs on other page changes.
    - Player bar caches its elements and only re-renders icons on change; the site video lookup is cached; cards are skipped when nothing about them changed; the quality watchdog stays idle while the deep player is pinned.

    ### Notes
    - Live latency is a few seconds higher than 0.9.7 by design; it buys the smoother playback.
    - Firefox for Android: Record captures audio only when the Sound menu is active.

  • v0.9.7 15. 09. 2026

    Toolbar under the player
    A new row directly beneath the player on room pages. Everything you adjust while watching lives here; the drawer keeps site-wide preferences only.
    Zoom slider (0.5×–3×), double-click to reset.
    Picture menu: brightness, contrast, saturation, hue and blur sliders (double-click any slider to reset), rotate / flip / sepia / invert, reset picture. The button tints while anything is applied.
    Sound menu: volume boost (100–400%), voice boost (rumble cut, low-mid cut, presence lift), tip volume, mute when hidden, only one tab plays sound. Boost is refused, with a note, when the stream isn't routed through the page (native HLS on iOS) or the site's player already owns the audio.
    Record: start/stop with elapsed time, R shortcut. Options: audio only, video only, low performance mode, warn before leaving while recording, keep buffer for saving, save the buffer now. Recordings include the boosted audio when boost is on and are saved automatically if you change room mid-recording.
    Room menu: watch without chat, copy stream URL, alert me when live, add/edit note, add to multi cam, hide this room.
    The toolbar follows the player into theater mode. "Show the toolbar under the player" in the Panel tab turns it off.
    Room cards
    The button strip is replaced by ▶ (watch without chat) and a ⋯ menu: hide this cam, hide country, note, alert when live, add to multi cam.
    Hidden countries have their own list with Undo in the Rooms tab and are included in export, import and reset.
    The Followed dropdown in the header gets hover previews and the same ⋯ menu.
    "random" link in the header nav opens a random live room (genders from the Multi tab; toggle in Rooms tab).
    Corner hover preview shows age · gender · location · viewers and the subject.
    Room page
    Extra room info adds: last subject when offline, private show price and minimum, premium private price and minimum, spy price (with fan-club rate), whether privates are recorded, joined date, fan club price.
    Schedule grid in the Rooms tab now counts days seen live per hour, shades cells in four levels, outlines the current hour and labels the hours (24h or am/pm). Existing data migrates.
    Multi cam
    Drag tiles to reorder; order is saved.
    Fullscreen (F11) and hide-toolbar mode (F10); the toolbar slides in from the top edge in both.
    Columns select: auto, 2–6.
    Play audio while hovering a tile.
    Hide cams in private, away or password shows.
    Remove offline, Remove all, Copy share link.
    Video
    Drop quality when the stream keeps stalling (three stalls in a minute → one step down, held five minutes).
    Start the stream in background tabs: clicks the site's "click to play" cover and starts muted; unmutes when you return.
    Look
    Hide merch links, hide surveys and feedback prompts.
    Dark theme on the older pages (fan club, supporter, followers, account forms).
    Separate card size for the "more rooms" strip under a stream.
    Panel
    "Apply recommended settings" (keeps language, launcher, lists and notes).
    Panel translation now covers the toolbar and its menus.
    Moved out of the drawer (now only in the toolbar)
    Tip volume slider, mute when hidden, one-tab sound, keep buffer for saving, picture in picture / fullscreen buttons, rotate / flip / zoom, watch without chat, copy stream URL, "alert me for this room", "add this room" to multi cam.
    Keyboard
    R starts or stops recording. ? lists all shortcuts.

  • v0.9.6 15. 09. 2026

    **Player**
    - One switch instead of two: **Deep rewind player** on (our player, minutes of scrubbable rewind) or off (plain site player). Existing settings migrate automatically.
    - New floating pill next to the gear on room pages showing **Deep** or **Site**; tap it or press **P** to switch. It follows the gear when you drag it.
    - Rewind window note now says what is really held and which quality would fit the full window, e.g. "holds ~2:19 at 2160p — 720p would hold the full 5:00". Shown in the Video tab and as a tooltip on the bar's "(max)".
    - New **Large rewind buffer** option (~400 MB instead of 120; 150 vs 60 on phones) for longer windows at high quality.
    - New **Pause the hidden site player** option (on by default): while deep rewind runs, the site's own player is kept paused so it stops fetching video underneath ours.
    - Quality dropdown arrow now sits inside the picker instead of floating next to it.

    **Sound**
    - **Tip Volume slider (0–100)** in the Sound tab drives the site's own Tip Volume setting; 0 = mute.
    - The driver that moves the site's slider was rewritten: it tries several methods and checks the site's label after each, so it now actually lands. "Check tip volume" reports the outcome and whether the slider was visible.
    - If the site's settings tab is closed, it is opened, adjusted and closed again automatically.

    **Settings panel**
    - Fixed: the panel could slide in *behind* the deep rewind player. It now sits above everything.
    - Works in fullscreen.
    - New filter box: type to search every setting across all tabs (Esc clears).
    - Remembers the tab you were last on.

    **Rooms**
    - "Add a watch-without-chat button" and "Open rooms in a new tab" now default to on (applied to existing installs too).

  • v0.9.5 14. 09. 2026

    ## 0.9.5

    ### Mobile player height (phones)

    - Dragging the grip now pushes the chat and tabs down instead of covering them. The site's outer wrappers are grown to fit the taller player and restored when the player is removed.
    - Drag up now goes all the way down to a thin strip (56px minimum, was 140px).
    - Zoom/crop only kicks in when the picture is dragged taller than the default 16:9 frame. At or below default the whole frame stays visible.
    - Dragging close to the default height snaps back to it; leaving zoom clears the pan offset.
    - Grip tooltip now mentions double-tap to reset.

  • v0.9.4 14. 09. 2026

    Settings on phones: a Section picker at the top of the panel reaches every section; header, close button and sections no longer affected by the site's mobile styles (close button was pushed off-screen).

  • v0.9.3 14. 09. 2026

    Version number is now shown in the settings panel header, so you can see which version is running on any device.

  • v0.9.2 14. 09. 2026

    Settings panel: tabs are rebuilt automatically if the site's mobile stylesheet collapses them (fixes the panel being stuck on the Sound tab on iOS). No other changes.

  • v0.9.1 14. 09. 2026

    ## Changelog

    ### 0.9.1
    - Settings panel tabs now show on iOS (the site's mobile stylesheet was hiding them).

    ### 0.9.0 — first public release
    Deep rewind player
    - Holds up to 5 minutes of the stream (2–20 configurable; the real limit depends on memory and the stream's bitrate, shown in the Video tab).
    - Player with its own controls inside the site's video area: slider across the top (full = live, drag left to rewind), back/forward 10 s, Live, quality, snapshot, picture-in-picture, fullscreen, volume.
    - Quality can be changed without losing what is already buffered.
    - Starts on auto quality, then pins a rendition once 10 s are held; falls back to auto if a rendition stalls.
    - Recovers from stream-server hiccups (retries with a fresh session; tells you when the server is down for everyone).
    - Optional: save the held video as an .mp4 (Video tab → "Keep buffer for saving", then press D).
    - Keyboard: ← → 10 s · J L 30 s · K / space pause · M mute · Home start · End live · > 2× catch-up · Q quality · S frame · ? help.

    Phones
    - Controls under the picture; drag the handle below them to zoom the picture to the height you want (double-tap to reset), drag the picture sideways to pan.
    - Double-tap the picture: left −10 s, right +10 s, middle fullscreen.

    Everything else
    - Tip-sound mute, dark theme, chat translation, hover previews, room notes, watch-list alerts, multi-cam page, ad and clutter removal — all optional, from the gear button.

  • v0.9.0 14. 09. 2026