audio playback for both user and assistant

This commit is contained in:
Andrei Stoica 2024-02-28 11:55:34 -05:00
parent 5cc002a110
commit 3c0a9b150b
2 changed files with 37 additions and 29 deletions

View File

@ -2,6 +2,7 @@ import { useState } from "react";
import { ChatMsg, Controls, Feed, Header } from "./components.tsx"; import { ChatMsg, Controls, Feed, Header } from "./components.tsx";
import "./App.css"; import "./App.css";
let userAudio: Array<Blob> = [];
let audioBlobs: Array<Blob> = []; let audioBlobs: Array<Blob> = [];
let streamBeingCaptured: MediaStream | null = null; let streamBeingCaptured: MediaStream | null = null;
let mediaRecorder: MediaRecorder | null = null; let mediaRecorder: MediaRecorder | null = null;
@ -51,15 +52,6 @@ function playRecord() {
audio.play(); audio.play();
} }
//function playMsg(msg: ChatMsg) {
// const audio = new Audio(
// "/speak?" +
// new URLSearchParams({ text: msg.content }),
// );
// console.log("loading audio and playing?");
// audio.play();
//}
function App() { function App() {
const [recordState, setRecordState] = useState(false); const [recordState, setRecordState] = useState(false);
const [chatState, setChatState] = useState([{ const [chatState, setChatState] = useState([{
@ -78,8 +70,10 @@ function App() {
} }
function sendAudio() { function sendAudio() {
var formData = new FormData(); let formData = new FormData();
formData.append("audio", new Blob(audioBlobs, { type: "audio/webm" })); let audio = new Blob(audioBlobs, { type: "audio/webm" });
userAudio.push(audio);
formData.append("audio", audio);
fetch("/get-text", { fetch("/get-text", {
"method": "POST", "method": "POST",
"body": formData, "body": formData,
@ -87,7 +81,11 @@ function App() {
.then((res) => { .then((res) => {
setChatState((curState: Array<ChatMsg>) => [ setChatState((curState: Array<ChatMsg>) => [
...curState, ...curState,
{ "role": "user", "content": res["user-transcript"] }, {
"role": "user",
"content": res["user-transcript"],
"audio": URL.createObjectURL(userAudio[userAudio.length - 1]),
},
]); ]);
fetch("/conversation", { fetch("/conversation", {
"method": "POST", "method": "POST",
@ -99,9 +97,10 @@ function App() {
.then((res) => { .then((res) => {
setChatState(( setChatState((
curState: Array<ChatMsg>, curState: Array<ChatMsg>,
) => [...curState, res]); ) => [...curState, {
// console.log("attempting to play result"); ...res,
//playMsg(res); "audio": "/speak?" + new URLSearchParams({ text: res.content }),
}]);
}); });
}); });
} }

View File

@ -9,7 +9,7 @@ import {
export type ChatMsg = { export type ChatMsg = {
role: string; role: string;
content: string; content: string;
audio: any = null; audio?: string;
}; };
export function Header() { export function Header() {
@ -50,18 +50,23 @@ export function Feed(props: { chat: Array<ChatMsg>; setChatStateFn: any }) {
} }
export function Msg(props: { msg: ChatMsg }) { export function Msg(props: { msg: ChatMsg }) {
let audio; //let audio;
if (props.msg.role == "assistant") { //if (props.msg.role == "assistant") {
audio = ( // audio = (
<audio // <audio
controls // controls
autoPlay // autoPlay
src={"/speak?" + new URLSearchParams({ text: props.msg.content })} // src={"/speak?" + new URLSearchParams({ text: props.msg.content })}
/> // />
); // );
} else if (props.msg.audio){ //} else if (props.msg.audio) {
<div />; // audio = (
} // <audio
// controls
// src={props.msg.audio}
// />
// );
//}
return ( return (
<div className="Messege text-lg"> <div className="Messege text-lg">
<span className="font-bold"> <span className="font-bold">
@ -71,7 +76,11 @@ export function Msg(props: { msg: ChatMsg }) {
<span className="ml-8"> <span className="ml-8">
{props.msg.content} {props.msg.content}
</span> </span>
{audio} <audio
controls
autoPlay={props.msg.role == "assistant"}
src={props.msg.audio}
/>
</div> </div>
); );
} }