mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
get waveform from socket
This commit is contained in:
@@ -30,7 +30,7 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
|||||||
const topics = useTopics(protectedPath, transcriptId);
|
const topics = useTopics(protectedPath, transcriptId);
|
||||||
const waveform = useWaveform(protectedPath, transcriptId);
|
const waveform = useWaveform(protectedPath, transcriptId);
|
||||||
const useActiveTopic = useState<Topic | null>(null);
|
const useActiveTopic = useState<Topic | null>(null);
|
||||||
const mp3 = useMp3(protectedPath, transcriptId);
|
const mp3 = useMp3(transcriptId);
|
||||||
|
|
||||||
if (transcript?.error || topics?.error) {
|
if (transcript?.error || topics?.error) {
|
||||||
return (
|
return (
|
||||||
@@ -59,7 +59,6 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
|||||||
.join("\n\n")
|
.join("\n\n")
|
||||||
.replace(/ +/g, " ")
|
.replace(/ +/g, " ")
|
||||||
.trim() || "";
|
.trim() || "";
|
||||||
console.log("calf full transcript");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -79,11 +78,11 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
|||||||
<Player
|
<Player
|
||||||
topics={topics?.topics || []}
|
topics={topics?.topics || []}
|
||||||
useActiveTopic={useActiveTopic}
|
useActiveTopic={useActiveTopic}
|
||||||
waveform={waveform?.waveform}
|
waveform={waveform.waveform.data}
|
||||||
media={mp3.media}
|
media={mp3.media}
|
||||||
mediaDuration={transcript.response.duration}
|
mediaDuration={transcript.response.duration}
|
||||||
/>
|
/>
|
||||||
) : mp3.error || waveform.error ? (
|
) : waveform.error ? (
|
||||||
<div>"error loading this recording"</div>
|
<div>"error loading this recording"</div>
|
||||||
) : (
|
) : (
|
||||||
<WaveformLoading />
|
<WaveformLoading />
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import { Topic } from "../../webSocketTypes";
|
|||||||
import LiveTrancription from "../../liveTranscription";
|
import LiveTrancription from "../../liveTranscription";
|
||||||
import DisconnectedIndicator from "../../disconnectedIndicator";
|
import DisconnectedIndicator from "../../disconnectedIndicator";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faGear, faSpinner } from "@fortawesome/free-solid-svg-icons";
|
import { faGear } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { lockWakeState, releaseWakeState } from "../../../../lib/wakeLock";
|
import { lockWakeState, releaseWakeState } from "../../../../lib/wakeLock";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import Player from "../../player";
|
import Player from "../../player";
|
||||||
import useMp3 from "../../useMp3";
|
import useMp3, { Mp3Response } from "../../useMp3";
|
||||||
import WaveformLoading from "../../waveformLoading";
|
import WaveformLoading from "../../waveformLoading";
|
||||||
|
|
||||||
type TranscriptDetails = {
|
type TranscriptDetails = {
|
||||||
@@ -48,7 +48,7 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
const [recordedTime, setRecordedTime] = useState(0);
|
const [recordedTime, setRecordedTime] = useState(0);
|
||||||
const [startTime, setStartTime] = useState(0);
|
const [startTime, setStartTime] = useState(0);
|
||||||
const [transcriptStarted, setTranscriptStarted] = useState(false);
|
const [transcriptStarted, setTranscriptStarted] = useState(false);
|
||||||
const mp3 = useMp3(true, "");
|
let mp3 = useMp3(details.params.transcriptId, true);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -74,6 +74,12 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
} // history.replaceState({}, "", newUrl);
|
} // history.replaceState({}, "", newUrl);
|
||||||
}, [webSockets.status.value, transcript.response?.status]);
|
}, [webSockets.status.value, transcript.response?.status]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (webSockets.duration) {
|
||||||
|
mp3.getNow();
|
||||||
|
}
|
||||||
|
}, [webSockets.duration]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
lockWakeState();
|
lockWakeState();
|
||||||
return () => {
|
return () => {
|
||||||
@@ -83,13 +89,13 @@ const TranscriptRecord = (details: TranscriptDetails) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{webSockets.waveform && mp3.media ? (
|
{webSockets.waveform && webSockets.duration && mp3?.media ? (
|
||||||
<Player
|
<Player
|
||||||
topics={webSockets.topics || []}
|
topics={webSockets.topics || []}
|
||||||
useActiveTopic={useActiveTopic}
|
useActiveTopic={useActiveTopic}
|
||||||
waveform={webSockets.waveform}
|
waveform={webSockets.waveform}
|
||||||
media={mp3.media}
|
media={mp3.media}
|
||||||
mediaDuration={recordedTime}
|
mediaDuration={webSockets.duration}
|
||||||
/>
|
/>
|
||||||
) : recordedTime ? (
|
) : recordedTime ? (
|
||||||
<WaveformLoading />
|
<WaveformLoading />
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type PlayerProps = {
|
|||||||
Topic | null,
|
Topic | null,
|
||||||
React.Dispatch<React.SetStateAction<Topic | null>>,
|
React.Dispatch<React.SetStateAction<Topic | null>>,
|
||||||
];
|
];
|
||||||
waveform: AudioWaveform;
|
waveform: AudioWaveform["data"];
|
||||||
media: HTMLMediaElement;
|
media: HTMLMediaElement;
|
||||||
mediaDuration: number;
|
mediaDuration: number;
|
||||||
};
|
};
|
||||||
@@ -29,7 +29,6 @@ export default function Player(props: PlayerProps) {
|
|||||||
);
|
);
|
||||||
const [activeTopic, setActiveTopic] = props.useActiveTopic;
|
const [activeTopic, setActiveTopic] = props.useActiveTopic;
|
||||||
const topicsRef = useRef(props.topics);
|
const topicsRef = useRef(props.topics);
|
||||||
|
|
||||||
// Waveform setup
|
// Waveform setup
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (waveformRef.current) {
|
if (waveformRef.current) {
|
||||||
@@ -40,7 +39,7 @@ export default function Player(props: PlayerProps) {
|
|||||||
// This is not ideal, but it works for now.
|
// This is not ideal, but it works for now.
|
||||||
const _wavesurfer = WaveSurfer.create({
|
const _wavesurfer = WaveSurfer.create({
|
||||||
container: waveformRef.current,
|
container: waveformRef.current,
|
||||||
peaks: props.waveform.data,
|
peaks: props.waveform,
|
||||||
hideScrollbar: true,
|
hideScrollbar: true,
|
||||||
autoCenter: true,
|
autoCenter: true,
|
||||||
barWidth: 2,
|
barWidth: 2,
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { useError } from "../../(errors)/errorContext";
|
|
||||||
import { DomainContext } from "../domainContext";
|
import { DomainContext } from "../domainContext";
|
||||||
import getApi from "../../lib/getApi";
|
import getApi from "../../lib/getApi";
|
||||||
import { useFiefAccessTokenInfo } from "@fief/fief/build/esm/nextjs/react";
|
import { useFiefAccessTokenInfo } from "@fief/fief/build/esm/nextjs/react";
|
||||||
import { shouldShowError } from "../../lib/errorUtils";
|
|
||||||
|
|
||||||
type Mp3Response = {
|
export type Mp3Response = {
|
||||||
url: string | null;
|
|
||||||
media: HTMLMediaElement | null;
|
media: HTMLMediaElement | null;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: Error | null;
|
getNow: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useMp3 = (protectedPath: boolean, id: string): Mp3Response => {
|
const useMp3 = (id: string, waiting?: boolean): Mp3Response => {
|
||||||
const [url, setUrl] = useState<string | null>(null);
|
|
||||||
const [media, setMedia] = useState<HTMLMediaElement | null>(null);
|
const [media, setMedia] = useState<HTMLMediaElement | null>(null);
|
||||||
|
const [later, setLater] = useState(waiting);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [error, setErrorState] = useState<Error | null>(null);
|
const api = getApi(true);
|
||||||
const { setError } = useError();
|
|
||||||
const api = getApi(protectedPath);
|
|
||||||
const { api_url } = useContext(DomainContext);
|
const { api_url } = useContext(DomainContext);
|
||||||
const accessTokenInfo = useFiefAccessTokenInfo();
|
const accessTokenInfo = useFiefAccessTokenInfo();
|
||||||
const [serviceWorkerReady, setServiceWorkerReady] = useState(false);
|
const [serviceWorkerReady, setServiceWorkerReady] = useState(false);
|
||||||
@@ -42,8 +37,8 @@ const useMp3 = (protectedPath: boolean, id: string): Mp3Response => {
|
|||||||
});
|
});
|
||||||
}, [navigator.serviceWorker, serviceWorkerReady, accessTokenInfo]);
|
}, [navigator.serviceWorker, serviceWorkerReady, accessTokenInfo]);
|
||||||
|
|
||||||
const getMp3 = (id: string) => {
|
useEffect(() => {
|
||||||
if (!id || !api) return;
|
if (!id || !api || later) return;
|
||||||
|
|
||||||
// createa a audio element and set the source
|
// createa a audio element and set the source
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -53,13 +48,13 @@ const useMp3 = (protectedPath: boolean, id: string): Mp3Response => {
|
|||||||
audioElement.preload = "auto";
|
audioElement.preload = "auto";
|
||||||
setMedia(audioElement);
|
setMedia(audioElement);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
}, [id, api, later]);
|
||||||
|
|
||||||
|
const getNow = () => {
|
||||||
|
setLater(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
return { media, loading, getNow };
|
||||||
getMp3(id);
|
|
||||||
}, [id, api]);
|
|
||||||
|
|
||||||
return { url, media, loading, error };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useMp3;
|
export default useMp3;
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ export type UseWebSockets = {
|
|||||||
topics: Topic[];
|
topics: Topic[];
|
||||||
finalSummary: FinalSummary;
|
finalSummary: FinalSummary;
|
||||||
status: Status;
|
status: Status;
|
||||||
waveform: AudioWaveform | null;
|
waveform: AudioWaveform["data"] | null;
|
||||||
|
duration: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
||||||
@@ -23,6 +24,7 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
|||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
const [topics, setTopics] = useState<Topic[]>([]);
|
const [topics, setTopics] = useState<Topic[]>([]);
|
||||||
const [waveform, setWaveForm] = useState<AudioWaveform | null>(null);
|
const [waveform, setWaveForm] = useState<AudioWaveform | null>(null);
|
||||||
|
const [duration, setDuration] = useState<number | null>(null);
|
||||||
const [finalSummary, setFinalSummary] = useState<FinalSummary>({
|
const [finalSummary, setFinalSummary] = useState<FinalSummary>({
|
||||||
summary: "",
|
summary: "",
|
||||||
});
|
});
|
||||||
@@ -351,6 +353,22 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "WAVEFORM":
|
||||||
|
console.debug(
|
||||||
|
"WAVEFORM event length:",
|
||||||
|
message.data.waveform.length,
|
||||||
|
);
|
||||||
|
if (message.data) {
|
||||||
|
setWaveForm(message.data.waveform);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "DURATION":
|
||||||
|
console.debug("DURATION event:", message.data);
|
||||||
|
if (message.data) {
|
||||||
|
setDuration(message.data.duration);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case "STATUS":
|
case "STATUS":
|
||||||
console.log("STATUS event:", message.data);
|
console.log("STATUS event:", message.data);
|
||||||
if (message.data.value === "error") {
|
if (message.data.value === "error") {
|
||||||
@@ -415,5 +433,6 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
|||||||
title,
|
title,
|
||||||
status,
|
status,
|
||||||
waveform,
|
waveform,
|
||||||
|
duration,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user