Bash: bash script to download trimmed mp3 from youtube url

1.5k views Asked by At

I would like to download the initially x seconds trimmed mp3 from a video url of youtube.
I found that youtube-dl can download the video from youtube to local machine. But, when I looked at the man pages of youtube-dl, I could not find any trim options.

So I tried to use the ffmpeg to trim downloaded mp3 file.
Instead of doing this is two steps, I like to write one bash script which does the same thing.
My attempt is given below.

However, I was stuck at one place:
"HOW TO GET THE VARIABLE NAME OF OUTPUT MP3 FILE FROM YOUTUBE-DL?"
The script is given below:

# trim initial x seconds of mp3 file
# e.g. mytrim https://www.youtube.com/watch?v=dD5RgCf1hrI 30
function mytrim() {
    youtube-dl --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $1
    ffmpeg -ss $2 -i $OUTPUT_MP3 -acodec copy -y temp.mp3
    mv temp.mp3 $OUTPUT_MP3
    }

How to get the variable value $OUTPUT_MP3?
echo "%(title)s.%(ext)s" gives the verbatim output, does not give the output filename.

How could we make the script work?

The help will be appreciated.

2

There are 2 answers

3
umläute On BEST ANSWER

youtube-dl supports a --get-filename option, that doesn't actually download anything, but gives the calculated filename on the stdout.

mytrim() {
    local downloaded_file
    youtube-dl --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $1
    downloaded_file=$(youtube-dl --get-filename --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $1)
    ffmpeg -ss $2 -i "${downloaded_file}" -acodec copy -y temp.mp3
    mv temp.mp3 "${downloaded_file}"
}
0
BhishanPoudel On

Thanks a lot @umlaute,
I added following functions to my bash_profile:

# download best video quality using youtube-dl
# usage: myvid https://youtu.be/450p7goxZqg?t=4
function myvid() {
  youtube-dl -f bestvideo+bestaudio "$1"
  rm -r youtube_video_time.txt
}

# usage: mymp3 youtube_video_url
mymp3() {
    local downloaded_file
    youtube-dl --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $1
    downloaded_file=$(youtube-dl --get-filename --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $1)
}

# initial x seconds trimmed mp3 song
# mytrim 5 https://www.youtube.com/watch?v=iLQxbEkN85o
mytrim() {
    local downloaded_file
    youtube-dl --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $2
    downloaded_file=$(youtube-dl --get-filename --extract-audio --embed-thumbnail --audio-format mp3 -o "%(title)s.%(ext)s" $2)
    ffmpeg -ss $1 -i "${downloaded_file}" -acodec copy -y temp.mp3
    mv temp.mp3 "${downloaded_file}"
    clear
    echo "${downloaded_file}"
    # Now replace whitespace by underscore
    find . -type f -name "* *.mp3" -exec bash -c 'mv "$0" "${0// /_}"' {} \;
    # Lowercase the file name
    for i in $(find . -name '*[A-Z]*.mp3' -type f); do mv "$i" "$(echo $i|tr A-Z a-z)"; done
}

To download songs from the text file

IN_URL="/Volumes/Media/Music/download_youtube_mp3/songs.txt"
ODIR="downloaded_songs/%(title)s.%(ext)s"
youtube-dl --extract-audio --embed-thumbnail --audio-format mp3 --audio-quality=320k --output $ODIR --batch-file=$IN_URL