Automating youtube-dl on Android for Custom In-Flight Entertainment

Home, Bangkok, Thailand, 2019-04-23

#automation #mobility

 
Photo by Myke Simon

YouTube is a pretty amazing resource - these days there are high-production-quality presentations on almost any topic you want to learn about.

A few of my current favorite channels are:

  • Louis Rossman who live-streams himself doing component-level repairs on Apple computers from his store in New York City
  • Makers Muse a fellow Australian who has been creating great 3D printing content for many years
  • AvE who needs no introduction and is from Norté America

YouTube has an offline option where you can temporarily download videos and cache them within the YouTube app on your device - however this does not always work: in some countries the feature is disabled and other times it just doesn’t work for.. reasons.

youtube-dl is a powerful tool for downloading media from online media properties - and there happens to be a package available for Termux on Android - to install it in a Termux shell window:

pkg install php ffmpeg

Then follow this post for youtube-dl installation steps.

You’ll probably want to enable storage access for Termux so you can place the output video files in the right place - see the Termux documenation.

So now with the combination of youtube-dl and ffmpeg you can download videos from YouTube (or elsewhere) and cache them on your Android device’s internal storage or SD card to be played back via VLC or some other media application.

The only problem is that you have to issue several commands to get a single video if you want to pull the video in it’s highest available quality - YouTube publishes separate streams for audio and video at different bit rates which are then muxed on the client-side. So you end up issuing the following commands:

  • youtube-dl -F to list the available streams
  • youtube-dl -f to download the audio stream
  • youtube-dl -f to download the video stream
  • ffmpeg to encode the two streams into a single MP4 file that can be played back in VLC

Plus you have to manage the filenames manually - rather tedious.

To simplify this, I wrote the following janky bash script (on Sunday morning when I was in Zürich) which you can run in a Termux shell:

#!/bin/bash

# ytget - Copyright 2019, Brendon Matheson

# ytget is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License v2 as published by the Free
# Software Foundation.

# ytget is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along with
# ytget.  If not, see http://www.gnu.org/licenses/gpl-2.0.html

videoUrl=$1

# Generate unique key for this retrieve
key=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)

# Get the video's title
echo "Getting video title for $videoUrl"
title=$(youtube-dl --skip-download --get-title --no-warnings $videoUrl | sed 2d)
title=$(echo $title | sed -e "s/[\/'\"]/-/g")	# Make the title filename friendly
echo "Video title $title"

# Get the video stream info
echo "Getting stream info for $videoUrl"
youtube-dl -F $videoUrl > $key"_streams"

# Find the best audio stream
audioId=$(cat $key"_streams" | \
	grep -e "audio only" | \
	awk -e '{gsub("k", "", $7); print $7 " " $1 }' | \
	sort -n -r | \
	head -n 1 | \
	awk -e '{ print $2 }')

echo "Selected audio stream $audioId"

# Find the best video stream

...

etc

Full source available on GitHub

To use it just run the script and paste in the URL of the YouTube video you want:

./ytget.sh <video-url>

For example:

The script generates a random prefix for it’s temp files so that you can run multiple instances of the script in the same directory - I usually run two side-by-side in tmux on my tablet device.

So now I can easily download a few videos in the lounge before boarding a flight for customized in-flight edutainment - sweet!