Skip to content

Instantly share code, notes, and snippets.

@ilyaigpetrov
Last active October 21, 2025 08:28
Show Gist options
  • Select an option

  • Save ilyaigpetrov/834a956685f3bc5738dc1de20e7aeb5e to your computer and use it in GitHub Desktop.

Select an option

Save ilyaigpetrov/834a956685f3bc5738dc1de20e7aeb5e to your computer and use it in GitHub Desktop.
HOWTO: Write `yt-dlp` wrapper shell scripts to download audio from the web via a terminal | #HOWTO #Tutorial #YTDLP #POSIX #Shell #CLI #Terminal #alias #Downlaod #Music #YouTube #Linux #Android #Termux #ToMyFutureSelf #EN

HOWTO: Write Wrapper Shell Scripts to Download Audio with yt-dlp

yt-dlp (YouTube DownLoader Plus) is a free open-source command-line tool, a fork of youtube-dl for downloading video and audio from thousands of websites, e.g. YouTube, SoundCloud, Bandcamp, etc. The content may be legally free or purchased music, podcasts, audiobooks, etc., which you want to save locally for many reasons.

Not for Production

I've written these scripts for myself and decided to share it in case someone finds it useful for self-development. I give absolutely NO WARRANTY if you decide to use them. I'm not a professional in shell scripting, I just learn by doing and sharing this how-to motivates me to practice more. I also recommend reading Further Work section below as it contains some warnings.

Do Not Abuse

  1. Please, keep in mind that by using these scripts you stress the servers/hosts. Don't try to download too much.
  2. Please, be informed that:

    Downloading copyrighted material without permission from the copyright holder is a violation of copyright law. Unauthorized downloading can lead to civil or criminal penalties for copyright infringement.

Publications

  1. Telegram channel "Декрабизация", RU: https://t.me/decrabru/58.
  2. Telegram chat group "LinuxCamp", RU: https://t.me/linuxcamp_chat/18467.

Instructions

In Termux or a terminal of other Debian-like apt-capable environment run:

## Install ##

# Turn off `sudo` in Termux:
if [ ! -z $TERMUX_VERSION ]; then alias sudo=''; fi
# Update information about packages:
sudo apt update
# Upgrade all installed packages to the latest versions:
sudo apt upgrade
# Install:
#  1) `curl` and `wget` -- used for downlaoding files from the web.
#  2) `python3` -- required to execute a `yt-dlp` binary.
#  3) `ffmpeg` -- used by `yt-dlp` for converting downloaded media to mp3, flac or other format.
sudo apt install --yes curl wget python3 ffmpeg

# WARNING: The following commands are dangerous!
# 1) Via `curl` it downloads `install.sh` script from one of GitHub's domains.
#    Make sure you trust the `url` variable below.
#    Verify the domain, username and gist id. The username and id must match with the url of
#    this page (gist) from the address bar of your browser.
# 2) The downloaded script's content is "piped down" (fed to) via `|` (pipe operator) to `sh` (shell).
# 3) The shell executes commands passed to its' input and installs aliases.
url='https://gist.githubusercontent.com/ilyaigpetrov/834a956685f3bc5738dc1de20e7aeb5e/raw/install.sh'
curl --silent $url | sh
# 4) The `.` (dot operator) executes commands from file `~/.bash_aliases` populated during the install
#    in order to make the aliases usable in your _current_ shell session.
. ~/.bash_aliases

To uninstall:

## Uninstall ##

myTmp="$(mktemp)"
cat ~/.bash_aliases | sed 's/^/un/' | sed 's/=.*//' | grep ' my-' > $myTmp
. $myTmp
sed --in-place '/ my-/d' ~/.bash_aliases

### Optionally ###

# BE CAREFUL: These tools to be deleted may be used by
# other applications. `apt` will warn you about the dependants.
sudo apt remove curl wget python3 ffmpeg

# Remove `yt-dlp`.
# You may need to install `which` tool via `apt` first.
sudo rm $(which yt-dlp)

Usage

cd ./music
mkdir ./from-internet
cd ./from-internet
# Download mp3 from a YouTube video:
my-audio-downloader mp3 https://www.youtube.com/watch?v=VIDEO_ID_HERE
# Want to convert the source media format to flac?
# Keep in mind that if the original quality
# is poor, flac won't make it any better.
# Anyway, just replace mp3 with flac:
my-audio-downloader flac https://soundcloud.com/ARTIST_NAME_HERE/TRACK_TITLE_HERE
# Download mp3(s) for some item (e.g. a playlist) from
# a SoundCloud short url:
my-audio-downloader mp3 https://on.soundcloud.com/SOME_ID_HERE
# Download the best quality and don't convert it:
my-audio-downloader-best https://soundcloud.com/ARTIST_NAME_HERE/TRACK_TITLE_HERE

Further Work

  1. The uninstaller script just uses my- to identify aliases for removal. This may easily happen to clash with aliases by other apps.
  2. The yt-dlp output template isn't perfect. E.g. I don't like the usage of autonumber as a fallback.
  3. My shell coding skills need more practice.
  4. WARNING: The output template for a filename may be vulnerable to code injections. E.g. some track or artist name may include unsafe characters or shell commands.
#!/bin/sh
# `-e` -- exit on the first error, don't resume.
# `-x` -- print each executed command.
set -ex
# Detect if inside Termux.
# If the string is not of zero (`-z`) length:
alias IF_TERMUX='[ ! -z $TERMUX_VERSION ]'
if IF_TERMUX; then
# Define `sudo` as a no-op:broot
alias sudo=''
# In Termux for Android user files are kept in `~/storage`.
export DOWNLOADS=~/storage/downloads
# Get the latest item in $PATH.
# E.g. /data/data/com.termux/file/usr/bin
export BIN=$(echo $PATH | tr ':' '\n' | head --lines 1)
else
export DOWNLOADS=~/Downloads
export BIN=~/bin
fi
mkdir --parents $BIN
DOWNLOAD_AND_SETUP () {
cd $DOWNLOADS
# Download yt-dlp executable for python3:
wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp --output-document ./yt-dlp
# Move the binary to executables directory.
# Termux's `chmod` can't change fs attributes in the previous location.
mv ./yt-dlp $BIN/.
# Mark it as executable.
chmod +x $BIN/yt-dlp
cd
# Update `yt-dlp` script to the latest version:
yt-dlp --update
}
DEFINE_ALIASES () {
# Create aliases -- your own (short) custom commands
# translated to other existing commands, e.g. to `yt-dlp`
# called with specified arguments. Below we create a helper
# alias that specifies output file format but still expects
# additional arguments.
alias my-yt-dlp-helper="yt-dlp --no-progress --output '%(playlist_uploader,artist|.)s/%(playlist,album|.)s/%(playlist_index,track_number,autonumber)05d_%(artist,uploader)s - %(title)s [%(id)s].%(ext)s'"
# For testing use `yt-dlp --print filename ...`.
# Define another alias that tells yt-dlp via our helper
# to extract audio and convert it to the format passed further:
alias my-audio-downloader='my-yt-dlp-helper --extract-audio --audio-format'
# If you don't specify audio format, then by default yt-dlp chooses the best quality.
alias my-audio-downloader-best='my-yt-dlp-helper --extract-audio'
# If you need a command for converting to mp3 or flac:
alias my-mp3-downloader='my-audio-downloader mp3'
alias my-flac-downloader='my-audio-downloader flac'
}
PERSIST_ALIASES () {
# When launched without any arguments `alias` outputs
# all known aliases created during the current user session.
# Try yourself:
#$ alias
#> [...] # Several aliases on multiple lines here.
#> alias ls='ls --color=auto'
#> alias my-audio-downloader='my-yt-dlp-helper [...]'
#> alias my-yt-dlp-helper='[...]'
# Now filter this list by piping the output to
# the `grep` tool that will return only lines
# containing "my-" inside:
#$ alias | grep 'my-'
#> alias my-audio-downloader='[...]'
#> alias my-yt-dlp-helper='[...]'
# The `>>` operator appends output of a previous
# command to the end of the file passed afterwards.
# For example:
#$ echo 'Your text goes here!' >> ./your-target-file.txt
#$ cat ./your-target-file.txt # Prints file's content:
#> Your text goes here!
# `~/.bash_aliases` is a special script that contains
# aliases or other commands executed on each start of
# a new interactive Bash shell terminal session.
# To define our custom aliases on each terminal
# launch:
prepend_alias () { sed -E 's/^(alias )?/alias /'; }
alias | grep 'my-' | prepend_alias >> ~/.bash_aliases
}
MAIN () {
DOWNLOAD_AND_SETUP
DEFINE_ALIASES
PERSIST_ALIASES
}
# Place the main function at the end of the script.
# In case this file is not fully downloaded (truncated)
# the script won't be executed.
MAIN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment