Pull to refresh

Скачиваем Youtube плейлист в формате mp3 одним bash-скриптом

Reading time2 min
Views34K
Так сложилось, что в данный момент мой рабочий ноутбук оснащен лишь 2GB оперативной памяти. В связи с этим возникла необходимость оптимизации браузера, т.к. при большом количестве открытых вкладок памяти становится недостаточно и используется swap-раздел, что ведет к тормозам.

В работе мне помогает музыка, обычно это открытый таб с плейлистом Youtube. Так вот этот таб в просессе работы съедает до 500MB (!) и даже больше (Google Chrome).

Такое положение дел вынудило написать bash-скрипт, который на входе получает ID плейлиста, на выходе – mp3 файлы, которые можно слушать в любимом плеере, например, в MOC:
MOC


Скачать mp3 с Youtube нельзя, поэтому процесс делим на 3 шага:
  1. скачиваем flv
  2. извлекаем звуковую дорожку
  3. удаляем временный flv


На всякий случай напомню, что ID плейлиста это get-параметр «list».

Зависимости:
sudo apt-get install youtube-dl ffmpeg libavcodec-extra-53

  • youtube-dl для скачивания видеофайла
  • ffmpeg libavcodec-extra-53 для конвертации в mp3


Собственно сам скрипт, подробно прокомментированный(скачать):
#!/bin/bash

usage='usage: 
  ./get_youtube_playlist <playlist_id> <target_folder> <num_songs>
    target_folder: (default: songs will be downloaded in current folder)
    num_songs:     number of songs to get (default: 50)

examples: 
  ./get_youtube_playlist RD02HIkZaLeuF9k
  ./get_youtube_playlist RD02HIkZaLeuF9k "instrumental hip-hop beats" 10
'

playlist_id=$1
target_folder=$2
num_songs=$3

if [ -z "$playlist_id" ]; then
    echo "$usage"
    exit 1
fi

if ! [[ "$num_songs" =~ ^[0-9]+$ ]] ; then
    num_songs=50
fi

if [ -z "$target_folder" ]; then
    target_folder='./'
elif [ ! -d "$target_folder" ]; then
    echo "Parameter target_folder is incorrect, $usage"
    exit 1
fi


# используем Youtube API для получения списка песен
# https://developers.google.com/youtube/2.0/developers_guide_protocol_playlist_search
youtube_api="`wget -qO- https://gdata.youtube.com/feeds/api/playlists/$playlist_id\?max-results\=$num_songs`"
if [ -z "$youtube_api" ]; then
    echo "Playlist ID is incorrect, $usage"
    exit 1
fi

# cписок ID песен помещаем в массив songs
songs=( 
    $(echo $youtube_api | \
    grep -P -o "<media:player url='.*?&" | \
    grep -P -o "(\w|-){11}") 
)

if [ -z "$songs" ]; then
    echo "Nothing to do, $usage"
    exit 1
fi

# теперь работаем с каждой отдельной песней
for (( i = 1 ; i <= ${#songs[@]} ; i++ )) 
do
    youtube_id=${songs[$i-1]}
    track_number=`printf "%0*d" 2 $i`
    flv_path="$target_folder/$youtube_id.flv"
    mp3_path="$target_folder/$track_number. $youtube_id.mp3"

    # 1. скачиваем flv
    youtube-dl --audio-format=mp3 -o "$flv_path" "http://youtu.be/$youtube_id"
    
    if [ -f "$flv_path" ]
    then
        # 2. flv -> mp3
        avconv -i "$flv_path" -y "$mp3_path" -acodec libmp3lame -ac 2 -ab 128k -vn

        # 3. удаляем flv
        rm "$flv_path"
    fi
done


Надеюсь, этот скрипт полезен не только мне и будет экономить много гигабайт оперативной памяти у хабражителей.
Tags:
Hubs:
Total votes 70: ↑61 and ↓9+52
Comments48

Articles