-
Notifications
You must be signed in to change notification settings - Fork 251
Expand file tree
/
Copy pathUploadAudio.tsx
More file actions
119 lines (108 loc) · 3.2 KB
/
Copy pathUploadAudio.tsx
File metadata and controls
119 lines (108 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import React, { useState } from "react";
import { useModalState } from "../../utils/hooks/modal-context";
import { cn } from "../../utils/styles";
import { StopSquareIcon, MicIcon } from "../icons";
import { motion } from "motion/react";
export const UploadAudio = () => {
const { mode, setAudioBase64, isRecording, setIsRecording } = useModalState();
const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(
null
);
const startRecording = async () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const isFirefox = navigator.userAgent.toLowerCase().includes("firefox");
const recorder = new MediaRecorder(stream, {
mimeType: isFirefox ? "audio/webm" : "audio/mp4",
});
const audioChunks: BlobPart[] = [];
recorder.ondataavailable = (event) => {
audioChunks.push(event.data);
};
recorder.onstop = () => {
stream.getTracks().forEach((track) => track.stop());
setAudioBase64("");
const audioBlob = new Blob(audioChunks, {
type: isFirefox ? "audio/webm" : "audio/mp4",
});
const reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = () => {
let base64data = reader.result as string;
base64data = base64data?.split(",")[1];
setAudioBase64(base64data);
};
};
setMediaRecorder(recorder);
recorder.start(100);
setIsRecording(true);
} catch (err) {
console.error("Error accessing microphone:", err);
alert(
"Error accessing microphone. Please make sure you have granted microphone permissions."
);
}
};
const stopRecording = () => {
if (mediaRecorder && mediaRecorder?.state !== "inactive") {
mediaRecorder?.stop();
setIsRecording(false);
}
};
const toggleRecording = () => {
if (isRecording) {
stopRecording();
} else {
void startRecording();
}
};
return (
<div>
<div
aria-role="button"
className={cn(
"tv-rounded tv-z-20 tv-cursor-pointer",
mode === "chat" && "tv-right-[60px] tv-top-[17px] tv-absolute"
)}
onClick={(e) => {
e.preventDefault();
toggleRecording();
}}
>
<div
onClick={(e) => {
e.preventDefault();
toggleRecording();
}}
className="tv-block md:tv-hidden tv-top-0 tv-bottom-0 tv-left-0 tv-right-0 tv-scale-125 tv-pr-3 tv-pl-6 tv-py-8 -tv-translate-x-5 tv-absolute"
></div>
{isRecording ? (
<motion.div
animate={{
opacity: [1, 0.7, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut",
}}
>
<StopSquareIcon
width={16}
height={16}
className={"tv-text-red-500"}
/>
</motion.div>
) : (
<MicIcon
width={16}
height={16}
className="tv-text-zinc-700 tv-dark-text-white"
/>
)}
</div>
</div>
);
};