Here at McKinley Labs, we're always looking for new ways to wildly exceed the numbers on this chart. We don't just limit ourselves to efficiency, however. We spend far too much time working toward privacy and minimalism as well. To that end, we choose not to watch online videos in a web browser. Here's how I watch online videos using MPV, FF2MPV, yt-dlp, Streamlink, Newsboat, and assorted MPV userscripts.
Yep, it's long enough for a table of contents. We're definitely reinforcing stereotypes about free software here.
Since yt-dlp is one of the most important parts of this whole setup, I want to make it clear what that is. yt-dlp is a fork of youtube-dlc, which is a dead fork of the now deceased youtube-dl. youtube-dl, which you've probably heard of, was a terrific tool for downloading all kinds of online video content. I wrote a simple guide for it which I've kept updated (and eventually changed to reference yt-dlp). Unfortunately, it stopped receiving updates from the original developers, and a fork vacuum was created.
yt-dlp is generally considered to be the best actively maintained fork, incorporating extra features from youtube-dlc and adding some of its own. MPV, the media player we'll use and the real backbone of the setup, even updated to look for yt-dlp before youtube-dl by default in its youtube-dl integration.
MPV will play online videos using yt-dlp by default simply by passing the URL as a command line argument or typing loadfile <URL> in the console. (Default binding: `) However, it lacks some features that are important when it comes to streaming online videos. That's where this guide comes in. There are loads of guides made by people who seem to be excited about MPV's yt-dlp integration, but none of them seem to go much further than specifying the URL at the command line.
Playing videos from the command line works well, but then you have an unresponsive, uncloseable terminal window open and that's annoying if your terminal doesn't swallow. You can also use the console loadfile method from above, but it is entirely too much work to copy the URL and paste it into the console.
The professional™ way to do it is to integrate MPV into other programs to open videos in MPV effortlessly. A web browser is the first thing we'll integrate. There are several browser extensions that do something like this, using a variety of methods, but the simplest one I found is called FF2MPV. Despite the name, it can be found on both addons.mozilla.org and the Chrome Web Store. FF2MPV works by using a browser extension to talk to a simple script located elsewhere on the system that launches MPV for you. You need to have the script available somewhere on your system, and tell the browser extension where it is using a config file.
It is simple enough to get the helper script set up with the browser extension, but I would rather not document it here because of all the moving parts. The developers have up to date, easy to follow guides for Windows, GNU/Linux, and Mac OS available here.
I followed the manual procedure for Firefox on GNU/Linux, but since I use Librewolf I had to change the location of ff2mpv.json to ~/.librewolf/native-messaging-hosts/ instead of ~/.mozilla/native-messaging-hosts/. I also cloned the git repository to ~/git/ and used ff2mpv.py from there so it would be easy to update as needed by running git pull.
If all goes well, you should be able to click the MPV icon in your browser's toolbar to open the current page in MPV, or right click a link and choose "Play in MPV". After a few seconds, MPV will open playing the specified video.
Okay, now you can play videos from your browser, but how do you keep up with new uploads? RSS feeds, of course! Newsboat is a TUI feed reader available for Unix-like systems, so Windows users can move on to the next section. Sorry Windows users.
Are they gone? Good. I'm not sorry. Once you have it installed, all you have to do to make Newsboat open feed items in MPV is add the following line to ~/.newsboat/config: browser "mpv --no-terminal %u &". We tell Newsboat that MPV is our web browser, set MPV to suppress terminal output, and run it in parallel to Newsboat so Newsboat doesn't hang until the video finishes.
Newsboat won't start without any feeds, so add some to ~/.newsboat/urls, one URL per line. If you don't have any, don't worry. The next section will show you where to find them for popular online video hosts. For now, here are a few feeds from different websites for your URLs file.
https://www.youtube.com/feeds/videos.xml?channel_id=UCUnyg72UXLkT2zCjyvGOOEg https://odysee.com/$/rss/@AlphaNerd:8 https://videos.lukesmith.xyz/feeds/videos.xml?videoChannelId=2
When you have a feed item highlighted, press o (by default) and MPV will open. Neat, right? But what if you want to use MPV to view regular feeds as well, with items you'll want to open in a Web browser? Sounds like you need something a little more advanced.
To make this work, we need to do something a little bit messy with Newsboat macros. We need to make MPV our web browser according to Newsboat, open the selected item in the newly configured browser, and change it back to the real one. It's a bit of a hack, but it works and it's what the developers recommend. Here is what this looks like in the Newsboat config file. Lines beginning with "#" are comments and will be ignored by Newsboat.
# Set browser command to xdg-open so links normally open in the default Web browser # Lynx is the Newsboat default # xdg-open may not be available on your system by default. In that case, change it to whatever you'd like. browser "xdg-open %u" # Create macro # 1. Define macro "m" # 2. Perform the following 3 actions: # - Set browser command: # - Run MPV through nohup, a POSIX utility, to "detach" MPV from the terminal in which Newsboat is running # (Stops MPV from closing when you close your terminal) # - Redirect all output to /dev/null # (Stops Nohup from creating a "nohup.out" file in the current directory) # - Run in parallel # (Stops Newsboat from hanging until MPV closes) # - Open the current item in the browser noninteractively # - Set browser command back to xdg-open # 3. Set help menu description to "Open in MPV" macro m set browser "nohup mpv %u > /dev/null 2> /dev/null &" ; open-in-browser-noninteractively ; set browser "xdg-open %u" -- "Open in MPV"
Now, when we have an item focused, we can press o to open it in the Web browser as normal. To open it in MPV, press the macro prefix button, , by default, and the button we set (m) to open it in MPV. That's even more neat.
This isn't specific to online video, but Newsboat will only fetch one feed at a time when you reload them. This gets very time consuming if you have a lot of feeds, so I like to set it to 100. In ~/.newsboat/config:
# Download 100 files at a time reload-threads 100
Note: As of May 5th, 2022, at least on my machine, it seems like enabling the option reload-only-visible-feeds conflicts with reload-threads and Newsboat will download files one at a time, regardless of what reload-threads is set to. I don't know why this is, and there doesn't seem to be any documentation of this behavior. It's just something to be aware of when you're writing your config file.
As promised, here is how to get RSS feeds for various video hosts.
https://www.youtube.com/feeds/videos.xml?channel_id=<ID> where <ID> is the alphanumeric string starting with UC, found in the URL of the desired creator's channel after /channel/.
Example: https://www.youtube.com/feeds/videos.xml?channel_id=UCUnyg72UXLkT2zCjyvGOOEg
If the channel has a URL ending in /user/<USERNAME>, use https://www.youtube.com/feeds/videos.xml?user=<USERNAME>.
https://odysee.com/$/rss/<USERNAME> where <USERNAME> is the username found in the URL of the desired creator's channel page after odysee.com/ including the @ at the beginning as well as the : and number at the end.
The feed URL can also be found by navigating to the desired creator's channel, clicking the three dots in the top right, and clicking "Copy RSS URL".
Example: https://odysee.com/$/rss/@AlphaNerd:8
Navigate to the desired creator's channel, click Subscribe and choose Subscribe via RSS
I really thought Rumble would provide RSS feeds, but they don't. That's a shame. I couldn't find a public service that creates them, either.
Twitch also doesn't provide RSS feeds, but there is a public service that creates them. Use https://twitchrss.appspot.com/vod/<USERNAME> where <USERNAME> is the username of the desired user.
Example: https://twitchrss.appspot.com/vod/actionretro
That feed will include streams that are currently live as well as videos uploaded afterward. If you don't want live streams in your feed, use https://twitchrss.appspot.com/vodonly/<USERNAME>.
TwitchRSS is Apache 2.0 licensed and the source is available at the GitHub repository.
While we're on the subject, Twitch has a system that embeds ad segments directly into the playlist. It doesn't contain actual ads, but it's just a placeholder segment that prevents you from watching the stream while it thinks the ad is playing. With yt-dlp + MPV, you won't see ads, but you will see the placeholder. There is an open GitHub issue about this.
For now, the best way to bypass this screen is to use another program called Streamlink. Streamlink is a "CLI utility which pipes video streams from various services into a video player". It has an option, --twitch-disable-ads that does just what we want. We also need to tell it to use MPV as the video player.
The full command to play a stream in MPV at the best quality is as follows:
streamlink --player=mpv --twitch-disable-ads https://twitch.tv/<USERNAME> best
Let's make a new macro in Newsboat to open an item in Streamlink. In ~/.newsboat/config:
macro s set browser "nohup streamlink --player=mpv --twitch-disable-ads %u best > /dev/null 2> /dev/null &" ; open-in-browser-noninteractively ; set browser "xdg-open %u" -- "Open in MPV with Streamlink"
MPV has some powerful options, and it's definitely worth skimming the full manual, but here are a few changes you can make to improve the experience.
By default, when running MPV from FF2MPV or Newsboat with an online video as an argument, it waits for a few seconds until the video is ready before the window opens. This can be confusing, so I find it's best to force one to open using this option.
force-window=immediate
yt-dlp can download subtitles for videos, and MPV can use them. To enable subtitles, add the following to ~/.config/mpv/mpv.conf. Lines starting with # are comments and will be ignored by MPV.
# Use a less strict setting when looking for subtitles # Allows human-made subtitles downloaded by yt-dlp to be loaded by MPV sub-auto=fuzzy # Tell yt-dlp to download English automatically generated subtitles if no human-made ones are available ytdl-raw-options=sub-lang="en",write-sub=,write-auto-sub=
By default, MPV will use the best quality available for any given video. If you wish to view videos at a lower quality for bandwidth or hardware reasons, here's how to set a maximum quality. Replace 1080 with your desired video height.
# Choose best format, 1080p or lower ytdl-format=bestvideo[height<=?1080]+bestaudio/best
mpv-youtube-quality is a Lua userscript for MPV that allows you to change the video quality of streamed videos on the fly. I'll mention more MPV userscripts later, but this one is a must-have.
Put youtube-quality.lua in the MPV scripts folder, usually ~/.config/mpv/scripts/, and youtube-quality.conf in the script-opts folder, usually ~/.config/mpv/script-opts/. We'll want to make at least one change to the configuration file.
The main change we want to make here is the font size. By default, at least on my 1600x900 display, the list of quality options exceeds my screen space. A font size of 24 is about right, at least on my machine, so replace the line that starts with style_ass_tags with the following in ~/.config/mpv/script-opts/youtube-quality.conf. You can replace 24 with a font size of your choosing.
style_ass_tags={\\fnmonospace\\fs24}
You can change the key bindings at the top if you want. You should also take a look at the fetch_formats option toward the bottom. It will use youtube-dl (more on that later) to fetch a complete list of available formats for that video, instead of giving you a list of resolutions that might not be available on the chosen video.
If you choose to enable fetch_formats, you'll need to tell the script to use yt-dlp instead of youtube-dl. Unfortunately, that's not a config option, so we'll need to edit the script. Open ~/.config/mpv/scripts/youtube-quality.lua and replace youtube-dl in the line after local ytdl = { (currently line 164) with yt-dlp.
local ytdl = { path = "yt-dlp", searched = false, blacklisted = {} }
Now, open a YouTube video (or a video on any service that offers multiple quality options) in MPV and press the keybinding for mpv-youtube-quality. By default, it's Control+F. You should see a list of quality options. Select one (default bindings: Up, Down, and Enter) and it will switch to that quality while keeping your position in the video.
Note: mpv-youtube-quality only works for videos played through yt-dlp. If you're using Streamlink like we covered in Bypassing ads on Twitch, this script won't work.
Here are some more userscripts I've found for MPV that you might find useful.
UMPV is a Python script made by the MPV developers that emulates "unique application" functionality with MPV. When it is invoked, it will try to reuse an existing instance of MPV and append the current file to the playlist of the existing instance. However, it will not interfere with any instance of MPV that was not started with UMPV. If no existing instance can be found, it will start MPV as normal.
In summary, it will create a unique instance of MPV and queue new files in that instance as you open them with UMPV. Here's how to set it up. First, download the script and put it in /usr/local/bin. You will probably need elevated permissions to write to that directory. Then, make the script executable using chmod +x /usr/local/bin/umpv.
UMPV will use your default configuration file (usually ~/.config/mpv/mpv.conf) when it runs MPV, but it uses some command line options which take priority. If you have set force-window=immediate in your config (see Open windows immediately), it will not take effect by default when using UMPV. To fix this, change the --force-window option toward the end of the file, currently line 82, to read --force-window=immediate.
opts.extend(["--no-terminal", "--force-window=immediate", "--input-ipc-server=" + SOCK, "--"])
Edit ff2mpv.py, and change the args variable, currently line 15, to reference UMPV and remove all command line options other than the URL.
args = ["umpv", url]
Edit ~/.newsboat/config to reference umpv.
Simple configuration:
browser "umpv %u"
Advanced configuration:
macro M set browser "nohup umpv %u > /dev/null 2> /dev/null &" ; open-in-browser-noninteractively ; set browser "xdg-open %u &" -- "Open in UMPV"
Chances are, your distribution automatically created a desktop entry for MPV when you installed it. Since we installed UMPV manually, we'll need to add our own desktop entry. That way, we can select UMPV as the default program to open video files.
I made a desktop entry for UMPV, available here, based off the one for MPV that was already on my system. Download that file or create your own, and put it in /usr/local/share/applications/.
From here, you can configure many applications to open media files using UMPV.
Well, that's about all I can think of. I will try to keep this guide updated and add new sections as things evolve. Hopefully this was of some use to you. See you next time.
Update 2022-05-08: Fixed invalid CSS