I want to know how can I include the speaker labelling in my sentiment analysis application using assemblyai API end-point. I'm having trouble on outputting the speaker label so I hope someone here could help.
I'm using reactjs in this application. credits to: Marius Espajo as a reference in creating this app. YouTube link of the tutorial: https://www.youtube.com/watch?v=OKJiSsBulRo&t=1934s
App.js
import React from 'react';
import {
Avatar,
Box,
Text,
VStack,
Grid,
HStack,
} from '@chakra-ui/react';
import { useState, useEffect } from 'react';
import { Recorder } from 'react-voice-recorder';
import 'react-voice-recorder/dist/index.css';
import axios from 'axios';
import Status from './Status';
import Result from './Result';
const assemblyApi = axios.create({
baseURL: 'https://api.assemblyai.com/v2',
headers: {
authorization: process.env.REACT_APP_ASSEMBLY_API_KEY,
'content-type': 'application/json',
},
});
const initialState = {
url: null,
blob: null,
chunks: null,
duration: {
h: 0,
m: 0,
s: 0,
},
};
function App() {
const [audioDetails, setAudioDetails] = useState(initialState);
const [transcript, setTranscript] = useState({ id: '' });
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const interval = setInterval(async () => {
if (transcript.id && transcript.status !== 'completed' && isLoading) {
try {
const { data: transcriptData } = await assemblyApi.get(
`/transcript/${transcript.id}`
);
setTranscript({ ...transcript, ...transcriptData }); // have stats = 'completed'
} catch (err) {
console.error(err);
}
} else {
setIsLoading(false);
clearInterval(interval);
}
}, 1000);
return () => clearInterval(interval);
}, [isLoading, transcript]);
const handleAudioStop = data => {
setAudioDetails(data);
};
const handleReset = () => {
setAudioDetails({ ...initialState });
setTranscript({ id: '' });
};
const handleAudioUpload = async (audioFile) => {
setIsLoading(true);
const { data: uploadResponse } = await assemblyApi.post('/upload', audioFile);
const { data } = await assemblyApi.post('/transcript', {
audio_url: uploadResponse.upload_url,
speaker_labels: true,
sentiment_analysis: true,
entity_detection: true,
iab_categories: true,
});
setTranscript({ id: data.id });
};
return (
<Box textAlign="center" fontSize="xl">
<Grid
minH={{ base: '50vh', md: '70vh', lg: '100vh' }}
p={{ base: '30px', md: '54px', lg: '90px' }}
>
<VStack spacing={8}>
<Avatar
size="2xl"
name="Assembly AI"
src="https://images.unsplash.com/photo-1535378620166-273708d44e4c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=957&q=80"
/>
<Box>
{transcript.text && transcript.status === 'completed' ? (
<Result transcript={transcript} />
) : (
<Status isLoading={isLoading} status={transcript.status} />
)}
</Box>
<Box>
<HStack spacing="15px">
<Box
w={{ base: '13px', md: '15px', lg: '20px' }}
h={{ base: '13px', md: '15px', lg: '20px' }}
bg="lightgreen">
</Box>{' '}
<Text fontSize="sm" pr="-100px">
Positive
</Text>
<Box
w={{ base: '13px', md: '15px', lg: '20px' }}
h={{ base: '13px', md: '15px', lg: '20px' }}
bg={'lightgray'}>
</Box>{' '}
<Text fontSize="sm">Neutral</Text>
<Box
w={{ base: '13px', md: '15px', lg: '20px' }}
h={{ base: '13px', md: '15px', lg: '20px' }}
bg="pink.200">
</Box>{' '}
<Text fontSize="sm">Negative</Text>
</HStack>
</Box>
<Box width={{ base: '300px', md: '360px', lg: '900px' }} pt="-1">
<Recorder
record={true}
audioURL={audioDetails.url}
handleAudioStop={handleAudioStop}
handleAudioUpload={handleAudioUpload}
handleReset={handleReset}
/>
</Box>
</VStack>
</Grid>
</Box>
);
}
export default App;
Status.js
import { Text, Progress } from '@chakra-ui/react';
const Status = ({ isLoading, status }) => {
return (
<div>
<Text>
{isLoading
? `Calculating... ${status || 'uploading'}...`
: 'Give me audio!'}
</Text>
<Progress
size="sm"
width={ { base: 200, md:300, lg:500}}
isIndeterminate={isLoading}
colorScheme="green"
/>
</div>
);
};
export default Status;
Results.js
import {Box, Text} from '@chakra-ui/react'
import Highlighted from './Highlighted'
const Result = ({ transcript }) => {
return (
<div>
<Box width={{ base: '300px', md: '700px', lg:'1000px'}} textAlign='justify'>
<Text fontSize={{ base: '15px', md: '20px', lg: '25px'}}>
{transcript.sentiment_analysis_results.map(result => (
<Highlighted text={result.text} sentiment={result.sentiment} />
))}
</Text>
</Box>
</div>
)
}
export default Result
Highlighted.js
import { Box, Text, Tooltip} from '@chakra-ui/react'
const sentimentColor = {
POSITIVE: 'lightgreen',
NEGATIVE: 'pink',
NEUTRAL: 'lightgray',
};
const Highlighted = ({ text, sentiment}) => {
return (
<Box as="mark" bg={sentimentColor[sentiment]} mr="1" textAlign="left" > {text} </Box>
)
}
export default Highlighted