How To Cast YouTube Videos From Your Phone To Raspberry Pi Using YouTube On TV (youtube.com/tv)

YouTube on TV https://youtube.com/tv Raspberry Pi

This article explains how to use YouTube on TV (https://youtube.com/tv) on a Raspberry Pi, and control it using the YouTube app from your mobile device, almost as if you're using a Chromecast.

Once you set up everything, you'll be able to use the cast button from the YouTube app on your phone to connect to YouTube on TV running on your Raspberry Pi (using Chromium web browser in kiosk mode), and use your phone as a YouTube remote. You'll be able to play videos, add videos to queue, change the volume using the phone's volume keys, etc. Also, multiple phones (so multiple users) can connect, play and add videos to the queue at the same time.

Note that I've only tested this using Android phones, so I'm not sure if it also works with iOS. I guess it should, but I don't own any iOS devices.

Important note. Don't confuse YouTube on TV (https://youtube.com/tv) with YouTube TV (https://tv.youtube.com). "YouTube on TV", or "YouTube for TV" is a web YouTube interface designed for smart TVs, and that's what we're going to use on a Raspberry Pi, while YouTube TV is a streaming television service that offers live TV and on-demand video.

Using YouTube on TV on a Raspberry Pi has quite a few advantages over using a Chromecast, but also some disadvantages. 

Advantages of using YouTube on TV (https://youtube.com/tv) on a Raspberry Pi instead of a Chromecast (I'm not sure if everything applies to the latest Chromecast, I have the older Chromecast Ultra):

  • You can use an ad blocker like Ublock Origin (comes preinstalled with Chromium browser on Raspberry Pi OS) - no more ads on YouTube (no, the Pi-hole is not reliable in blocking YouTube ads, believe me, I've tried)
  • The YouTube app on your phone doesn't disconnect from YouTube on TV after a period of inactivity
  • The YouTube app doesn't close after a period of inactivity, so paused videos remain on screen indefinitely
  • You can navigate through the YouTube on TV app from your phone (after connecting to YouTube on TV with your mobile device, click the cast icon and you'll get a Remote button which allows navigating through the videos, changing the video settings, etc.)
  • You can change the video quality (which is not possible on a Chromecast) using the remote I mentioned above
  • You should be able to browse the YouTube on TV interface using your TV's remote, as long as the TV supports CEC, by using cec-client. This requires some tweaking, and I haven't gotten to do it yet. Here's how to power on / off a TV connected via HDMI-CEC for example.

Disadvantages of using YouTube on TV on a Raspberry Pi instead of a Chromecast:

  • Using YouTube on TV on a Raspberry Pi is obviously... only for YouTube, while a Chromecast supports many other audio and video platforms. This is a major disatvantage if you use many other audio/video platforms but if you only want this for YouTube, using YouTube on TV on a Raspberry Pi is a great alternative
  • The video quality may be lower. Using the h264ify extension (installed by default on Raspberry Pi OS; required for hardware-accelerated video playback on YouTube) you'll get a maximum video quality of 1080p30. Without this extension you get up to 4K videos (but they didn't play properly on my Raspberry Pi 4). Also, using YouTube on TV on a Raspberry Pi, if a video is 1080p60 only, the video is downgraded to 720p60
  • The first time you connect a phone to YouTube on TV, you need to enter a pin, and for this you need a mouse (or some software to emulate a mouse from your phone or desktop) on your Raspberry Pi in order to get to the pin page. Once a phone is connected with a pin, it works just like a Chromecast

These are all the pros and cons I could think of, but there might be others. It really depends on the way you use this and what you want from it.

It's important to note that to test all of this, I've used a Raspberry Pi 4 with Raspberry Pi OS. Not everything from the instructions below will work if you use a different Linux distribution (e.g. adding programs to startup will not be the same). I'm not sure how well older Raspberry Pi models are able to play YouTube videos. Also, you don't have to use this on a Raspberry Pi - you could use in on any computer running Linux, but some parts of the instructions below won't work exactly in the same way.


Setup YouTube on TV (https://youtube.com/tv) with Chromium to launch on startup on your Raspberry Pi


1. Install the YouTube TV on PC Chrome extension on Chromium browser.

You can get the extension from the Chrome Web Store

By default, visiting https://youtube.com/tv on a device other than a TV redirects to the regular YouTube website. It looks like Google really doesn't want us using this on anything other than a TV because of... probably ad blockers. 

Using a TV user agent fixes this, but the videos are 720p. Using the YouTube TV on PC extension, https://youtube.com/tv stops redirecting to the regular YouTube, while also allowing videos with a quality higher than 720p. We'll still need to use an user agent when launching Chromium in kiosk mode, because it bypasses this extension's user agent for some reason (this doesn't happen when it's started with no kiosk or full screen mode), but using this we'll get higher quality videos.

2. Create a script that launches Chromium browser in kiosk mode and loads https://youtube.com/tv, with some settings to optimize it for usage with YouTube on TV.

Create a script, let's call it yt, in ~/.local/bin.

To make sure that the ~/.local/bin folder exists (and create it if it doesn't), run this command:

mkdir -p ~/.local/bin

Now create a file called yt in ~/.local/bin, and open it with a text editor. We'll use Nano command line text editor to open it using the following command:

nano ~/.local/bin/yt

In this file, paste the following:

#!/bin/bash

sed -i 's/"exited_cleanly": false/"exited_cleanly": true/' ~/.config/chromium/Default/Preferences

sed -i 's/"exit_type": "Crashed"/"exit_type": "None"/' ~/.config/chromium/Default/Preferences

sleep 5; chromium-browser --autoplay-policy=no-user-gesture-required --enable-extensions --user-agent="Mozilla/5.0(SMART-TV; Linux; Tizen 4.0.0.2) AppleWebkit/605.1.15 (KHTML, like Gecko) SamsungBrowser/9.2 TV Safari/605.1.15" --kiosk "https://www.youtube.com/tv"  >/dev/null 2>&1 &

Here's what this does:

  • the 2 sed commands (via Raspberry Pi StackExchange) modify the Chromium Preferences file as if Chromium exited cleanly, in case the browser actually didn't exit cleanly. This way you don't get the session restore popup in case the browser crashes, your power goes out, etc. I'm not sure if this is really needed when launching Chromium in kiosk mode, but I think it's better to have this in the script than have Chromium not launch correctly
  • the last line:
    • sleep 5 is used to wait 5 seconds before starting Chromium browser. We'll be adding this script to startup, so we'll wait 5 seconds before starting Chromium, so the Raspberry Pi has enough time to connect to the Internet. In case it takes longer for you, modify the sleep value here
    • next, we start Chromium using the following options:
      • --autoplay-policy=no-user-gesture-required: this allows Chromium to autostart the video. Without this, you need to manually start the first video after a Chromium restart, and this can't be done from the YouTube app, so you'd need a keyboard to do this, or send a key using something like xdotool
      • --enable-extensions: self-explanatory - it allows loading extensions, like the YouTube TV on PC extension, UBlock Origin, h264ify, etc.
      • --user-agent="Mozilla/5.0(SMART-TV; Linux; Tizen 4.0.0.2) AppleWebkit/605.1.15 (KHTML, like Gecko) SamsungBrowser/9.2 TV Safari/605.1.15": even though we're using the YouTube TV on PC Chrome extension, if Chromium starts in full-screen / kiosk mode, it still redirects to the regular YouTube website interface. So we're using a TV user agent to get YouTube to stay on https://youtube.com/tv
      • --kiosk: runs Chromium in kiosk mode. This makes it start in full-screen, and disables some popus, like the translate popup, etc.
      • "https://www.youtube.com/tv": this is the URL we want to open when Chromium starts
    • >/dev/null 2>&1 redirects STDOUT and STDERR so you don't see any output in the terminal if you run this manually, and & keeps the application running

3. Add our new script to startup.

Start by making the new yt script executable:

chmod +x ~/.local/bin/yt

Next, edit the Raspberry Pi OS autostart file (~/.config/lxsession/LXDE-pi/autostart) using a text editor - using the command below we'll open it using Nano command line editor:

nano ~/.config/lxsession/LXDE-pi/autostart

In this file, add the following line to autostart the yt script:

@bash /home/pi/.local/bin/yt

When you're done, save the file (use Ctrl + O, then Enter to save it, followed by Ctrl + X to exit Nano).

It's important to note that we can't use ~/.local/bin/yt in the autostart file. We need to use the full path to the yt script. So if the path is different (you're not using the default pi user), adjust this to your system / username.

4. Launch Chromium with YouTube on TV for the first time.

Chromium with YouTube on TV will launch automatically on startup. But since we don't want to reboot just to start it, we can start it manually. Close any running Chromium browser windows, then open a terminal and type:

~/.local/bin/yt &

5. Pair your phone with YouTube on TV running on Raspberry Pi.

With Chromium browser running and https://www.youtube.com/tv open on your Raspberry Pi, go to settings (the gear icon in the bottom left-hand side), then click on Link with TV code, and you'll see a code on your TV's screen:

YouTube on TV code

Now open the YouTube app on your phone, click on the cast icon at the top of the app, and you'll have an option that says Link with TV code

Android YouTube link with tv code

Click this and enter the code you see on your TV:

YouTube Android enter code

Click Link after entering the code, and you're done! You can connect to YouTube on TV running on your Raspberry Pi and cast YouTube videos from your phone to it, by connecting to the newly added device:

YouTube Android connect to TV

This gets YouTube on TV up and running on your Raspberry Pi. However, besides this, I'm also using some tweaks / optimizations, which you might also want to use. See below for details.


Optimizations / tweaks for using YouTube on TV via Chromium on Raspberry Pi


1. Enable hardware acceleration in Chromium browser running on Raspberry Pi.

This is probably the most important optimization / tweak. Using this, YouTube videos should use much less CPU, while keeping your Raspberry Pi cooler. Check out the following article from Linux Uprising for exact instructions:

How To Enable Hardware Acceleration In Chromium On Raspberry Pi OS

2. Autohide the mouse cursor when inactive.

The mouse cursor shows up on top of YouTube on TV. To get it to autohide, I'm using unclutter-xfixes, a rewrite of the popular unclutter tool, but using the x11-xfixes extension (and with some improvements). You may also use the original unclutter (it's in the repositories), however I personally prefer this fork. Note that their usage is not the same so if you want to use the original unclutter, see here.

To install unclutter-xfixes, install Git if you haven't already, as well as the unclutter-xfixes dependencies:

sudo apt install git libx11-dev libxfixes-dev libxi-dev libev-dev asciidoc

Next, clone the unclutter-xfixes GitHub repository, build and install the tool:

git clone https://github.com/Airblader/unclutter-xfixes

cd unclutter-xfixes

make

sudo make install

Now to autohide the mouse cursor when idle, you'll need to add unclutter -b to startup. To do this, open the Raspberry Pi OS autostart file with a text editor - we'll use Nano console text editor below:

nano ~/.config/lxsession/LXDE-pi/autostart

At the end of the file, add:

@unclutter -b

When you're done, save the file (use Ctrl + O, then Enter to save it, followed by Ctrl + X to exit Nano). Or wait and save it after the next step, since we're adding yet another command to autostart.

3. Disable screen blanking

To disable screen blanking, once again we'll have to add a command to the autostart file. So open the ~/.config/lxsession/LXDE-pi/autostart file with Nano:

nano ~/.config/lxsession/LXDE-pi/autostart

And at the end of the file, add:

@xset -dpms s off

And finally, save the file (use Ctrl + O, then Enter to save it, followed by Ctrl + X to exit).

4. Install Profile Sync Daemon to load the Chromium profile into tmpfs (RAM).

Profile Sync Daemon is a tool to keep your browser profile in tmpfs, and periodically sync it back to your physical disk. This speeds up Chromium while also making less writes to the disk, so your Raspberry Pi's sdcard / USB lasts for longer. Use this if your Raspberry Pi has enough RAM.

Install it using:

sudo apt install profile-sync-daemon

Next, run PSD for the first time in order to create the user configuration file:

psd

Now edit the PSD configuration file using a text editor, e.g. Nano:

nano ~/.config/psd/psd.conf

In this file, uncomment the BROWSERS line, and add chromium to it, so it looks like this:

BROWSERS="chromium"

Now you can enable and start PSD:

systemctl --user enable psd
systemctl --user start psd

[[Edit]] Chromium and a few other browsers have their cache stored in a different location than the browser profile. So let's also load the Chromium cache in RAM (using tmpfs), by editing /etc/fstab using Nano console editor:

sudo nano /etc/fstab

And adding the following line to the file (don't edit anything else, a bad fstab file means your Pi will no longer boot):

tmpfs   /home/pi/.cache/chromium tmpfs   user,exec,uid=1000,gid=1000,size=500m      0 0

Edit the size value with the amount of MB you want to use for the Chromium cache stored in RAM. I'm using 500 here, but you may want to use a different value, depending on the amount of RAM available for your Raspberry Pi.

I've also disabled the swap on my Raspberry Pi in order to minimize disk writes, but I'm not sure if that's such a good idea, so I'm not adding instructions for that here. You can find how to do this with a simple search.