Twitch Chat TTS

Full source code available on Github, Working demo at tts.seanhweb.com

My friends like to stream on Twitch and use Text to Speech (abbreviated as TTS) for their chat to be able be read aloud on their stream. I noticed looking into this that there isn't much out there that is reliable and works. One of the main sites they would use likes to shut off seemingly randomly. I decided to set out on my own and create a web page that parses a specific channel's twitch chat, and then reads it out loud.

There is an open source library called tmi.js that will allow me to connect to twitch chat and start reading it.

I created a page that has a simple button and a textbox. The textbox is where you input a channel, and the button starts listening to twitch chat. Once the button is pressed, the below function is executed.

function startListening() {
  const channel = document.querySelector("#channelname").value;
  if(isAZ(channel) == false) {
    statusElement.className = "error"; 
    statusElement.textContent = "Please enter just the channel name, not the entire URL."; 
  }
  else {
    const client = new tmi.Client({
      connection: {
        secure: true,
        reconnect: true,
      },
      channels: [channel],
    });

    document.getElementById("listenBtn").textContent = "Listening...";
    document.getElementById("listenBtn").disabled = true; 
    statusElement.className = "success"; 

    var listening = true; 
    client.connect().then(() => {
      statusElement.textContent = `Connected to twitch. Listening for messages in ${channel}...`;
    });

    client.on('message', (wat, tags, message, self) => {
      writeMessage(tags, message); 
      speakMessage(message); 
    });
  }
}

This function handles listening to the chat, and executes functions when a message is sent. For now, the message is written to the bottom of the page and the mesage spoken.

function speakMessage(message) {
  const utterance = new SpeechSynthesisUtterance(message);
  utterance.volume = document.querySelector('#volume').value;
  window.speechSynthesis.speak(utterance);
}

This function takes a message received and speaks it in the browser using SpeechSynthesis. The volume is determined by a volume bar placed on the page with the ID of "volume".

function writeMessage(tags,message) {
  let div = document.createElement('div'); 
  div.className = "single-message";

  let chatter = document.createElement('span'); 
  chatter.className= "chatter";
  chatter.style.color = tags['color'];
  chatter.textContent = tags['display-name']+': ';

  let chatMessage = document.createElement('span'); 
  chatMessage.className= "messageContent"; 
  chatMessage.textContent = message; 

  div.appendChild(chatter); 
  div.appendChild(chatMessage); 

  document.getElementById("messages").appendChild(div); 
}

This function writes the message to the bottom of the page, keeping the users chat color on twitch intact.

To do's and nice to haves

For now, this works perfectly. I even have it set up so that when I push to the Github repository, the website is automatically updated.

However, I'd like to offload the speech text synthesis to Amazon Polly, as the speech is far better quality and is compatible with more browsers. This will take time though, as I would need to potentially store the mp3's in S3, and then manage costs associated with that.

Edit 8/17/24

I tried this for a bit using Lambda to generate mp3s. My costs kept going up and up to a point I couldn't afford it. I'm sure there are better ways to handle this, but for now I turned off Amazon Polly and have the browser generating the speech.