MeTube Sender

ChromeArcManifest V3No build step

YouTube → your MeTube,
in one right-click.

MeTube Sender sends videos, shorts and playlists to your self-hosted MeTube from any page, then plays what MeTube downloaded in an overlay, right on top of YouTube.

Free and open source. A zip with its SHA-256 checksum on every release.

🔒youtube.com/watch?v=aqz-KE-bpKQ
Big Buck Bunny (2008) · 4K
Open link in new tab
Open link in new window
Copy link address
MeTube›
Inspect
MeTube settings…
Open MeTube
Video · 1080p · MP4
Audio · M4A
Subtitles · French + English (SRT)
More video qualities
More audio formats
Subtitles in one language
MeTube
Current page
Big Buck Bunny (2008) · 4K
Play
4 YouTube linksAllNone
  • Sintel (2010) · Blender Foundation✓
  • Tears of Steel · Official trailer✓
  • Caminandes 3 · Llamigos✓
  • Spring · Blender Open Movie✓
Send selected
Big Buck Bunny (2008) · 4K
Looking up this video in MeTube…
— Subtitles, right where you left YouTube.
0:00 / 9:56
Video finished
Delete from MeTube Watch again Keep and close
Space play/pause · ←/→ 5s · F fullscreen · C subtitles · M mute · Del delete · Esc close

Any page, any YouTube link.

One right-click, and it's on its way to MeTube, in the quality you chose.

Or open the popup: it lists every video on the page. Tick, send.

Then press Alt+Shift+M and watch it from MeTube, right on YouTube.

Watched once? Delete it from MeTube. Done.

What it does

Every way to send a video, and one way to watch it.

Video · 1080p · MP4 Audio · M4A Subtitles · French + English (SRT)

Right-click menu

One MeTube entry on links, pages, selected text and the YouTube player. Three blocks (video, audio, subtitles), with the entries, the one-click choices and the layout you decide.

Sintel (2010)✓ Tears of Steel✓ Caminandes 3✓

Popup that scans the page

The toolbar button lists the videos, shorts and playlists linked from the current page, embedded players included, with their titles. Tick some or all, then send. Audio only is one toggle away.

Player on YouTube

On a video page, Alt+Shift+M opens the video from MeTube in an overlay: it resumes where you were, shows the download's progress if it's still running, and plays your subtitles.

youtu.be/aqz-KE-bpKQ?si=x7Kq…&feature=shareyoutube.com/watch?v=aqz-KE-bpKQ

Clean URLs

YouTube links are cut down to v, list and t: no si, pp, feature or index. Short, mobile, live and embed links become the standard watch URL. Other sites pass through unchanged, since MeTube takes everything yt-dlp does.

3!

Feedback you can see

The badge counts what was sent. A red ! means something failed: open the popup to read why. When the browser shows notifications, you get one too.

ENFR

English and French

Menus, popup, settings, player, notifications and errors follow the browser's language, numbers and sizes included (1.2 GB, 1,2 Go). Adding a language is one JSON file.

Install

Three clicks in your browser. No store needed.

Download the latest metube-sender-<version>.zip and unzip it into a folder you'll keep. To run the unreleased code instead, clone the repository.

  1. Open chrome://extensions.
  2. Turn on Developer mode (top-right toggle).
  3. Click Load unpacked and select the folder that contains manifest.json.
  4. The settings page opens. Enter your MeTube URL, Save, Allow, Test connection.
  5. Optional: click the puzzle icon and pin MeTube Sender, so its badge is always visible.
  6. Pin the extension (extensions menu in the sidebar / URL bar) to reach the popup and see the badge. Arc rarely shows extension notifications: the badge and the popup show every result anyway.

Keyboard shortcut

The player's shortcut is Alt+Shift+M (Option+Shift+M on a Mac). To change it, or if another extension already took it, open chrome://extensions/shortcuts and edit Play the current YouTube video from MeTube. The settings page shows the current shortcut and has a Change shortcut button.

Updating

Unzip the new release into the same folder, replacing its files (or pull the new code), then click the reload icon on the extension's card. Loading it from a different folder installs a second extension, without your settings.

Configure

One URL, and you're connected.

When you click Save, the browser asks for permission to access your MeTube host: click Allow. Then Test connection calls /version and shows the MeTube and yt-dlp versions it finds.

MeTube URL
e.g. https://metube.example.com. If MeTube runs under a path prefix (URL_PREFIX), include it: https://example.com/metube.
Username / Password
Sent as Authorization: Basic … with every request, e.g. for Traefik basicAuth. Leave both empty if MeTube isn't behind auth.
Download type / Format / Quality
Defaults for every send. Video: format Any or MP4, quality Best, 2160p … 240p or Worst. Audio: M4A, MP3 or Opus, with the qualities MeTube accepts for each format.
Folder
Optional sub-folder of MeTube's download directory. MeTube must run with CUSTOM_DIRS=true, plus CREATE_CUSTOM_DIRS=true if the folder doesn't exist yet.
Right-click menu
Layout, where it appears, and the entries of each block. See Right-click menu.
Subtitle languages
Languages the player looks for, comma-separated (default fr, en). They must match the subtitleslangs MeTube downloads. The menu's subtitles block uses the same list.
When a video ends, offer to delete it
On by default. See Deleting a video.

All settings, including the password, are stored in this browser's extension storage (chrome.storage.local). They are never sent anywhere except to your MeTube host.

Player on YouTube

Watch it from MeTube, without leaving YouTube.

On a youtube.com/watch?v=… page, press the shortcut or click Play in the popup. The overlay pauses YouTube's player, notes where you were, and looks the video up in MeTube's history by video ID. Then:

Already downloaded

Plays the file. If you had watched more than 5 seconds on YouTube, it starts from there.

Queued or downloading

Shows the progress, refreshed every 2 seconds, and starts playing when the download finishes.

Not in MeTube

Adds it with your default options, then shows the progress.

Failed in MeTube

Shows MeTube's error (private, age-restricted, removed…), with Try again.

Keyboard

  • SpaceKplay / pause
  • ←→seek 5 seconds
  • Ffullscreen (or double-click the picture)
  • Csubtitles on / off
  • Mmute
  • Deldelete from MeTube
  • Escclose (YouTube stays paused)

Play/pause, seeking, volume, speed (0.5× to 2× in the ⋯ menu), subtitles, picture-in-picture and fullscreen are in the control bar. The overlay also closes when you navigate to another video.

Deleting a video

The player is for watching a video once, while YouTube streaming is out of reach. Once watched, the file can go:

  • Trash button or Del: a confirmation shows the title, quality, size and subtitles. Cancel is selected, so Enter never deletes by accident.
  • When the video ends (unless turned off in the settings): Delete from MeTube, Watch again, or Keep and close. Nothing is deleted without a click.

After deleting, the extension checks whether the file is really gone from the server and says so. MeTube only erases files when it's set up for it: see Server setup.

How the video gets past basic auth

A <video> element can't send an Authorization header. The extension adds one with a declarativeNetRequest rule, rebuilt whenever you save the settings. The rule only applies to GET requests for media, started by the extension's own player, to your MeTube URL. Requests made by YouTube or any other site never get your credentials, so a web page can't use them to add or delete downloads. Every other request (/history, /add, subtitle files) is sent by the service worker.

MeTube server setup

Three lines on the server, for the full experience.

Sending works with any MeTube. The player wants a little more: subtitles written next to the videos, HTTPS, and permission to erase files.

Subtitles

MeTube only writes subtitle files if yt-dlp is told to. Add this to MeTube's environment, with the same languages as in the extension's settings. yt-dlp then saves <video>.<lang>.vtt next to each video, and the player loads each one it finds. Only videos downloaded after this change have subtitles.

YTDL_OPTIONS={"writesubtitles": true, "writeautomaticsub": true, "subtitleslangs": ["fr","en"], "subtitlesformat": "vtt"}

Deleting files

MeTube's default (DELETE_FILE_ON_TRASHCAN=false) only removes the entry from its list and keeps the file. For the player's delete button to erase files, add the line below. true also works, but then MeTube's own trash button always erases files too. With the default, the player tells you the file was kept.

DELETE_FILE_ON_TRASHCAN=ask

HTTPS

YouTube is an HTTPS page, and browsers won't load http:// video inside it. MeTube must be reachable over https://, for example through Traefik with a certificate. localhost is the only exception.

Default download URLs

The player expects MeTube's standard file URLs: {MeTube URL}/download/…, or /audio_download/… for audio. If you changed PUBLIC_HOST_URL to serve files from elsewhere, the player won't find them.

One entry per video

MeTube keeps one history entry per video URL. Downloading the audio or the subtitles of a video that's already downloaded replaces its entry (the video file stays on disk); the player then no longer finds the video and would download it again. For subtitles to watch with, prefer YTDL_OPTIONS; use the menu's subtitles block to get the files themselves.

Formats

The browser must be able to play the file. MP4 (H.264/AAC) and WebM play everywhere. If you get can't play this file, set the default video format to MP4 in the settings.

Example docker-compose.yml

A MeTube service with everything the extension can use. Put it behind your HTTPS reverse proxy.

services:
  metube:
    image: ghcr.io/alexta69/metube
    container_name: metube
    restart: unless-stopped
    ports:
      - "8081:8081"
    volumes:
      - ./downloads:/downloads
    environment:
      # Optional "Folder" setting in the extension
      - CUSTOM_DIRS=true
      - CREATE_CUSTOM_DIRS=true
      # Player: subtitles next to each video, same languages as the extension
      - YTDL_OPTIONS={"writesubtitles":true,"writeautomaticsub":true,"subtitleslangs":["fr","en"],"subtitlesformat":"vtt"}
      # Player: the delete button really erases the file
      - DELETE_FILE_ON_TRASHCAN=ask
How MeTube treats some links
  • t= timestamps: current MeTube versions turn a t parameter into the start of a clip, so watch?v=…&t=90 downloads from 1:30 onward. To get the whole video, send a link without t.
  • Videos opened from a playlist (watch?v=…&list=…): the popup tags these In playlist. Whether MeTube downloads only that video or the whole playlist depends on its strict playlist mode (DEFAULT_OPTION_PLAYLIST_STRICT_MODE).
  • Private lists that need your YouTube login are ignored: Watch later (WL), Liked videos (LL) and Liked music (LM).

Troubleshooting

What the message means, and what to do.

Authentication failed (401)

Check the username and password in the settings.

Can't reach host

The URL is wrong, the server is down, or it's unreachable from this machine (VPN, DNS, TLS certificate).

Not found (404)

The URL is missing MeTube's path prefix, or points to the wrong service.

MeTube rejected the request (400): …

MeTube refused the options; the reason comes from MeTube. Example: a folder was set but CUSTOM_DIRS is off.

did not answer with JSON

Something other than MeTube answered, such as a login page from Authelia or Authentik, or a proxy error page. Basic auth is the only login method this extension supports.

not allowed to access …

Open the settings and click Save, then Allow. If no prompt appears, go to the extension's Details page → Site access and add your MeTube site.

Popup: Can't scan this page

Browser pages (chrome://, arc://, the Web Store) can't be read by extensions. Send page still works for normal web pages.

Player: MeTube couldn't download this video

MeTube's own error is shown below it (private, age-restricted, removed…). Try again re-adds the video.

Player: the file isn't on the server anymore

The download was deleted from disk but is still in MeTube's history. Download again re-adds it.

Player: won't load http:// video

Serve MeTube over HTTPS (see Server setup).

Player: can't play this file

The browser doesn't support the file's format. Set the default video format to MP4.

Player: no subtitles

Check YTDL_OPTIONS (see Server setup), and that the languages match. Videos downloaded before the change have none.

Player: the server kept the file

MeTube removed the entry but not the file: run it with DELETE_FILE_ON_TRASHCAN=ask.

A menu entry is missing

Check Right-click menu in the settings (block turned off, quality not selected, context unchecked). Subtitles need at least one Subtitle language.

The shortcut does nothing

Another extension may use it: set a different one (see Keyboard shortcut). It only works on youtube.com/watch?v=… pages.

Permissions and privacy

Nothing leaves your browser, except toward your MeTube.

Every network call is made by the background service worker, never by the pages you visit. The player page is the only file YouTube pages can load from the extension.

Development

Plain JavaScript. Clone, load, hack.

No build step, no dependencies to install. The only library, Media Chrome for the player, is vendored (Manifest V3 doesn't allow loading code from the internet). Tests need Node 22+.

Test and build

git clone https://github.com/CostardRouge/metube-extension.git
cd metube-extension
node --test              # unit tests
scripts/build.sh         # dist/metube-sender-<version>.zip
scripts/build.sh 1.2.0   # or with a given version

The CI workflow runs the tests and builds the zip on every pull request and push to main. The zip stays attached to the run for 14 days, to try a change before it's released.

Releasing

git checkout main && git pull
git tag v1.1.0
git push origin v1.1.0

Releases are only created from a version tag on main. The Release workflow runs the tests, builds the zip with that version written into its manifest.json, and publishes a GitHub release with the zip, its SHA-256 checksum and notes from the merged pull requests.

Where things are
manifest.json
background.js            service worker entry: registers listeners, routes messages
sw/                      menus, sending, feedback, player requests, the auth rule
lib/                     settings, i18n, menu model, MeTube API client, history, YouTube URLs
content/overlay-host.js  injected into YouTube on demand: the overlay iframe, pause, navigation
overlay/                 the player page shown in that iframe
popup/  options/  ui/    toolbar popup, settings page, shared dark theme
_locales/                English (default) and French messages
vendor/media-chrome/     Media Chrome (MIT), unmodified ES modules
tests/                   URL handling, history matching, menus, messages, the manifest, this site
docs/                    this website (GitHub Pages)