<<<<<<< Updated upstream
=======
A powerful Chrome Extension (Manifest V3) that translates English subtitles on Pluralsight.com to Vietnamese (or other languages) in real-time using LLM APIs like OpenAI GPT or Google Gemini.
✅ Real-time Translation - Automatically translates subtitles as they appear
✅ Dual Display - Shows both English (original) and translated (yellow italic) subtitles simultaneously
✅ Smart Caching - Avoids re-translating the same subtitle if you rewind
✅ Multiple Languages - Supports Vietnamese, Spanish, French, German, Japanese, Chinese
✅ Dual API Support - Works with OpenAI and Google Gemini APIs
✅ Async/Await Architecture - Non-blocking translation to prevent UI freezing
✅ Efficient Observation - Uses MutationObserver for precise subtitle detection
Pluralsight-Bilingual-Translator/
├── manifest.json # Chrome Extension configuration (Manifest V3)
├── popup.html # Settings UI for API key and language selection
├── popup.js # Popup logic for saving/loading settings
├── styles.css # Popup and extension styling
├── content.js # Core logic: subtitle detection + injection (MutationObserver)
├── background.js # Service worker: API request handling (CORS workaround)
└── README.md # This file
- Chrome/Chromium browser (v88+)
- OpenAI API key OR Google Gemini API key
- Pluralsight account with active video content
Option A: OpenAI (Recommended)
- Go to https://platform.openai.com/api-keys
- Create a new API key
- Keep it secret (never share publicly)
Option B: Google Gemini
- Go to https://aistudio.google.com/apikey
- Create a new API key
- Keep it secret (never share publicly)
- Clone or download this repository
- Open Chrome and navigate to
chrome://extensions/ - Enable "Developer mode" (top-right corner)
- Click "Load unpacked" and select the
Pluralsight-Bilingual-Translatorfolder - The extension icon should appear in your toolbar
- Click the extension icon in your Chrome toolbar
- Enter your API key (OpenAI or Google Gemini)
- Select your API provider
- Choose your target language (default: Vietnamese)
- Click "Save Settings"
- Navigate to a Pluralsight course with English subtitles
- Enable subtitles in the video player
- The extension will automatically detect and translate subtitles
- Translations appear in yellow italic text below the English subtitle
{
"manifest_version": 3,
"permissions": ["storage", "scripting"],
"host_permissions": ["https://www.pluralsight.com/*"],
"action": { "default_popup": "popup.html" },
"background": { "service_worker": "background.js" },
"content_scripts": [...]
}The content.js implements a robust MutationObserver strategy:
// Detects changes in subtitle DOM
const observer = new MutationObserver((mutations) => {
handleSubtitleMutation(mutations);
});
observer.observe(subtitleContainer, {
childList: true, // Watch for added/removed nodes
subtree: true, // Observe all descendants
characterData: true // Watch for text changes
});Selector Strategy:
- Searches multiple possible subtitle selectors to handle different Pluralsight player versions
- Fallback mechanism if initial selectors fail
- Retry logic with 2-second intervals
Subtitle Text Detected (content.js)
↓
Generate Hash (for caching)
↓
Check Translation Cache
↓
If Not Cached → Send to API (message passing to background.js)
↓
API Response (OpenAI or Gemini)
↓
Cache Result + Inject into DOM
↓
Display with Yellow Styling
OpenAI GPT-3.5-turbo:
POST https://api.openai.com/v1/chat/completions
Header: Authorization: Bearer {API_KEY}
Body: {
"model": "gpt-3.5-turbo",
"messages": [
{"role": "system", "content": "You are a tech translator..."},
{"role": "user", "content": "Original subtitle text"}
]
}Google Gemini:
POST https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent?key={API_KEY}
Body: {
"contents": [{"role": "user", "parts": [{"text": "..."}]}]
}- Cache Structure:
Map<hash, { original, translation }> - Persistence: Cached data stored in
chrome.storage.local - Hash Function: Simple numeric hash of subtitle text
- Benefits:
- Prevents duplicate API calls when rewinding
- Reduces API costs
- Improves performance
- Vietnamese (default)
- Spanish
- French
- German
- Japanese
- Chinese (Simplified)
To add more languages, edit popup.html and add options:
<option value="[Language Name]">[Display Name]</option>Sent to LLM for every translation:
You are a tech translator. Translate the following technical sentence to {language}
concisely. Do not add explanations.
Customize by editing background.js:
const SYSTEM_PROMPT = `Your custom prompt here...`;- OpenAI:
gpt-3.5-turbo(setmodelinbackground.jsfor GPT-4) - Gemini:
gemini-pro
Change to GPT-4 in background.js:
model: 'gpt-4' // Requires GPT-4 API access✅ API Keys Stored Securely:
- Keys stored in
chrome.storage.sync(encrypted by Chrome) - Never logged or sent to external services except the API provider
- User controls what data is sent
✅ No Data Collection:
- No analytics or tracking
- No server backend
- Direct API calls only
✅ Best Practices:
- Never commit API keys to version control
- Use environment variables or
.envfiles if developing locally - Consider using restricted API keys with usage limits
-
Check if extension is enabled:
- Go to
chrome://extensions/ - Verify the extension is toggled ON
- Go to
-
Verify API key:
- Click extension icon → Check if API key is saved
- Test API key directly at OpenAI/Gemini console
-
Check Console:
- Right-click on Pluralsight video → Inspect → Console
- Look for
[Pluralsight Translator]log messages - Check for API errors
-
Ensure subtitles are enabled:
- Enable subtitles in the Pluralsight video player (CC button)
- Translator only works if subtitles are visible
"401 Unauthorized"
- Invalid API key
- Check if API key is correctly copied
- Ensure key hasn't expired
"429 Rate Limited"
- Exceeded API usage quota
- OpenAI: Check billing and limits at https://platform.openai.com/account/billing/limits
- Gemini: Check quotas at Google Cloud Console
"Invalid subtitle container"
- Pluralsight changed the subtitle DOM structure
- Check console for clues about new selectors
- Pluralsight player update may be needed
- Too many API calls? Cache is working - check
chrome://extensionsand click "Details" → "Inspect Views" → Service Worker - Subtitle detection slow? Browser performance - close other tabs or reduce cache size
- Video freezing? API response slow - try a different API provider
If Pluralsight updates their video player and subtitles aren't detected:
- Open the Pluralsight video
- Right-click → Inspect → Elements tab
- Locate the subtitle text in the DOM
- Find the parent container class name
- Edit
content.jsline ~104 to add the new selector:
const selectors = [
'.player-subtitles span',
'[class*="subtitle"] span',
'.your-new-selector span', // Add here
// ...
];- Chrome Extensions Manifest V3 Docs
- MutationObserver API
- Chrome Storage API
- OpenAI API Docs
- Google Gemini API Docs
Edit content.js around line 180:
translationElement.style.cssText = `
color: #FFD700; // Change color (yellow)
font-size: inherit; // Font size
font-style: italic; // Make it italic
opacity: 0.95; // Transparency
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); // Shadow
`;Currently unlimited. To limit cache, edit content.js:
if (translationCache.size > 1000) {
// Delete oldest entries or clear all
translationCache.clear();
}This project is provided as-is for educational purposes. Respect API provider terms of service when using OpenAI or Google Gemini.
To improve this extension:
- Test with various Pluralsight courses
- Report selector issues if subtitles aren't detected
- Suggest language additions or styling improvements
- Test with both OpenAI and Gemini APIs
- API Costs: Every subtitle translation costs money (OpenAI/Gemini). Monitor your API usage.
- Internet Required: Extension needs internet for API calls
- Pluralsight Only: Currently designed for Pluralsight.com; may not work elsewhere
- Rate Limiting: APIs may rate-limit you if translating too many subtitles quickly
- Hotkey to toggle translation on/off
- Custom prompt engineering UI
- Translation history log
- Multiple subtitle track support
- Offline translation (local models)
- Dark mode for popup
- Statistics dashboard (translations done, API costs)
Happy Learning with Bilingual Translations! 🌍
Stashed changes