Auto-deploy: 2026-06-02 18:09:34
This commit is contained in:
@@ -44,6 +44,7 @@ function initRecognition(language) {
|
|||||||
// Prevent infinite restart loop on fatal errors
|
// Prevent infinite restart loop on fatal errors
|
||||||
if (event.error !== 'no-speech') {
|
if (event.error !== 'no-speech') {
|
||||||
isRecording = false;
|
isRecording = false;
|
||||||
|
if (typeof stopMediaTracks === 'function') stopMediaTracks();
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
@@ -68,29 +69,54 @@ function initRecognition(language) {
|
|||||||
return recognition;
|
return recognition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let localStream = null;
|
||||||
|
|
||||||
|
function stopMediaTracks() {
|
||||||
|
if (localStream) {
|
||||||
|
localStream.getTracks().forEach(track => track.stop());
|
||||||
|
localStream = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for messages from background script
|
// Listen for messages from background script
|
||||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
if (message.type === 'START_RECORDING') {
|
if (message.type === 'START_RECORDING') {
|
||||||
try {
|
const lang = message.payload?.language || 'ar-SA';
|
||||||
const lang = message.payload?.language || 'ar-SA';
|
|
||||||
|
|
||||||
// Re-init if language changed or not init yet
|
// 1. Get an audio stream first. This is REQUIRED in offscreen documents
|
||||||
if (!recognition || recognition.lang !== lang) {
|
// to actually activate the microphone and ensure permissions are active.
|
||||||
recognition = initRecognition(lang);
|
navigator.mediaDevices.getUserMedia({ audio: true })
|
||||||
}
|
.then((stream) => {
|
||||||
|
localStream = stream;
|
||||||
|
|
||||||
if (!isRecording) {
|
try {
|
||||||
recognition.start();
|
if (!recognition || recognition.lang !== lang) {
|
||||||
isRecording = true;
|
recognition = initRecognition(lang);
|
||||||
sendResponse({ success: true });
|
}
|
||||||
} else {
|
|
||||||
sendResponse({ success: true, warning: 'Already recording' });
|
if (!isRecording) {
|
||||||
}
|
recognition.start();
|
||||||
} catch (e) {
|
isRecording = true;
|
||||||
console.error('[Offscreen] Failed to start:', e);
|
sendResponse({ success: true });
|
||||||
sendResponse({ success: false, error: e.message });
|
} else {
|
||||||
}
|
sendResponse({ success: true, warning: 'Already recording' });
|
||||||
return true;
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[Offscreen] Failed to start:', e);
|
||||||
|
sendResponse({ success: false, error: e.message });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('[Offscreen] getUserMedia failed:', err);
|
||||||
|
// The user hasn't granted permission yet, or hardware error
|
||||||
|
sendResponse({ success: false, error: 'not-allowed' });
|
||||||
|
chrome.runtime.sendMessage({
|
||||||
|
type: 'OFFSCREEN_RECORDING_ERROR',
|
||||||
|
payload: { error: 'not-allowed' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return true; // Keep channel open for async sendResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.type === 'STOP_RECORDING') {
|
if (message.type === 'STOP_RECORDING') {
|
||||||
@@ -102,6 +128,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
console.warn('[Offscreen] Stop failed:', e);
|
console.warn('[Offscreen] Stop failed:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stopMediaTracks();
|
||||||
sendResponse({ success: true });
|
sendResponse({ success: true });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user