new(all): Got mic stream.
This commit is contained in:
parent
19220010c1
commit
0905970207
10 changed files with 203 additions and 23 deletions
10
dist/components/App.js
vendored
10
dist/components/App.js
vendored
|
|
@ -36,6 +36,12 @@ const App = () => {
|
||||||
await recorder.startRecording();
|
await recorder.startRecording();
|
||||||
};
|
};
|
||||||
const handleStopRecording = async () => {
|
const handleStopRecording = async () => {
|
||||||
|
//@ts-ignore
|
||||||
|
if (window.microphone) {
|
||||||
|
//@ts-ignore
|
||||||
|
window.stopMicrophone();
|
||||||
|
console.log('Microphone stopped');
|
||||||
|
}
|
||||||
setRecording(false);
|
setRecording(false);
|
||||||
const code = await recorder.stopRecording();
|
const code = await recorder.stopRecording();
|
||||||
setBasicCode(code);
|
setBasicCode(code);
|
||||||
|
|
@ -58,8 +64,8 @@ const App = () => {
|
||||||
return (react_1.default.createElement("div", { className: "p-4 h-auto" },
|
return (react_1.default.createElement("div", { className: "p-4 h-auto" },
|
||||||
react_1.default.createElement("h1", { className: "text-2xl font-bold mb-4" }, "General Bots Desktop"),
|
react_1.default.createElement("h1", { className: "text-2xl font-bold mb-4" }, "General Bots Desktop"),
|
||||||
react_1.default.createElement("div", { className: "space-x-4 mb-4 h-auto" },
|
react_1.default.createElement("div", { className: "space-x-4 mb-4 h-auto" },
|
||||||
react_1.default.createElement("button", { className: `px-4 py-2 rounded ${recording ? 'bg-red-500' : 'bg-blue-500'} text-white`, onClick: recording ? handleStopRecording : handleStartRecording }, recording ? 'Stop Recording' : 'Start Recording'),
|
react_1.default.createElement("button", { id: "startBtn", className: `px-4 py-2 rounded ${recording ? 'bg-red-500' : 'bg-blue-500'} text-white`, onClick: recording ? handleStopRecording : handleStartRecording }, recording ? 'Stop Recording' : 'Start Recording'),
|
||||||
react_1.default.createElement("button", { className: "px-4 py-2 rounded bg-green-500 text-white", onClick: handlePlayback, disabled: !basicCode }, "Play Recording")),
|
react_1.default.createElement("button", { id: "stopBtn", className: "px-4 py-2 rounded bg-green-500 text-white", onClick: handlePlayback, disabled: !basicCode }, "Play Recording")),
|
||||||
react_1.default.createElement("div", { className: "mt-4 h-20" },
|
react_1.default.createElement("div", { className: "mt-4 h-20" },
|
||||||
react_1.default.createElement("h2", { className: "text-xl font-bold mb-2" }, "Generated BASIC Code:"),
|
react_1.default.createElement("h2", { className: "text-xl font-bold mb-2" }, "Generated BASIC Code:"),
|
||||||
react_1.default.createElement("pre", { className: "h-20 min-h-100 bg-gray-100 p-2 rounded border" }, basicCode)),
|
react_1.default.createElement("pre", { className: "h-20 min-h-100 bg-gray-100 p-2 rounded border" }, basicCode)),
|
||||||
|
|
|
||||||
42
dist/main/main.js
vendored
42
dist/main/main.js
vendored
|
|
@ -59,6 +59,26 @@ function createWindow() {
|
||||||
preload: path.join(__dirname, '../preload/preload.js')
|
preload: path.join(__dirname, '../preload/preload.js')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
electron_2.ipcMain.handle('request-microphone', async () => {
|
||||||
|
try {
|
||||||
|
const stream = await mainWindow.webContents.executeJavaScript(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
return stream;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing microphone:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`);
|
||||||
|
return stream; // Return the stream to the UserService
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Failed to get microphone stream:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
mainWindow.setAutoHideMenuBar(true);
|
mainWindow.setAutoHideMenuBar(true);
|
||||||
mainWindow.setMaximizable(false);
|
mainWindow.setMaximizable(false);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
|
@ -69,6 +89,26 @@ function createWindow() {
|
||||||
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
||||||
}
|
}
|
||||||
electron_2.ipcMain.handle('mouse-event', recorder.handleMouseEvent.bind(recorder));
|
electron_2.ipcMain.handle('mouse-event', recorder.handleMouseEvent.bind(recorder));
|
||||||
|
electron_2.ipcMain.handle('request-microphone', async () => {
|
||||||
|
try {
|
||||||
|
const stream = await mainWindow.webContents.executeJavaScript(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
return stream;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing microphone:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`);
|
||||||
|
return stream; // Return the stream to the UserService
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Failed to get microphone stream:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
electron_2.ipcMain.handle('keyboard-event', recorder.handleKeyboardEvent.bind(recorder));
|
electron_2.ipcMain.handle('keyboard-event', recorder.handleKeyboardEvent.bind(recorder));
|
||||||
// Handler to capture the entire screen
|
// Handler to capture the entire screen
|
||||||
electron_2.ipcMain.handle('get-screenshot', async () => {
|
electron_2.ipcMain.handle('get-screenshot', async () => {
|
||||||
|
|
@ -103,7 +143,6 @@ function createWindow() {
|
||||||
return true; // On Windows/Linux, permissions are handled by the OS
|
return true; // On Windows/Linux, permissions are handled by the OS
|
||||||
});
|
});
|
||||||
electron_2.ipcMain.handle('start-microphone-capture', async (event) => {
|
electron_2.ipcMain.handle('start-microphone-capture', async (event) => {
|
||||||
debugger;
|
|
||||||
const window = electron_2.BrowserWindow.fromWebContents(event.sender);
|
const window = electron_2.BrowserWindow.fromWebContents(event.sender);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
throw new Error('No window found for this request');
|
throw new Error('No window found for this request');
|
||||||
|
|
@ -172,6 +211,7 @@ function sendToWindow(channel, ...args) {
|
||||||
async function startMicrophoneCapture(window) {
|
async function startMicrophoneCapture(window) {
|
||||||
console.log('Starting microphone capture...');
|
console.log('Starting microphone capture...');
|
||||||
try {
|
try {
|
||||||
|
navigator.mediaDevices;
|
||||||
// Request microphone access
|
// Request microphone access
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const stream = await window.myApi.startMicrophone();
|
const stream = await window.myApi.startMicrophone();
|
||||||
|
|
|
||||||
17
dist/preload/preload.js
vendored
17
dist/preload/preload.js
vendored
|
|
@ -1,16 +1,21 @@
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
const { contextBridge } = require('electron');
|
const { contextBridge } = require('electron');
|
||||||
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
// Initialize IPC listeners for microphone access
|
||||||
|
ipcRenderer.on('request-microphone', async () => {
|
||||||
|
if (navigator.mediaDevices) {
|
||||||
|
return navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error("MediaDevices API not supported");
|
||||||
|
}
|
||||||
|
// Send the microphone stream back to the renderer
|
||||||
|
//event.sender.send('microphone-stream', stream);
|
||||||
|
});
|
||||||
//@ts-nocheck
|
//@ts-nocheck
|
||||||
window.myApi = {
|
window.myApi = {
|
||||||
startMicrophone: () => {
|
startMicrophone: () => {
|
||||||
alert(1);
|
alert(1);
|
||||||
if (navigator.mediaDevices) {
|
|
||||||
return navigator.mediaDevices.getUserMedia({ audio: true });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error("MediaDevices API not supported");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
sendMessage: (message) => {
|
sendMessage: (message) => {
|
||||||
console.log('[preload] sendMessage called with:', message);
|
console.log('[preload] sendMessage called with:', message);
|
||||||
|
|
|
||||||
10
dist/services/recorder.service.js
vendored
10
dist/services/recorder.service.js
vendored
|
|
@ -116,13 +116,21 @@ class RecorderService {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
getMicrophoneStream() {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
//@ts-ignore
|
||||||
|
return window.getMicrophoneStream();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
async startMicrophoneCapture() {
|
async startMicrophoneCapture() {
|
||||||
console.log('RecorderService.startMicrophoneCapture()');
|
console.log('RecorderService.startMicrophoneCapture()');
|
||||||
try {
|
try {
|
||||||
this.isListeningToMicrophone = true;
|
this.isListeningToMicrophone = true;
|
||||||
electron_1.ipcRenderer.on('audio-level', this.handleAudioLevel);
|
electron_1.ipcRenderer.on('audio-level', this.handleAudioLevel);
|
||||||
electron_1.ipcRenderer.on('audio-chunk', this.handleAudioChunk);
|
electron_1.ipcRenderer.on('audio-chunk', this.handleAudioChunk);
|
||||||
await electron_1.ipcRenderer.invoke('start-microphone-capture');
|
const stream = this.getMicrophoneStream();
|
||||||
|
console.log('Got Stream');
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('Failed to start microphone capture:', error);
|
console.error('Failed to start microphone capture:', error);
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,18 @@ const App: React.FC = () => {
|
||||||
const [basicCode, setBasicCode] = useState('');
|
const [basicCode, setBasicCode] = useState('');
|
||||||
|
|
||||||
const handleStartRecording = async () => {
|
const handleStartRecording = async () => {
|
||||||
|
|
||||||
setRecording(true);
|
setRecording(true);
|
||||||
await recorder.startRecording();
|
await recorder.startRecording();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStopRecording = async () => {
|
const handleStopRecording = async () => {
|
||||||
|
//@ts-ignore
|
||||||
|
if (window.microphone) {
|
||||||
|
//@ts-ignore
|
||||||
|
window.stopMicrophone();
|
||||||
|
console.log('Microphone stopped');
|
||||||
|
}
|
||||||
setRecording(false);
|
setRecording(false);
|
||||||
const code = await recorder.stopRecording();
|
const code = await recorder.stopRecording();
|
||||||
setBasicCode(code);
|
setBasicCode(code);
|
||||||
|
|
@ -41,6 +48,7 @@ const App: React.FC = () => {
|
||||||
|
|
||||||
<div className="space-x-4 mb-4 h-auto">
|
<div className="space-x-4 mb-4 h-auto">
|
||||||
<button
|
<button
|
||||||
|
id="startBtn"
|
||||||
className={`px-4 py-2 rounded ${recording ? 'bg-red-500' : 'bg-blue-500'} text-white`}
|
className={`px-4 py-2 rounded ${recording ? 'bg-red-500' : 'bg-blue-500'} text-white`}
|
||||||
onClick={recording ? handleStopRecording : handleStartRecording}
|
onClick={recording ? handleStopRecording : handleStartRecording}
|
||||||
>
|
>
|
||||||
|
|
@ -48,6 +56,7 @@ const App: React.FC = () => {
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
id="stopBtn"
|
||||||
className="px-4 py-2 rounded bg-green-500 text-white"
|
className="px-4 py-2 rounded bg-green-500 text-white"
|
||||||
onClick={handlePlayback}
|
onClick={handlePlayback}
|
||||||
disabled={!basicCode}
|
disabled={!basicCode}
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,30 @@ function createWindow() {
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
preload: path.join(__dirname, '../preload/preload.js')
|
preload: path.join(__dirname, '../preload/preload.js')
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
ipcMain.handle('request-microphone', async () => {
|
||||||
|
try {
|
||||||
|
const stream = await mainWindow.webContents.executeJavaScript(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
return stream;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing microphone:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`);
|
||||||
|
return stream; // Return the stream to the UserService
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get microphone stream:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
mainWindow.setAutoHideMenuBar(true);
|
mainWindow.setAutoHideMenuBar(true);
|
||||||
mainWindow. setMaximizable(false);
|
mainWindow. setMaximizable(false);
|
||||||
|
|
||||||
|
|
@ -55,6 +77,28 @@ function createWindow() {
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
||||||
} ipcMain.handle('mouse-event', recorder.handleMouseEvent.bind(recorder));
|
} ipcMain.handle('mouse-event', recorder.handleMouseEvent.bind(recorder));
|
||||||
|
|
||||||
|
|
||||||
|
ipcMain.handle('request-microphone', async () => {
|
||||||
|
try {
|
||||||
|
const stream = await mainWindow.webContents.executeJavaScript(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
return stream;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing microphone:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`);
|
||||||
|
return stream; // Return the stream to the UserService
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get microphone stream:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle('keyboard-event', recorder.handleKeyboardEvent.bind(recorder));
|
ipcMain.handle('keyboard-event', recorder.handleKeyboardEvent.bind(recorder));
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -98,12 +142,12 @@ function createWindow() {
|
||||||
|
|
||||||
|
|
||||||
ipcMain.handle('start-microphone-capture', async (event) => {
|
ipcMain.handle('start-microphone-capture', async (event) => {
|
||||||
debugger;
|
|
||||||
const window = BrowserWindow.fromWebContents(event.sender);
|
const window = BrowserWindow.fromWebContents(event.sender);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
throw new Error('No window found for this request');
|
throw new Error('No window found for this request');
|
||||||
}
|
}
|
||||||
return startMicrophoneCapture(window);
|
return startMicrophoneCapture(window);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('stop-microphone-capture', async (event) => {
|
ipcMain.handle('stop-microphone-capture', async (event) => {
|
||||||
|
|
@ -175,11 +219,12 @@ function sendToWindow(channel: string, ...args: any[]) {
|
||||||
window.webContents.send(channel, ...args);
|
window.webContents.send(channel, ...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startMicrophoneCapture(window: BrowserWindow): Promise<void> {
|
async function startMicrophoneCapture(window: BrowserWindow): Promise<void> {
|
||||||
console.log('Starting microphone capture...');
|
console.log('Starting microphone capture...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
navigator.mediaDevices;
|
||||||
// Request microphone access
|
// Request microphone access
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const stream = await window.myApi.startMicrophone()
|
const stream = await window.myApi.startMicrophone()
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,24 @@ const { contextBridge } = require('electron');
|
||||||
|
|
||||||
const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
|
const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
|
||||||
|
|
||||||
|
// Initialize IPC listeners for microphone access
|
||||||
|
ipcRenderer.on('request-microphone', async () => {
|
||||||
|
|
||||||
|
if (navigator.mediaDevices) {
|
||||||
|
return navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
} else {
|
||||||
|
console.error("MediaDevices API not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the microphone stream back to the renderer
|
||||||
|
//event.sender.send('microphone-stream', stream);
|
||||||
|
});
|
||||||
|
|
||||||
//@ts-nocheck
|
//@ts-nocheck
|
||||||
(window as any).myApi = {
|
(window as any).myApi = {
|
||||||
|
|
||||||
startMicrophone: ()=>{
|
startMicrophone: () => {
|
||||||
alert(1);
|
alert(1);
|
||||||
if (navigator.mediaDevices) {
|
|
||||||
return navigator.mediaDevices.getUserMedia({ audio: true });
|
|
||||||
} else {
|
|
||||||
console.error("MediaDevices API not supported");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
sendMessage: (message: any) => {
|
sendMessage: (message: any) => {
|
||||||
console.log('[preload] sendMessage called with:', message);
|
console.log('[preload] sendMessage called with:', message);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,56 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>General Bots Desktop</title>
|
<title>General Bots Desktop</title>
|
||||||
<script>var global = global || window;</script>
|
<script>var global = global || window;</script>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const stream = navigator.mediaDevices.getUserMedia({
|
||||||
|
audio: true,
|
||||||
|
video: false
|
||||||
|
}).then(stream => {
|
||||||
|
alert(1);
|
||||||
|
// Now you have access to the stream
|
||||||
|
window.microphone = stream;
|
||||||
|
|
||||||
|
// You can store it in a global variable
|
||||||
|
window.getMicrophoneStream = () => stream;
|
||||||
|
|
||||||
|
// Or expose it through a global function
|
||||||
|
window.stopMicrophone = () => {
|
||||||
|
stream.getTracks().forEach(track => track.stop());
|
||||||
|
window.microphone = null;
|
||||||
|
};
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error accessing microphone:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
const startBtn = document.getElementById('startBtn');
|
||||||
|
const stopBtn = document.getElementById('stopBtn');
|
||||||
|
|
||||||
|
startBtn.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
await navigator.mediaDevices.getUserMedia({
|
||||||
|
audio: true,
|
||||||
|
video: false
|
||||||
|
}).then(stream => {
|
||||||
|
window.microphone = stream;
|
||||||
|
console.log('Microphone started');
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to start microphone:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -3,6 +3,12 @@ import ReactDOM from 'react-dom/client';
|
||||||
import App from '../components/App';
|
import App from '../components/App';
|
||||||
|
|
||||||
console.log('[renderer] Initializing React app');
|
console.log('[renderer] Initializing React app');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.createRoot(
|
ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
).render(
|
).render(
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,23 @@ export class RecorderService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMicrophoneStream(): MediaStream | null {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
//@ts-ignore
|
||||||
|
return window.getMicrophoneStream();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
private async startMicrophoneCapture() {
|
private async startMicrophoneCapture() {
|
||||||
console.log('RecorderService.startMicrophoneCapture()');
|
console.log('RecorderService.startMicrophoneCapture()');
|
||||||
try {
|
try {
|
||||||
this.isListeningToMicrophone = true;
|
this.isListeningToMicrophone = true;
|
||||||
ipcRenderer.on('audio-level', this.handleAudioLevel);
|
ipcRenderer.on('audio-level', this.handleAudioLevel);
|
||||||
ipcRenderer.on('audio-chunk', this.handleAudioChunk);
|
ipcRenderer.on('audio-chunk', this.handleAudioChunk);
|
||||||
await ipcRenderer.invoke('start-microphone-capture');
|
const stream = this.getMicrophoneStream();
|
||||||
|
|
||||||
|
console.log('Got Stream');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start microphone capture:', error);
|
console.error('Failed to start microphone capture:', error);
|
||||||
throw new Error(`Microphone initialization failed: ${error.message}`);
|
throw new Error(`Microphone initialization failed: ${error.message}`);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue