OBS text to speech: make your stream speak any text
OBS Studio does not read text aloud by itself: it shows and mixes what you give it. To add a voice you give it audio, either clips you voiced in advance or a file a script voices on the fly and asks OBS to play. Since OBS 28 the obs-websocket server is built in, so a script on the same PC can control a source without any plugin.
This guide shows both ways with the free SuperClonica engine, which voices text offline on your streaming PC. We tested the script against the obs-websocket protocol: it sets the file of a Media Source and restarts it for every line.
Fixed lines: a Media Source and a hotkey
For lines you use again and again, such as “be right back” or a welcome, voice them once: superclonica --text "Be right back, grab a snack!" --voice F1 --lang en --output brb.wav. In OBS add a Media Source, pick the file, turn on Restart playback when source becomes active, and give the source a show hotkey in Settings, Hotkeys. Every time you press it, the line plays.
Any text, live: a script and obs-websocket
In OBS open Tools, WebSocket Server Settings, enable the server and note the password. Add a Media Source named TTS to your scene; leave its file empty. Then install the two packages:
pip install superclonica-cpu obsws-python
Save the script as obs_say.py:
import os, sys, wave
import numpy as np
import obsws_python as obs
from superclonica import Superclonica
SOURCE = "TTS" # the name of a Media Source in your scene
VOICE = os.environ.get("TTS_VOICE", "F1") # M1..M5, F1..F5 or a voice file from the catalog
LANGUAGE = os.environ.get("TTS_LANGUAGE", "en")
FILES = [os.path.abspath("tts-a.wav"), os.path.abspath("tts-b.wav")]
tts = Superclonica()
client = obs.ReqClient(host="localhost", port=4455, password=os.environ.get("OBS_PASSWORD", ""), timeout=5)
def save(path, audio, rate):
pcm = (np.clip(np.asarray(audio, dtype=np.float32).reshape(-1), -1, 1) * 32767).astype(np.int16)
with wave.open(path, "wb") as file:
file.setnchannels(1)
file.setsampwidth(2)
file.setframerate(rate)
file.writeframes(pcm.tobytes())
def say(text, turn):
path = FILES[turn % 2] # two files, so OBS never reads the one being written
audio, rate = tts.synthesize(text, voice=VOICE, lang=LANGUAGE)
save(path, audio, rate)
client.set_input_settings(SOURCE, {"local_file": path}, True)
client.trigger_media_input_action(SOURCE, "OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART")
for turn, line in enumerate(sys.stdin):
if line.strip():
say(line.strip(), turn)Run it with the password in OBS_PASSWORD and type lines, or pipe text into it from your chat bot:
python obs_say.py
Each line is voiced to a WAV, the TTS source gets that file, and OBS plays it from the start. The script alternates two files, so OBS never reads a file while it is being written.
Choose the voice
On the page of any voice in the catalog, paste a typical line, 30 to 100 characters, choose the language and press Voice it. In a few seconds you hear how your stream will sound, with no account. Set TTS_VOICE to one of the ten stock voices, M1 to M5 and F1 to F5, or to the path of a catalog voice file, and TTS_LANGUAGE to any of 31 languages; Chinese is not supported yet.
Keep it under control
If viewers can send text, voice only redeems, bits or donations, cap the length, filter links and slurs, and keep a mute key for the TTS source. Character voices are fan-made and fine for fun on stream within the SuperClonica terms, but never let chat speak with a voice that imitates a real person. Our Twitch chat TTS guide covers the chat side.