GUIDE

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.