Skip to content

alexrel/CastFlow-EXT

Repository files navigation

CastFlow

Sleek, lightweight browser extension for opening direct video links (.mp4, .m3u8, .webm) from Firefox or Chromium in external media players (mpv/VLC).

Why CastFlow? (Motivation)

Watching high-definition video streams directly inside a web browser on low-end hardware, such as a Raspberry Pi, often causes severe CPU bottlenecks, frame drops, and lag. This is due to heavy browser rendering engines and the lack of efficient hardware-accelerated video decoding in web browsers on ARM-based or low-spec devices.

CastFlow solves this by:

  • Zero-overhead redirection: It catches video stream URLs, referrers, and session cookies directly from your web traffic.
  • Hardware-accelerated playback: It forwards the stream to a native external player (mpv or VLC) via a lightweight Native Messaging host.
  • Optimized performance: Media players render streams directly with native GPU acceleration, resulting in smooth, stutter-free playback and significantly lower CPU usage and temperatures on your Pi.

What it does

  • Watches network requests and simple DOM video/source/link URLs.
  • Stores recent video URLs per browser tab.
  • Popup shows the captured URLs.
  • Buttons launch mpv or VLC through a Native Messaging host.
  • Native host accepts only http(s) URLs and launches the player without a shell.

Project Structure & Shared Architecture

To maximize code reuse and avoid duplication, the source files for both Firefox and Chromium extensions are unified in the src/ directory.

  • src/: Contains the core logic (background.js, content.js, popup.js, popup.html, popup.css).
  • extension-firefox/: Contains only Firefox-specific settings (manifest.json using Manifest V2).
  • extension-chromium/: Contains only Chromium-specific settings (manifest.json using Manifest V3).
  • build.sh: Copies files from src/ to both extension directories for local loading/testing.
  • package.sh: Runs build.sh and then archives the extensions into the dist/ directory.

Configure sites

Edit src/background.js:

const ALLOWED_PAGE_HOSTS = ["example.com", "video.example.net"];

Leave it empty while testing:

const ALLOWED_PAGE_HOSTS = [];

Firefox install

Before loading or packaging, make sure to compile the shared files:

cd CastFlow
./build.sh

On the Pi:

./install_native_host.sh firefox

Then open Firefox:

  1. Go to about:debugging#/runtime/this-firefox.
  2. Click Load Temporary Add-on.
  3. Select extension-firefox/manifest.json.
  4. Start a video on a target site.
  5. Open the extension popup and click Open mpv or Open VLC.

Pre-built Signed Add-on

A pre-built, signed Firefox addon is committed and ready to install at: dist/firefox-signed/247d4b86c0534abaa496-0.1.0.xpi

For permanent installation on regular Firefox Release, you can simply install this .xpi file. For temporary testing, use the Load Temporary Add-on flow.

Packaging

Each browser extension is independent. Build separate archives with:

cd CastFlow
./package.sh

This creates:

dist/open-video-in-player-firefox.zip
dist/open-video-in-player-firefox-unsigned.xpi
dist/open-video-in-player-chromium.zip
dist/open-video-native-host.zip

The Firefox and Chromium zips contain only extension files. The native host is intentionally separate because browsers do not allow an extension package to install or run local programs by itself.

Normal Firefox will not permanently install an unsigned local .xpi; it shows "This add-on could not be installed because it has not been verified."

For Firefox temporary testing, use Load Temporary Add-on against extension-firefox/manifest.json:

about:debugging#/runtime/this-firefox

For a permanent Firefox add-on, submit/sign open-video-in-player-firefox.zip through Mozilla's add-on signing flow. Choose unlisted/self-distributed signing if this extension is only for you. The signed .xpi can then be installed normally.

open-video-in-player-firefox-unsigned.xpi is only a convenience artifact for Developer Edition/Nightly or other Firefox builds where unsigned extensions are allowed. It will not install in regular Firefox Release.

Firefox self-distributed signing with web-ext

  1. Create AMO API credentials:
https://addons.mozilla.org/en-US/developers/addon/api/key/
  1. Export them in your shell:
export WEB_EXT_API_KEY="..."
export WEB_EXT_API_SECRET="..."
  1. Sign as unlisted/self-distributed:
./sign_firefox_self_distributed.sh

The signed .xpi will appear in:

dist/firefox-signed/

Install that signed .xpi in regular Firefox.

For Chromium local use, running ./build.sh and then doing Load unpacked from extension-chromium is simplest. If you pack it into a .crx, keep the generated private key so the extension ID stays stable; the native host manifest must contain that exact Chromium extension ID.

Chromium install

Before loading or packaging, make sure to compile the shared files:

cd CastFlow
./build.sh

On the Pi:

  1. Open chrome://extensions.
  2. Enable Developer mode.
  3. Click Load unpacked.
  4. Select extension-chromium.
  5. Copy the extension ID shown by Chromium.

Then run:

cd CastFlow
./install_native_host.sh chromium EXTENSION_ID_FROM_CHROMIUM

Restart Chromium after installing the native host.

On macOS, this installs to:

~/Library/Application Support/Chromium/NativeMessagingHosts/com.local.open_video.json

For Google Chrome instead of Chromium:

./install_native_host.sh chrome EXTENSION_ID_FROM_CHROME

Native host installer paths

The installer supports Linux, macOS, and Windows:

python3 install_native_host.py firefox
python3 install_native_host.py chromium EXTENSION_ID_FROM_CHROMIUM
python3 install_native_host.py chrome EXTENSION_ID_FROM_CHROME

Convenience wrappers:

./install_native_host.sh chromium EXTENSION_ID
install_native_host.bat chromium EXTENSION_ID

It writes manifests here:

Linux Firefox:   ~/.mozilla/native-messaging-hosts/com.local.open_video.json
Linux Chromium:  ~/.config/chromium/NativeMessagingHosts/com.local.open_video.json
Linux Chrome:    ~/.config/google-chrome/NativeMessagingHosts/com.local.open_video.json
macOS Firefox:   ~/Library/Application Support/Mozilla/NativeMessagingHosts/com.local.open_video.json
macOS Chromium:  ~/Library/Application Support/Chromium/NativeMessagingHosts/com.local.open_video.json
macOS Chrome:    ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.local.open_video.json
Windows:         native/generated/com.local.open_video.json plus HKCU registry entry

On Windows, Native Messaging hosts are discovered through Registry keys under:

HKCU\Software\Mozilla\NativeMessagingHosts\com.local.open_video
HKCU\Software\Chromium\NativeMessagingHosts\com.local.open_video
HKCU\Software\Google\Chrome\NativeMessagingHosts\com.local.open_video

Notes

  • This does not handle DRM.
  • This passes session cookies to the external player (for mpv) to support authenticated streams. It also passes the page URL as Referer.
  • blob: URLs cannot be opened directly; the extension tries to catch the real .m3u8/.mp4 network request instead.
  • Some sites use URLs without file extensions but correct Content-Type; the Chromium build has a small Debug section in the popup to show whether anything was caught.

About

Collects direct video URLs from selected sites and opens them in mpv or VLC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors