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();
|
||||
};
|
||||
const handleStopRecording = async () => {
|
||||
//@ts-ignore
|
||||
if (window.microphone) {
|
||||
//@ts-ignore
|
||||
window.stopMicrophone();
|
||||
console.log('Microphone stopped');
|
||||
}
|
||||
setRecording(false);
|
||||
const code = await recorder.stopRecording();
|
||||
setBasicCode(code);
|
||||
|
|
@ -58,8 +64,8 @@ const App = () => {
|
|||
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("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", { className: "px-4 py-2 rounded bg-green-500 text-white", onClick: handlePlayback, disabled: !basicCode }, "Play 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", { 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("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)),
|
||||
|
|
|
|||
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')
|
||||
}
|
||||
});
|
||||
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.setMaximizable(false);
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
|
|
@ -69,6 +89,26 @@ function createWindow() {
|
|||
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
||||
}
|
||||
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));
|
||||
// Handler to capture the entire screen
|
||||
electron_2.ipcMain.handle('get-screenshot', async () => {
|
||||
|
|
@ -103,7 +143,6 @@ function createWindow() {
|
|||
return true; // On Windows/Linux, permissions are handled by the OS
|
||||
});
|
||||
electron_2.ipcMain.handle('start-microphone-capture', async (event) => {
|
||||
debugger;
|
||||
const window = electron_2.BrowserWindow.fromWebContents(event.sender);
|
||||
if (!window) {
|
||||
throw new Error('No window found for this request');
|
||||
|
|
@ -172,6 +211,7 @@ function sendToWindow(channel, ...args) {
|
|||
async function startMicrophoneCapture(window) {
|
||||
console.log('Starting microphone capture...');
|
||||
try {
|
||||
navigator.mediaDevices;
|
||||
// Request microphone access
|
||||
//@ts-ignore
|
||||
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 { contextBridge } = require('electron');
|
||||
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
|
||||
window.myApi = {
|
||||
startMicrophone: () => {
|
||||
alert(1);
|
||||
if (navigator.mediaDevices) {
|
||||
return navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
}
|
||||
else {
|
||||
console.error("MediaDevices API not supported");
|
||||
}
|
||||
},
|
||||
sendMessage: (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;
|
||||
}
|
||||
}
|
||||
getMicrophoneStream() {
|
||||
if (typeof window !== 'undefined') {
|
||||
//@ts-ignore
|
||||
return window.getMicrophoneStream();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async startMicrophoneCapture() {
|
||||
console.log('RecorderService.startMicrophoneCapture()');
|
||||
try {
|
||||
this.isListeningToMicrophone = true;
|
||||
electron_1.ipcRenderer.on('audio-level', this.handleAudioLevel);
|
||||
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) {
|
||||
console.error('Failed to start microphone capture:', error);
|
||||
|
|
|
|||
|
|
@ -10,11 +10,18 @@ const App: React.FC = () => {
|
|||
const [basicCode, setBasicCode] = useState('');
|
||||
|
||||
const handleStartRecording = async () => {
|
||||
|
||||
setRecording(true);
|
||||
await recorder.startRecording();
|
||||
};
|
||||
|
||||
const handleStopRecording = async () => {
|
||||
//@ts-ignore
|
||||
if (window.microphone) {
|
||||
//@ts-ignore
|
||||
window.stopMicrophone();
|
||||
console.log('Microphone stopped');
|
||||
}
|
||||
setRecording(false);
|
||||
const code = await recorder.stopRecording();
|
||||
setBasicCode(code);
|
||||
|
|
@ -41,6 +48,7 @@ const App: React.FC = () => {
|
|||
|
||||
<div className="space-x-4 mb-4 h-auto">
|
||||
<button
|
||||
id="startBtn"
|
||||
className={`px-4 py-2 rounded ${recording ? 'bg-red-500' : 'bg-blue-500'} text-white`}
|
||||
onClick={recording ? handleStopRecording : handleStartRecording}
|
||||
>
|
||||
|
|
@ -48,6 +56,7 @@ const App: React.FC = () => {
|
|||
</button>
|
||||
|
||||
<button
|
||||
id="stopBtn"
|
||||
className="px-4 py-2 rounded bg-green-500 text-white"
|
||||
onClick={handlePlayback}
|
||||
disabled={!basicCode}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,30 @@ function createWindow() {
|
|||
contextIsolation: false,
|
||||
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. setMaximizable(false);
|
||||
|
||||
|
|
@ -55,6 +77,28 @@ function createWindow() {
|
|||
} else {
|
||||
mainWindow.loadFile(path.join(__dirname, '../../src/renderer/index.html'));
|
||||
} 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));
|
||||
|
||||
|
||||
|
|
@ -98,12 +142,12 @@ function createWindow() {
|
|||
|
||||
|
||||
ipcMain.handle('start-microphone-capture', async (event) => {
|
||||
debugger;
|
||||
|
||||
const window = BrowserWindow.fromWebContents(event.sender);
|
||||
if (!window) {
|
||||
throw new Error('No window found for this request');
|
||||
}
|
||||
return startMicrophoneCapture(window);
|
||||
return startMicrophoneCapture(window);
|
||||
});
|
||||
|
||||
ipcMain.handle('stop-microphone-capture', async (event) => {
|
||||
|
|
@ -175,15 +219,16 @@ function sendToWindow(channel: string, ...args: any[]) {
|
|||
window.webContents.send(channel, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
async function startMicrophoneCapture(window: BrowserWindow): Promise<void> {
|
||||
console.log('Starting microphone capture...');
|
||||
|
||||
try {
|
||||
|
||||
navigator.mediaDevices;
|
||||
// Request microphone access
|
||||
//@ts-ignore
|
||||
const stream = await window.myApi.startMicrophone()
|
||||
|
||||
|
||||
audioCapture.audioStream = stream;
|
||||
|
||||
// Set up audio analysis
|
||||
|
|
|
|||
|
|
@ -3,17 +3,24 @@ const { contextBridge } = require('electron');
|
|||
|
||||
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
|
||||
(window as any).myApi = {
|
||||
|
||||
startMicrophone: ()=>{
|
||||
startMicrophone: () => {
|
||||
alert(1);
|
||||
if (navigator.mediaDevices) {
|
||||
return navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
} else {
|
||||
console.error("MediaDevices API not supported");
|
||||
}
|
||||
},
|
||||
sendMessage: (message: any) => {
|
||||
console.log('[preload] sendMessage called with:', message);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>General Bots Desktop</title>
|
||||
<script>var global = global || window;</script>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
|
@ -3,6 +3,12 @@ import ReactDOM from 'react-dom/client';
|
|||
import App from '../components/App';
|
||||
|
||||
console.log('[renderer] Initializing React app');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
).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() {
|
||||
console.log('RecorderService.startMicrophoneCapture()');
|
||||
try {
|
||||
this.isListeningToMicrophone = true;
|
||||
ipcRenderer.on('audio-level', this.handleAudioLevel);
|
||||
ipcRenderer.on('audio-chunk', this.handleAudioChunk);
|
||||
await ipcRenderer.invoke('start-microphone-capture');
|
||||
const stream = this.getMicrophoneStream();
|
||||
|
||||
console.log('Got Stream');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to start microphone capture:', error);
|
||||
throw new Error(`Microphone initialization failed: ${error.message}`);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue