Claude Skills Guide

Chrome Extension Auto Caption Video: Building Real-Time Subtitling Tools

Automatic video captioning has become essential for accessibility, language learning, and content consumption in noisy environments. Building a Chrome extension that adds real-time captions to videos opens up powerful possibilities for developers and power users. This guide walks through the technical implementation using the Web Speech API and Chrome extension APIs.

Understanding the Architecture

A Chrome extension for auto-captioning video operates at the intersection of content scripts, background workers, and browser APIs. The core challenge is capturing audio from video elements on a page and feeding it to a speech recognition system in real time.

The architecture consists of three main components:

  1. Content script - Injected into web pages to detect video elements and capture audio
  2. Speech recognition service - Uses the Web Speech API to transcribe spoken content
  3. Caption overlay - Renders synchronized text on top of the video

This separation allows the extension to work across different video platforms without requiring platform-specific code.

Setting Up the Extension Structure

Every Chrome extension needs a manifest file. For a video captioning extension, you’ll need permissions to access active tabs and potentially inject scripts into video hosting sites.

{
  "manifest_version": 3,
  "name": "Auto Video Caption",
  "version": "1.0",
  "permissions": ["activeTab", "scripting"],
  "host_permissions": ["*://*.youtube.com/*", "*://*.vimeo.com/*"],
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }]
}

The host permissions array should include the video platforms where you want captions to appear. You can expand this to support Netflix, Coursera, or any other video streaming service.

Detecting Video Elements

The content script runs on every page load and must identify video elements. Modern websites use various selectors for video players, so you’ll need a robust detection strategy.

// content.js
function findVideoElements() {
  const selectors = [
    'video',
    '[class*="video-player"]',
    '[data-component="video"]',
    'iframe[src*="video"]'
  ];
  
  let videos = [];
  for (const selector of selectors) {
    videos = videos.concat(
      Array.from(document.querySelectorAll(selector))
    );
  }
  
  return videos.filter(v => v.offsetParent !== null);
}

function initializeCaptioning() {
  const videos = findVideoElements();
  videos.forEach(video => {
    if (!video.dataset.captionEnabled) {
      video.dataset.captionEnabled = 'true';
      attachCaptionEngine(video);
    }
  });
}

The initialization function runs after the page loads and periodically checks for new video elements that might appear dynamically.

Implementing Speech Recognition

The Web Speech API provides SpeechRecognition (or webkitSpeechRecognition in Chrome) for converting speech to text. This API runs entirely in the browser without requiring backend services.

class VideoCaptionEngine {
  constructor(videoElement) {
    this.video = videoElement;
    this.recognition = new webkitSpeechRecognition();
    this.recognition.continuous = true;
    this.recognition.interimResults = true;
    this.recognition.lang = 'en-US';
    
    this.setupRecognitionHandlers();
    this.createCaptionOverlay();
  }
  
  setupRecognitionHandlers() {
    this.recognition.onresult = (event) => {
      let transcript = '';
      for (let i = event.resultIndex; i < event.results.length; i++) {
        transcript += event.results[i][0].transcript;
      }
      this.updateCaption(transcript);
    };
    
    this.recognition.onerror = (event) => {
      console.error('Speech recognition error:', event.error);
    };
  }
  
  createCaptionOverlay() {
    this.overlay = document.createElement('div');
    this.overlay.className = 'auto-caption-overlay';
    this.overlay.style.cssText = `
      position: absolute;
      bottom: 60px;
      left: 50%;
      transform: translateX(-50%);
      background: rgba(0, 0, 0, 0.8);
      color: white;
      padding: 8px 16px;
      border-radius: 4px;
      font-family: Arial, sans-serif;
      font-size: 16px;
      max-width: 80%;
      text-align: center;
      z-index: 9999;
    `;
    
    const container = this.video.parentElement;
    container.style.position = 'relative';
    container.appendChild(this.overlay);
  }
  
  updateCaption(text) {
    this.overlay.textContent = text;
  }
  
  start() {
    this.recognition.start();
  }
  
  stop() {
    this.recognition.stop();
  }
}

The caption overlay uses absolute positioning to appear above the video. Adjust the positioning based on the specific video player you’re targeting.

Handling Audio Sources

The Web Speech API listens to the default microphone input, not the audio playing through the video element. This creates a challenge: the API expects live microphone input rather than processed audio from a video.

Two approaches solve this limitation:

Option 1: Use the Tab Capture API

The chrome.tabCapture API lets you capture the audio from a specific tab. This works well but requires additional permissions and user consent.

async function captureTabAudio(tabId) {
  const stream = await chrome.tabCapture.capture({
    audio: true,
    video: false
  });
  
  const audioContext = new AudioContext();
  const source = audioContext.createMediaStreamSource(stream);
  // Connect to speech recognition...
}

Option 2: Rely on system audio

On systems where system audio routes to the default microphone (some configurations on macOS and Windows), the standard Web Speech API can capture video audio. This is less reliable but requires fewer permissions.

For production extensions, the Tab Capture approach provides more consistent results across different operating systems and browser configurations.

Improving Recognition Accuracy

Speech recognition quality varies significantly based on several factors. Implement these enhancements to improve accuracy:

Language matching: Set the recognition language to match the video content.

// Detect video language from page content or URL
function detectLanguage() {
  const htmlLang = document.documentElement.lang;
  const url = window.location.href;
  
  if (url.includes('.jp/')) return 'ja-JP';
  if (url.includes('.de/')) return 'de-DE';
  if (url.includes('.fr/')) return 'fr-FR';
  
  return htmlLang || 'en-US';
}

Context hints: Provide phrase hints specific to the video content.

this.recognition.onstart = () => {
  // Extract potential terms from page title
  const title = document.title.split(' - ')[0];
  // Use custom grammar for better recognition
};

Managing Extension State

Power users expect control over caption behavior. Add toggle functionality and customization options.

function attachCaptionEngine(video) {
  const engine = new VideoCaptionEngine(video);
  
  // Toggle captions with keyboard shortcut
  video.addEventListener('keydown', (e) => {
    if (e.key === 'c' && e.altKey) {
      if (engine.isRunning) {
        engine.stop();
      } else {
        engine.start();
      }
    }
  });
  
  // Auto-start for videos over 2 minutes
  if (video.duration > 120) {
    engine.start();
  }
}

Platform-Specific Considerations

Different video platforms require different approaches:

Create platform-specific detection logic to handle these differences gracefully.

Building and Testing

Load your extension in Chrome through chrome://extensions/, enable Developer mode, and click “Load unpacked”. Test across different video sites to verify compatibility.

For debugging, the content script console provides immediate feedback:

console.log('Auto Caption: Video detected', video.src);
console.log('Auto Caption: Recognition started');

Conclusion

Building a Chrome extension for auto-captioning video combines web APIs, browser extension architecture, and speech recognition technology. The Web Speech API provides accessible speech-to-text capabilities, while content scripts enable injection into any video page.

The key challenges involve capturing system audio, handling platform-specific video players, and managing recognition accuracy across different audio environments. Start with the basic implementation and iterate based on user feedback and testing results.

For developers interested in extending this functionality, consider adding support for multiple languages, exporting captions as SRT files, or integrating with external transcription services for higher accuracy.

Built by theluckystrike — More at zovo.one