Skip to main content

How to play audio from decoded base64 string with ElevenLabs Streaming Websocket Typescript

I am attempting to use the ElevenLabs API and Websockets to stream audio to the browser. response.audio does return a generated partial MP3 audio chunk encoded as a base64 string, but I am stuck on trying to properly decode and play it. This is my current attempt:

Main notes:

  • The API does return a response of base64 string successfully
  • I keep receiving the error on Chrome: Uncaught (in promise) DOMException: Failed to load because no supported source was found.
  • My blob url returns a 404 error

Here is my code:

"use client";


import React, { useRef, useState } from 'react';

const StreamingAudioTest: React.FC = () => {

  const [isPlaying, setIsPlaying] = useState(false);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  const handlePlayButtonClick = () => {

    const voiceId = "<voice-id>";
    const model = 'eleven_monolingual_v1';
    const wsUrl = `wss://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream-input?model_id=${model}`;
    const socket = new WebSocket(wsUrl);

    socket.onopen = function (event) {
      const bosMessage = {
        "text": " ",
        "voice_settings": {
          "stability": 0.5,
          "similarity_boost": true
        },
        "xi_api_key": "<api-key>", // replace with your API key
      };

      socket.send(JSON.stringify(bosMessage));

      const textMessage = {
        "text": "Hello ",
        "try_trigger_generation": true,
      };

      socket.send(JSON.stringify(textMessage));

      const eosMessage = {
        "text": ""
      };

      socket.send(JSON.stringify(eosMessage));
    };

    socket.onmessage = async function (event) {
      const response = await JSON.parse(event.data);

   
      if (response.audio) {
        
        const audioChunk = atob(response.audio); // decode base64

  
      
        console.log("Recieved audio chunk")

        if (audioRef.current) {
            const blob = new Blob([audioChunk], { type: 'audio/mp3' }); 
            audioRef.current.src = URL.createObjectURL(blob);
            audioRef.current.play();
          }
        
      }

      if (response.isFinal) {
        // Handle generation completion
      }

      if (response.normalizedAlignment) {
        // Handle alignment info if needed
      }
    };

    socket.onerror = function (error) {
      console.error(`WebSocket Error: ${error}`);
    };

    socket.onclose = function (event) {
      if (event.wasClean) {
        console.info(`Connection closed cleanly, code=${event.code}, reason=${event.reason}`);
      } else {
        console.warn('Connection died');
      }
    };

    // Cleanup the WebSocket when the component unmounts
    return () => {
      socket.close();
    };
  };


  return (
    <div className='text-red-500'>
      <h1>Text-to-Speech Audio Player</h1>
      <button onClick={handlePlayButtonClick} disabled={isPlaying}>
        {isPlaying ? 'Playing...' : 'Play Audio'}
      </button>
      {/* <audio ref={audioRef} controls /> */}

      <audio ref={audioRef} autoPlay controls />
    </div>
  );
};




export default StreamingAudioTest;

Via Active questions tagged javascript - Stack Overflow https://ift.tt/t9AZyWC

Comments

Popular posts from this blog

Prop `className` did not match in next js app

I have written a sample code ( Github Link here ). this is a simple next js app, but giving me error when I refresh the page. This seems to be the common problem and I tried the fix provided in the internet but does not seem to fix my issue. The error is Warning: Prop className did not match. Server: "MuiBox-root MuiBox-root-1" Client: "MuiBox-root MuiBox-root-2". Did changes for _document.js, modified _app.js as mentioned in official website and solutions in stackoverflow. but nothing seems to work. Could someone take a look and help me whats wrong with the code? Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console