Добавляем Last.fm радио в MPD плейлист

в 11:36, , рубрики: bash, last.fm, linux, mp3, mpd, music, streaming, метки: , , , , ,

Здравствуй Xабраменш,

IchBin's. Все началось с того, что поддержка last.fm радио была настолько коряво реализована в MPD, что я даже перестал эту функцию компилировать. Корявость ее заключалась в том, что настроившись на канал, все равно приходилось вручную добавлять треки в плейлист, ибо сервер выдает по пять треков за запрос. Следовательно, после того как все треки проигрались, нужно повторить запрос и получить следующие 5 треков! Дальше речь пойдет о скриптах, которые бы этот процесс автоматизировали

Bash.fm — работа над ашипками

Оригинальная идея была найдена тут. Скрипты по ссылке давно устарели и не работали. К тому же, автор скриптов имеет весьма своеобразный стиль и умудрился добавить ненужных зависимостей, например, на lynx. Поэтому пришлось большую часть изменить, хотя логика работы осталась прежней:

  • Инициализируем сессию с помощью fmstart
  • Настраиваемся на канал с помощью fmpersonal, fmart, ...
  • Добавляем в плейлист треки с канала с помощью fmget (5 треков за вызов)
  • PROFIT!

Начнем с fmstart:

root@Buffalo:~# cat /mnt/sd/bin/fmstart
#!/bin/sh

username=$(sed -nr 's/^username=(.*)/1/p' ~/.bashfm)
password=$(sed -nr 's/^password=([^[:space:]]*).*/1/p' ~/.bashfm)
mediaplayer=$(sed -nr 's/^mediaplayer=(.*)/1/p' ~/.bashfm)

if [ ! -z "$password" ]; then
  passwordmd5=$(echo -n $password | md5sum | sed -nr 's/([^[:space:]]*).*/1/p')
else
  passwordmd5=$(sed -nr 's/^passwordmd5=([^[:space:]]*).*/1/p' ~/.bashfm)
fi

echo 'username='$username > ~/.bashfm
echo 'password=' >> ~/.bashfm
echo 'mediaplayer='"$mediaplayer" >> ~/.bashfm
echo 'passwordmd5='$passwordmd5 >> ~/.bashfm

login_url='http://ws.audioscrobbler.com/radio/handshake.php?'
login_url="$login_url"'version=1.1.1&platform=linux&username='
login_url="$login_url"$username'&passwordmd5='$passwordmd5
login_url="$login_url"'&debug=0&partner='

echo "login_url=$login_url" >> ~/.bashfm

wget -q -O - "$login_url" >> ~/.bashfm
echo >> ~/.bashfm

Для правильной работы скрипта нужно предварительно создать файл ~/.bashfm со следующим содержанием:

root@Buffalo:~# cat ~/.bashfm
username=ichbins
password=123456
mediaplayer=/mnt/sd/bin/mpc add

здесь username и password — твое имя и пароль c last.fm, а mediaplayer — команда, с помощью которой треки добавляются в плейлист.
При первом запуске fmstart, пароль будет удален и заменен на md5 сумму.

Небольшое отступление:
MPC — это стандартный клиент MPD для командной строки. Но я его не компилирую, а использую скрипт в одну строчку:

root@Buffalo:~# cat /mnt/sd/bin/mpc
#!/bin/sh

echo "$*" | nc localhost 6600

Этот скрипт не является полным аналогом MPC, но для моих нужд его всегда хватало.

Теперь о скриптах выбора канала. По сути они все одинаковые, только канальный УРЛ внутри различается. Я слушаю либо персональное радио, либо радио конкретного артиста — поэтому ниже я приведу лишь эти два скрипта.
Скрипт активизации канала персонального радио:

root@Buffalo:~# cat /mnt/sd/bin/fmpersonal
#!/bin/sh

#
# "fmpersonal" plays user's personal radio station
#
 
session=$(sed -nr 's/^session=(.*)/1/p' ~/.bashfm)
username=$(sed -nr 's/^username=(.*)/1/p' ~/.bashfm)

tuning_url='http://ws.audioscrobbler.com/radio/adjust.php?'
tuning_url="${tuning_url}session=${session}&url=lastfm://user/"
tuning_url="${tuning_url}${username}/personal"

#echo "$tuning_url"
wget -q -O - "$tuning_url"
echo

При успешном выполнении скрипт выдаст:

root@Buffalo:~# /mnt/sd/bin/fmpersonal
response=OK
url=http://www.last.fm/listen/user/IchBins/personal
stationname=IchBins’s Library Radio

Скрипт активизации артиста выглядит похоже:

root@Buffalo:~# cat /mnt/sd/bin/fmart
#!/bin/sh

# "fmart" plays the radio station corresponding to a
# certain artist. It takes the artist's name as command
# line argument. Use quotes when the artist's name
# contains spaces.
#
# Example:
# fmart 'jahcoozi'
 
artist=$(echo $1 | sed 's/ /%20/g')
 
session=$(sed -nr 's/^session=(.*)/1/p' ~/.bashfm)

tuning_url='http://ws.audioscrobbler.com/radio/adjust.php?'
tuning_url="${tuning_url}session=${session}&url=lastfm://artist/"
tuning_url="${tuning_url}${artist}/similarartists&debug=0"

#echo "$tuning_url"
wget -q -O - "$tuning_url"
echo

Результат выполнения:

root@Buffalo:~# /mnt/sd/bin/fmart
response=FAILED
error=4
root@Buffalo:~# /mnt/sd/bin/fmart "Knorkator"
response=OK
url=http://www.last.fm/listen/artist/Knorkator/similarartists
stationname=Knorkator Radio

Настроившись на канал, можно добавить из него треки к себе в плейлист с помощью fmget:

root@Buffalo:~# cat /mnt/sd/bin/fmget
#!/bin/sh

# "fmget" gets list of mp3's from a radiostation and
# adds it into the current playlist
#
# Example:
# fmart 'Depeche Mode'; fmget

session=$(sed -nr 's/^session=(.*)/1/p' ~/.bashfm)
mplayer=$(sed -nr 's/^mediaplayer=(.*)/1/p' ~/.bashfm)

tuning_url='http://ws.audioscrobbler.com/radio/xspf.php?'
tuning_url="${tuning_url}sk=${session}"
tuning_url="${tuning_url}&discovery=0&desktop=1.5.1"

#echo "$tuning_url"
mp3list=$(wget -q -O - "$tuning_url" | sed -nr "s/.*<location>(.*)</location>/1/p")

for i in $mp3list; do
  #echo $i
  $mplayer "$i"
done

Результат работы:

root@Buffalo:~# /mnt/sd/bin/fmget
OK MPD 0.16.0
OK
OK MPD 0.16.0
OK
OK MPD 0.16.0
OK
OK MPD 0.16.0
OK
OK MPD 0.16.0
OK

Полученные ссылки на треки являются ссылками на mp3 файлы, поэтому их можно скармливать любому плееру, а не только MPD. Достаточно заменить mediaplayer параметер в файле ~/.bashfm

Вот собственно и все, что я хотел рассказать. Что касается автоматизации процесса добавления треков в плейлист, то данный скрипт я оставлю тебе в качестве домашнего задания. Тут можно вызвать fmget +100500 раз или в цикле вызывать «mpc status», парсить ответ и если nextsong==playlistlength, то вызвать fmget.

В качестве бонуса, если уж ты осилил до сюда, я дам тебе, мой любопытный друг, все скрипты из статьи в одном флаконе

Автор: ichbins


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js