Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f013b4751 | ||
|
|
66dce4415a | ||
|
|
6460349fc7 | ||
|
|
6926c27f20 | ||
|
|
cbf82f9317 |
+13
-9
@@ -30,15 +30,15 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
// use `security find-identity -v -p codesigning` to find your identity
|
// use `security find-identity -v -p codesigning` to find your identity
|
||||||
// for macos signing
|
// for macos signing
|
||||||
// Use ad-hoc signing with entitlements for local development
|
// Disabled for local builds - ad-hoc signing causes issues
|
||||||
osxSign: {
|
// osxSign: {
|
||||||
identity: '-', // ad-hoc signing (no Apple Developer account needed)
|
// identity: '-', // ad-hoc signing (no Apple Developer account needed)
|
||||||
optionsForFile: (filePath) => {
|
// optionsForFile: (filePath) => {
|
||||||
return {
|
// return {
|
||||||
entitlements: 'entitlements.plist',
|
// entitlements: 'entitlements.plist',
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
// notarize is off - requires Apple Developer account
|
// notarize is off - requires Apple Developer account
|
||||||
// osxNotarize: {
|
// osxNotarize: {
|
||||||
// appleId: 'your apple id',
|
// appleId: 'your apple id',
|
||||||
@@ -61,6 +61,10 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: '@electron-forge/maker-dmg',
|
name: '@electron-forge/maker-dmg',
|
||||||
platforms: ['darwin'],
|
platforms: ['darwin'],
|
||||||
|
config: {
|
||||||
|
name: 'CheatingDaddy',
|
||||||
|
format: 'ULFO',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '@reforged/maker-appimage',
|
name: '@reforged/maker-appimage',
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cheating-daddy",
|
"name": "cheating-daddy",
|
||||||
"productName": "cheating-daddy",
|
"productName": "cheating-daddy",
|
||||||
"version": "0.5.3",
|
"version": "0.5.8",
|
||||||
"description": "cheating daddy",
|
"description": "cheating daddy",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
"cheating daddy ai assistant for interviews"
|
"cheating daddy ai assistant for interviews"
|
||||||
],
|
],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "sohzm",
|
"name": "ShiftyX1",
|
||||||
"email": "sohambharambe9@gmail.com"
|
"email": "lead@pyserve.org"
|
||||||
},
|
},
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+15
-2
@@ -281,6 +281,7 @@ async function sendImageMessage(base64Image, prompt) {
|
|||||||
let audioChunks = [];
|
let audioChunks = [];
|
||||||
let lastAudioTime = 0;
|
let lastAudioTime = 0;
|
||||||
const SILENCE_THRESHOLD_MS = 1500; // 1.5 seconds of silence
|
const SILENCE_THRESHOLD_MS = 1500; // 1.5 seconds of silence
|
||||||
|
let silenceCheckTimer = null;
|
||||||
|
|
||||||
async function processAudioChunk(base64Audio, mimeType) {
|
async function processAudioChunk(base64Audio, mimeType) {
|
||||||
if (!openaiClient) {
|
if (!openaiClient) {
|
||||||
@@ -294,8 +295,20 @@ async function processAudioChunk(base64Audio, mimeType) {
|
|||||||
audioChunks.push(buffer);
|
audioChunks.push(buffer);
|
||||||
lastAudioTime = now;
|
lastAudioTime = now;
|
||||||
|
|
||||||
// Check for silence (no new audio for SILENCE_THRESHOLD_MS)
|
// Clear existing timer
|
||||||
// This is a simple approach - in production you'd want proper VAD
|
if (silenceCheckTimer) {
|
||||||
|
clearTimeout(silenceCheckTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set timer to check for silence
|
||||||
|
silenceCheckTimer = setTimeout(async () => {
|
||||||
|
const silenceDuration = Date.now() - lastAudioTime;
|
||||||
|
if (silenceDuration >= SILENCE_THRESHOLD_MS && audioChunks.length > 0) {
|
||||||
|
console.log('Silence detected, flushing audio for transcription...');
|
||||||
|
await flushAudioAndTranscribe();
|
||||||
|
}
|
||||||
|
}, SILENCE_THRESHOLD_MS);
|
||||||
|
|
||||||
return { success: true, buffering: true };
|
return { success: true, buffering: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-84
@@ -33,90 +33,14 @@ function createWindow(sendToRenderer, geminiSessionRef) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { session, desktopCapturer } = require('electron');
|
const { session, desktopCapturer } = require('electron');
|
||||||
|
session.defaultSession.setDisplayMediaRequestHandler(
|
||||||
// Setup display media request handler for screen capture
|
(request, callback) => {
|
||||||
if (process.platform === 'darwin') {
|
desktopCapturer.getSources({ types: ['screen'] }).then(sources => {
|
||||||
// On macOS, use SystemAudioDump for audio (not browser loopback)
|
callback({ video: sources[0], audio: 'loopback' });
|
||||||
// So we just need to capture the screen
|
});
|
||||||
session.defaultSession.setDisplayMediaRequestHandler(
|
},
|
||||||
async (request, callback) => {
|
{ useSystemPicker: true }
|
||||||
try {
|
);
|
||||||
const sources = await desktopCapturer.getSources({
|
|
||||||
types: ['screen'],
|
|
||||||
thumbnailSize: { width: 0, height: 0 } // Skip thumbnail generation for speed
|
|
||||||
});
|
|
||||||
|
|
||||||
if (sources.length === 0) {
|
|
||||||
console.error('No screen sources available');
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// On macOS, directly use the first screen (system already granted permission)
|
|
||||||
// Audio is handled separately by SystemAudioDump
|
|
||||||
console.log('Screen capture source:', sources[0].name);
|
|
||||||
callback({ video: sources[0], audio: 'loopback' });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error getting screen sources:', error);
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ useSystemPicker: false } // Disable system picker, use our source directly
|
|
||||||
);
|
|
||||||
} else if (process.platform === 'win32') {
|
|
||||||
// On Windows, use desktopCapturer with loopback audio
|
|
||||||
// This captures system audio via WASAPI without needing user interaction
|
|
||||||
session.defaultSession.setDisplayMediaRequestHandler(
|
|
||||||
async (request, callback) => {
|
|
||||||
try {
|
|
||||||
console.log('Windows: Getting screen sources with loopback audio...');
|
|
||||||
const sources = await desktopCapturer.getSources({
|
|
||||||
types: ['screen'],
|
|
||||||
thumbnailSize: { width: 0, height: 0 }
|
|
||||||
});
|
|
||||||
|
|
||||||
if (sources.length === 0) {
|
|
||||||
console.error('No screen sources available on Windows');
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Windows: Using screen source:', sources[0].name, 'with loopback audio');
|
|
||||||
// 'loopback' enables system audio capture via WASAPI on Windows
|
|
||||||
callback({ video: sources[0], audio: 'loopback' });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error getting screen sources on Windows:', error);
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ useSystemPicker: false }
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// On Linux, try to get system audio via loopback
|
|
||||||
session.defaultSession.setDisplayMediaRequestHandler(
|
|
||||||
async (request, callback) => {
|
|
||||||
try {
|
|
||||||
const sources = await desktopCapturer.getSources({
|
|
||||||
types: ['screen'],
|
|
||||||
thumbnailSize: { width: 0, height: 0 }
|
|
||||||
});
|
|
||||||
|
|
||||||
if (sources.length === 0) {
|
|
||||||
console.error('No screen sources available');
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Linux: Using screen source with loopback audio');
|
|
||||||
callback({ video: sources[0], audio: 'loopback' });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error getting screen sources:', error);
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ useSystemPicker: false }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
mainWindow.setResizable(false);
|
mainWindow.setResizable(false);
|
||||||
mainWindow.setContentProtection(true);
|
mainWindow.setContentProtection(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user