How to Set Up an Owncast Chat Overlay in OBS Studio
Introduction
Unlike major live streaming platforms, Owncast is a smaller self-hosted solution which gives you complete control over your stream. Using Owncast has a number of upsides and downsides, but one notable downside is the loss of access to common plug-and-play tools, like chat overlays for your stream. That doesn't mean it is impossible though, it just requires a little more hands-on configuration.
Setting up a chat overlay for an Owncast stream in OBS Studio is a common question in the Owncast community, so this blog post serves to share how I have my chat overlay set up and to explain how it works.
Setting Up Owncast Chat in OBS Studio
Here's how to get a basic Owncast chat overlay set up in OBS Studio:
- Create a new Browser Source in your scene.
- In the URL field, enter
https://<your domain here>/embed/chat/readonly/where<your domain here>is replaced with the domain of your Owncast instance.- For example, for my Owncast instance, the URL is
https://stream.logal.dev/embed/chat/readonly/.
- For example, for my Owncast instance, the URL is
- In the Width and Height fields, enter the desired values to match how much space you want the chat overlay to occupy on your stream. You will probably need to adjust these dimensions to get the right fit.
- In the FPS field, enter a value which matches the framerate you have configured in OBS Studio. For example, I stream at 60 FPS, so I set the value to 60.
- Finally, copy and paste the following content in the Custom CSS field:
@keyframes fade { 0% { opacity: 0; } 2% { opacity: 1; } 95% { opacity: 1; } 100% { opacity: 0; } } body { background-color: #00000000 !important; } #chat-container { background-color: #00000000 !important; } #chat-container > div > div > div > div { background-color: #111111bb !important; animation: fade 60s forwards !important; } - That's it! Feel free to tweak the values until you get the look you want. There is no right or wrong way to do it.
How the Custom CSS Works
The CSS might look a little intimidating, but it's actually quite straightforward if we break it down into smaller pieces. Here's how each part contributes to the final result:
Fade Animation
@keyframes fade {
0% { opacity: 0; }
2% { opacity: 1; }
95% { opacity: 1; }
100% { opacity: 0; }
}
This rule declares a keyframe set named fade which will be used to control the visibility of chat messages over time. The resulting animation starts with the message completely invisible, quickly fades it in to full visibility by 2% of the animation duration, keeps it visible until 95% of the duration, and then fades it out by the end. This creates a smooth fade-in and fade-out effect for each chat message.
This rule by itself doesn't actually do anything; it just declares the keyframe set. The actual application of it to chat messages is implemented in the final section.
Transparent Backgrounds
body {
background-color: #00000000 !important;
}
#chat-container {
background-color: #00000000 !important;
}
These properties make the background of the chat completely transparent. Without it, the chat would always appear as a solid rectangle covering part of the stream, even when there are no messages.
Message Styling and Animation
#chat-container > div > div > div > div {
background-color: #111111bb !important;
animation: fade 60s forwards !important;
}
This is where the magic happens for individual chat messages. Two declarations work together here:
- The
background-colorproperty gives each chat message a semi-transparent dark gray background. This helps the text stand out while still letting some of the underlying stream content show through. - The
animationproperty applies ourfadekeyframe set from earlier. The60sduration is critical as it is what makes the percentage values meaningful.- For example, with 60 seconds configured, messages fade in almost immediately (2% = 1.2 seconds), stay visible for most of the time (until 95% = 57 seconds), then fade out in the final 3 seconds. If you change this to 30s instead, those same percentages would mean messages fade in at 0.6 seconds, stay visible until 28.5 seconds, and fade out over the last 1.5 seconds. You might need to adjust the keyframe percentages to get the timing behavior you want.