150 lines
4.5 KiB
JavaScript
150 lines
4.5 KiB
JavaScript
// Background service worker
|
|
chrome.runtime.onInstalled.addListener(() => {
|
|
console.log('SDB Audio Extractor extension installed');
|
|
|
|
// Create context menu
|
|
chrome.contextMenus.create({
|
|
id: 'extractAudio',
|
|
title: 'Extract Audio with SDB',
|
|
contexts: ['page'],
|
|
documentUrlPatterns: ['https://www.youtube.com/watch*']
|
|
});
|
|
});
|
|
|
|
// Function to clean YouTube URL
|
|
function getCleanVideoUrl(url) {
|
|
const match = url.match(/[?&]v=([^&]+)/);
|
|
if (match) {
|
|
return `https://www.youtube.com/watch?v=${match[1]}`;
|
|
}
|
|
return url; // Return original if we can't extract video ID
|
|
}
|
|
|
|
// Handle context menu clicks
|
|
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
|
if (info.menuItemId === 'extractAudio') {
|
|
// Get API configuration
|
|
const result = await chrome.storage.sync.get(['apiToken', 'apiBaseUrl']);
|
|
const apiToken = result.apiToken;
|
|
const apiBaseUrl = result.apiBaseUrl || 'http://goyave';
|
|
|
|
if (!apiToken) {
|
|
// Open options page if no token configured
|
|
chrome.runtime.openOptionsPage();
|
|
return;
|
|
}
|
|
|
|
// Get video information from content script for notification
|
|
let videoTitle = null;
|
|
try {
|
|
const videoInfo = await chrome.tabs.sendMessage(tab.id, { action: 'getVideoInfo' });
|
|
if (videoInfo && videoInfo.title) {
|
|
videoTitle = videoInfo.title;
|
|
}
|
|
} catch (error) {
|
|
console.log('Could not get video info from content script:', error);
|
|
}
|
|
|
|
// Send extraction request
|
|
try {
|
|
// Use clean URL for the API request
|
|
const cleanUrl = getCleanVideoUrl(tab.url);
|
|
|
|
const response = await fetch(`${apiBaseUrl}/api/v1/extractions/?url=${encodeURIComponent(cleanUrl)}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'API-TOKEN': apiToken
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
// Show success notification
|
|
const notificationMessage = videoTitle
|
|
? `Audio extraction started for "${videoTitle}"!`
|
|
: 'Audio extraction started successfully!';
|
|
|
|
chrome.notifications.create({
|
|
type: 'basic',
|
|
iconUrl: 'icon48.png',
|
|
title: 'SDB Audio Extractor',
|
|
message: notificationMessage
|
|
});
|
|
} else {
|
|
throw new Error(`HTTP ${response.status}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('Extraction error:', error);
|
|
let errorMessage = 'Unknown error occurred';
|
|
|
|
if (error.message) {
|
|
errorMessage = error.message;
|
|
} else if (error.name === 'TypeError' && error.message.includes('fetch')) {
|
|
errorMessage = 'Cannot connect to API server';
|
|
} else if (typeof error === 'string') {
|
|
errorMessage = error;
|
|
}
|
|
|
|
chrome.notifications.create({
|
|
type: 'basic',
|
|
iconUrl: 'icon48.png',
|
|
title: 'SDB Audio Extractor',
|
|
message: `Failed to extract audio: ${errorMessage}`
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle messages from content scripts or popup
|
|
chrome.runtime.onMessage.addListener((request, _sender, sendResponse) => {
|
|
console.log('Background received message:', request);
|
|
|
|
if (request.action === 'extractAudio') {
|
|
// Handle extraction request from content script if needed
|
|
handleExtraction(request.url).then(sendResponse);
|
|
return true; // Keep message channel open for async response
|
|
}
|
|
});
|
|
|
|
async function handleExtraction(url) {
|
|
try {
|
|
const result = await chrome.storage.sync.get(['apiToken', 'apiBaseUrl']);
|
|
const apiToken = result.apiToken;
|
|
const apiBaseUrl = result.apiBaseUrl || 'http://goyave';
|
|
|
|
if (!apiToken) {
|
|
throw new Error('API token not configured');
|
|
}
|
|
|
|
// Use clean URL for the API request
|
|
const cleanUrl = getCleanVideoUrl(url);
|
|
|
|
const response = await fetch(`${apiBaseUrl}/api/v1/extractions/?url=${encodeURIComponent(cleanUrl)}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'API-TOKEN': apiToken
|
|
}
|
|
});
|
|
|
|
if (!response.ok) {
|
|
let errorMessage = `HTTP ${response.status}`;
|
|
try {
|
|
const errorData = await response.json();
|
|
if (errorData.detail) {
|
|
errorMessage = errorData.detail;
|
|
} else if (errorData.message) {
|
|
errorMessage = errorData.message;
|
|
} else if (typeof errorData === 'string') {
|
|
errorMessage = errorData;
|
|
}
|
|
} catch (e) {
|
|
errorMessage = response.statusText || errorMessage;
|
|
}
|
|
throw new Error(errorMessage);
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Extraction error:', error);
|
|
throw error;
|
|
}
|
|
} |