Skip to content

Repository files navigation

SubPIP — Subtitles-Aware Picture-in-Picture for the Web

A browser extension that creates a smart Picture-in-Picture video window that includes subtitles, even on websites where normal PiP drops them.

🎯 What is SubPIP?

Most websites render subtitles as HTML overlays on top of videos. When Picture-in-Picture is activated, browsers only send the raw video stream to the PiP window, causing subtitles to disappear.

SubPIP fixes this by building a real-time synthetic video pipeline:

  1. Captures the video frames into a canvas
  2. Extracts subtitle text and timing
  3. Renders the subtitles directly onto the video frames
  4. Streams the combined result into a Picture-in-Picture window

The PiP window therefore shows exactly what the user sees on the page — video + subtitles — but floating.

✨ Features

  • 📺 Works with any HTML5 video element
  • 💬 Supports WebVTT & site-rendered subtitles (YouTube, Vimeo, Coursera, etc.)
  • 🖼️ Burns subtitles into the PiP stream in real time
  • 🎥 Uses canvas → MediaStream → Picture-in-Picture
  • 🪟 Creates a fully subtitle-aware PiP window
  • 🔌 Runs as a browser extension (Chrome / Firefox compatible)

🏗️ Technical Architecture

HTML5 Video
     ↓
Frame Capture
     ↓
Canvas Renderer
     ↓
Subtitle Extractor
     ↓
Text Overlay
     ↓
Canvas Stream
     ↓
Synthetic MediaStream
     ↓
Picture-in-Picture

The extension does not rely on the browser's built-in PiP compositor. It creates its own video pipeline so subtitles become part of the pixels.

📦 Installation

Chrome / Edge / Brave

  1. Clone or download this repository
  2. Open your browser and navigate to chrome://extensions/
  3. Enable "Developer mode" in the top right corner
  4. Click "Load unpacked"
  5. Select the SubPip directory
  6. The extension should now appear in your extensions list

Firefox

  1. Clone or download this repository
  2. Open your browser and navigate to about:debugging#/runtime/this-firefox
  3. Click "Load Temporary Add-on"
  4. Select the manifest.json file in the SubPip directory
  5. The extension should now be installed

🚀 Usage

  1. Navigate to a website with a video (e.g., YouTube, Vimeo, Coursera)
  2. Make sure subtitles are enabled on the video
  3. Click the SubPIP extension icon in your browser toolbar
  4. Click "Enable SubPIP"
  5. The Picture-in-Picture window will open with subtitles burned in
  6. To disable, click the extension icon again and click "Disable SubPIP"

⌨️ Keyboard Shortcuts

When SubPIP is active, you can use these keyboard shortcuts:

  • Spacebar / K - Play/Pause
  • Left Arrow - Seek back 10 seconds
  • Right Arrow - Seek forward 10 seconds
  • C - Toggle subtitles
  • S - Open Settings
  • ? / / - Show help

⚙️ Settings

Click the "Settings" button in the popup to customize:

  • Subtitle font size (12-48px)
  • Subtitle font color
  • Subtitle background color
  • Subtitle background opacity

ℹ️ About

Click the "About" link in the popup footer to learn more about SubPIP, its features, and how it works.

🎬 Supported Sites

SubPIP works with any HTML5 video element. It has special support for:

  • YouTube - Extracts captions from YouTube's custom caption system
  • Vimeo - Extracts captions from Vimeo's caption display
  • Coursera - Extracts subtitles from Coursera's video player
  • Any site with WebVTT - Uses native text track API

⚠️ Limitations

DRM-Protected Content

DRM-protected platforms (Netflix, Disney+, Prime Video, etc.) block video capture and will not work with SubPIP. This is a browser security restriction that cannot be bypassed.

Performance

  • Higher CPU/GPU usage compared to native PiP due to real-time canvas rendering
  • Subtitle styling is simplified for performance

Browser Compatibility

  • Chrome/Edge/Brave: Full support
  • Firefox: Full support
  • Safari: Not supported (different extension model)

🔧 Development

Project Structure

SubPip/
├── manifest.json          # Extension manifest
├── popup.html            # Extension popup UI
├── popup.css             # Popup styles
├── popup.js              # Popup logic
├── background.js         # Service worker
├── content.js            # Content script (main logic)
├── icons/                # Extension icons
│   ├── icon16.png
│   ├── icon48.png
│   └── icon128.png
└── README.md             # This file

Key Components

content.js

The main content script that:

  • Finds video elements on the page
  • Extracts subtitles from various sources
  • Captures video frames to canvas
  • Renders subtitles onto frames
  • Creates MediaStream from canvas
  • Launches Picture-in-Picture

background.js

Service worker that:

  • Manages active SubPIP sessions
  • Handles cross-tab communication
  • Updates extension badge

popup.js

Popup UI that:

  • Shows current status
  • Enables/disables SubPIP
  • Communicates with content script

Adding Support for New Sites

To add support for a new video platform, create a new subtitle extractor class in content.js:

class NewSiteSubtitleExtractor {
    constructor() {
        this.currentText = null;
        this.observer = null;
    }
    
    initialize() {
        this.startMonitoring();
    }
    
    startMonitoring() {
        // Set up DOM monitoring
    }
    
    extract() {
        // Extract subtitle text from DOM
    }
    
    getCurrent() {
        if (this.currentText) {
            return { text: this.currentText };
        }
        return null;
    }
    
    hasSubtitles() {
        return this.currentText !== null;
    }
    
    cleanup() {
        // Clean up observers
    }
}

Then add it to the setupSiteSpecificExtractor() method in the SubtitleExtractor class.

🤝 Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

📄 License

This project is open source and available under the MIT License.

🙏 Acknowledgments

SubPIP was created to solve a common problem faced by language learners, accessibility users, and multitaskers who want to watch subtitled content while working.

📞 Support

If you encounter any issues or have questions, please open an issue on the project repository.

☕ Support the Project

If you find SubPIP helpful and want to support its continued development, consider buying me a coffee! Your support helps keep this project free and actively maintained.

☕ Buy me a coffee


Tagline: "Picture-in-Picture, but it actually shows what you're watching."

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages