The Stripchat Player widget: strict=1, sound and the traps nobody documents

Stripchat logo on an admission ticket, stub reading Player widget

The Stripchat Player widget is the easiest way to put a live stream on a model page. It is also full of behaviors the documentation doesn’t mention: it can show a different model than the one you asked for, it can freeze if you turn the sound on too early, and it reports that it is playing when it isn’t. Here is what we learned by reading its code and testing it on real pages.

Our verdict

Add strict=1

EffortOne parameter, then a few lines of JS
First resultsImmediate
We still use itOn every model page

The short version

  • Without strict=1, the Stripchat Player widget replaces the requested model with another one as soon as she is in a private show, a group show or offline.
  • With strict=1 and modelName, the widget only shows the requested model, and displays a “private session” or “offline” message otherwise.
  • Adding playerId to the widget URL enables a postMessage API: the page can send play, pause, mute, unmute, setVolume, fullscreen and getCurrentState, and receives events such as ready, play and error.
  • Sending unmute before the Stripchat Player has started playing makes the video freeze on mobile browsers; unmute about one second after the first play event.
  • The Chaturbate embed has no equivalent message API and cannot be unmuted from the page.

Why does the widget show another model?

Because by default the Player widget substitutes “the most relevant” other model whenever the one you asked for is not in a public show. You load the Player with modelName=anna. As long as Anna is in a public show, everything is fine. The moment she goes private, into a group show, or offline, the widget quietly switches. Your page says Anna, the video shows someone else. Between two syncs of your model list, that can last for minutes, on every page where the model is not public.

The fix is a parameter the widget accepts even though it isn’t documented:

.../widgets/Player?modelName=anna&strict=1&userId=YOUR_ID

With strict=1, the widget only ever shows the model you named:

Model statusWithout strictWith strict=1
Public showPlays her streamPlays her stream
Private or group showPlays another model“Currently on private session”, link to her room
OfflinePlays another model“Currently offline”, link to similar models
Tested on the live widget, September 2026.

It also combines with tag, so you can keep a category filter. If you run a white label and don’t want the widget to name Stripchat in those messages, detect the state yourself (next section) and show your own “not live right now” screen.

How does the hidden message API work?

Add playerId=something to the widget URL and the iframe starts talking to your page through postMessage. Without playerId, there is no bridge at all.

// your page → the player
iframe.contentWindow.postMessage(
  { type: 'stripchat-player', playerId: 'p1', action: 'mute' }, '*'
);
// actions: play, pause, mute, unmute, setVolume ({ payload: { volume: 0.5 } }),
//          fullscreen, getCurrentState

// the player → your page
window.addEventListener('message', (e) => {
  if (e.data?.type !== 'stripchat-player' || e.data.playerId !== 'p1') return;
  console.log(e.data.event, e.data.payload);
  // events: ready, play, pause, error, volumeChange, muteChange,
  //         fullscreenChange, currentState ({ isPlaying, volume, muted, isFullscreen })
});

Two things to know before you rely on it. The play event repeats every couple of seconds like a heartbeat, so react to the first one only. And currentState is not always honest: in a private show it can report isPlaying: true while there is no video at all. A public model sends play within about a second; if you get ready and no play after a few seconds, treat the model as not live. A fatal error event with type hls means the same thing.

How do you turn the sound on without freezing the video?

Let the player start muted and only unmute about one second after its first play event. Browsers only allow autoplay when the video is muted. If you send unmute as soon as the player says ready, the widget tries to start with sound, the browser refuses, and the video freezes on mobile. Worse, the widget keeps sending play as if nothing happened, and a plain mute afterwards doesn’t restart it.

The sequence that works for us:

  1. Let the player start muted.
  2. Wait for the first play event, then about 1.2 seconds more.
  3. Send unmute only if the visitor asked for sound.
  4. If a pause arrives right after your unmute, the browser refused: send mute then play, and switch your sound button back to off.

Test this with autoplay restrictions turned on. Headless browsers allow everything by default and will hide the bug. In Chromium, launch with --autoplay-policy=user-gesture-required.

Other settings worth knowing

ParameterWhat it doesWhen to use it
volumeControl=0Hides the widget’s own speaker iconWhen a link covers the player: otherwise visitors click the speaker and leave for the platform
hideModelName, hideLiveBadgeRemove the name and the live badgeWhen your page already shows them
posterUrlImage shown before the stream startsAvoids a black box while loading
p1, p2Custom tracking values, recorded in Stripcash statsTo know which page or placement converts
  • The widget’s own fullscreen button doesn’t work on iPhone. A button on your page that puts the container in fullscreen (with a fixed-position fallback when the API is missing) is more reliable.
  • For a vertical, phone-style feed, the Stripcash aggregator feed (/app/models-ext/models, not the basic /api/models feed) gives each room’s stream width and height: a stream is vertical when its height is greater than its width. That is more reliable than a “mobile” tag.
  • Ad blockers block the widget entirely. Plan a fallback for that case: here is how we detect it.

What about the Chaturbate embed?

The Chaturbate embed has no message API and stays muted. In our tests it stayed muted with or without its disable_sound option, on mobile and desktop: the only way to get sound is the visitor clicking its own button inside the iframe. Don’t promise sound on a Chaturbate embed, and don’t place your own sound button over it.

Frequently asked questions

Why does the Stripchat widget show a different model?

By default, the Player widget replaces the requested model with another one when she is not in a public show. Add strict=1 to the widget URL together with modelName, and it will only ever show that model.

What does strict=1 do in the Stripchat Player widget?

It disables substitution. The widget plays the named model when she is public, and shows a “private session” or “offline” message with a link to her room otherwise. It works together with the tag parameter.

Can I control the Stripchat widget with JavaScript?

Yes, if you add playerId to the widget URL. The page can then send play, pause, mute, unmute, setVolume, fullscreen and getCurrentState through postMessage, and receives ready, play, pause, error and state events in return.

Why does the Stripchat stream freeze when I turn the sound on?

Because the unmute was sent before playback started. Browsers refuse to autoplay with sound, so the player stalls. Start muted, wait for the first play event plus about a second, then unmute.

Can I unmute a Chaturbate embed from my page?

No. The Chaturbate embed has no message API and stays muted until the visitor clicks its own sound button inside the iframe.

One parameter fixes the worst of it. Add strict=1 today, then take the time to wire the message API: it turns a black box into a player you actually control.