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
| Effort | One parameter, then a few lines of JS |
| First results | Immediate |
| We still use it | On 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=1andmodelName, the widget only shows the requested model, and displays a “private session” or “offline” message otherwise. - Adding
playerIdto the widget URL enables a postMessage API: the page can sendplay,pause,mute,unmute,setVolume,fullscreenandgetCurrentState, and receives events such asready,playanderror. - Sending
unmutebefore the Stripchat Player has started playing makes the video freeze on mobile browsers; unmute about one second after the firstplayevent. - 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 status | Without strict | With strict=1 |
|---|---|---|
| Public show | Plays her stream | Plays her stream |
| Private or group show | Plays another model | “Currently on private session”, link to her room |
| Offline | Plays another model | “Currently offline”, link to similar models |
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:
- Let the player start muted.
- Wait for the first
playevent, then about 1.2 seconds more. - Send
unmuteonly if the visitor asked for sound. - If a
pausearrives right after yourunmute, the browser refused: sendmutethenplay, 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
| Parameter | What it does | When to use it |
|---|---|---|
volumeControl=0 | Hides the widget’s own speaker icon | When a link covers the player: otherwise visitors click the speaker and leave for the platform |
hideModelName, hideLiveBadge | Remove the name and the live badge | When your page already shows them |
posterUrl | Image shown before the stream starts | Avoids a black box while loading |
p1, p2 | Custom tracking values, recorded in Stripcash stats | To 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/modelsfeed) 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.
