mckinley.cc Home Blog Notes Twtxt

Watching Online Videos Like a Pro Using Free Software

May 6th, 2022

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.

Table of Contents

Yep, it's long enough for a table of contents. We're definitely reinforcing stereotypes about free software here.

  1. Table of Contents
  2. yt-dlp vs. youtube-dl
  3. Playing videos from the browser with FF2MPV
  4. Keeping up with new uploads using Newsboat
  5. Getting RSS feeds
  6. Bypassing ads on Twitch
  7. Tweaking mpv.conf
  8. Changing video quality on the fly using mpv-youtube-quality
  9. More MPV userscripts
  10. Queuing videos with UMPV
  11. Integrating UMPV with other programs
  12. Conclusion

yt-dlp vs. youtube-dl

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 browser with FF2MPV

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.

Keeping up with new uploads using Newsboat

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.

Advanced Newsboat configuration

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.

Make feed updates faster

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.

Getting RSS feeds

As promised, here is how to get RSS feeds for various video hosts.

YouTube

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>.

Odysee

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

PeerTube

Navigate to the desired creator's channel, click Subscribe and choose Subscribe via RSS

Rumble

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

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.

Bypassing ads on Twitch

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"

Tweaking mpv.conf

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.

Open windows immediately

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

Subtitles

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=

Set maximum quality

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

Changing video quality on the fly using mpv-youtube-quality

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.

More MPV userscripts

Here are some more userscripts I've found for MPV that you might find useful.

Queuing videos with UMPV

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.

Fix force-window=immediate

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,
    "--"])

Integrating UMPV with other programs

FF2MPV

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]

Newsboat

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"

File browsers, among others

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.

Conclusion

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