Pull to refresh

Мучаем Last.fm и СDDB.

Reading time 4 min
Views 3.9K
Случилось так, что за долгую меломанскую жизнь у меня скопилось более 1000 дисков уже «архаичного» формата аудио CD. А что же делать в эпоху социальных сетей, в общем, и Last.fm в частности, с таким количеством дисков? Правильно, надо отправить всё на Last.fm и желательно скопом, не слушая их на компьютере (хотя такое количество это всего полтора месяца непрерывного штурма соседских ушей), а кроме того аудио CD на компьютере я не слушаю. Чтобы решить такую «непростую» задачу надо всего четыре вещи: великий и могучий язык PERL, Last.fm API, CDDB и быть немного программистом.
Или к радости, или к сожалению, у меня есть только 3/4 от необходимого, так как программистом я не являюсь и никоим образом профессия моя к компьютерам не относима (sic!). Ну что же, глаза болят, а руки делают; желание иметь красивую статистику и профиль пересиливают отсутствие необходимых навыков :).

1. Last.fm API

Здесь ничего сложного нет, детально можно почитать на странице описания, а в если вкратце, то работает это так.

1.1

Отсылаем HTTP/1.1 GET-запрос на адрес
http://post.audioscrobbler.com:80/.
Строка запроса должна выглядеть следующим образом:
http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=<client-id>&v=<client-ver>&u=<user>&t=<timestamp>&a=<auth><pre>
<client-id> = id программы клиента  	
<client-ver> = версия программы клиента
<user> = логично, что это имя пользователя 
<timestamp> = Unix time
<auth>= токен авторизации который равен md5(md5(пароль) + timestamp)
Unix time равно количеству секунд прошедших с 1 января 1970 года.

1.2

После того как все отправили получаем от сервера ответ, который выглядит примерно так:
OK
17E61E13454CDD8B68E8D7DEEEDF6170
http://post.audioscrobbler.com:80/np_1.2
http://post2.audioscrobbler.com:80/protocol_1.2
Видим что все хорошо, радуемся и «жмем руку серверу».

1.3

Начинаем сам процесс передачи данных о музыке (на диалекте Last.fm скробблинга) на сервер
По адресу, который получили в ответ на первый запрос, отсылаем POST-запрос, который должен обязательно содержать:
<sessionID> = ID сессии, который получили также ранее
<artist> = Название вашего любимого ВИА
<track> = Название песни вашего любимого ВИА
<time> = Опять таки UNIX Time на момент начала проигрывания.

Это все обязательные поля. Любопытные могут ознакомиться с полным списком. Самое интересное, что timestamp может быть любым и «музыка будущего» это нормально.



Но великий язык PERL не был бы настолько велик, если бы мы не могли воспользоваться сторонними модулями. Я пользовался Net::LastFM::Submission, хоть есть и другие варианты.

2. CDDB (Compact Disc Data Base)

На самом деле мы будем пользоваться не СDDB, которая находиться в собственности у Gracenote (Sony), а безвозмездным аналогом freedb. Политика Gracenote немного похожа на политику любимой AOL, в один момент они просто забанили все «нелицензионные» приложения дабы те перешили на формат CDDB2 который, как вы догадываетесь, обратно не совместим с CDDB1 и кажется лицензия у него совсем не GNU Public.

Что же такое CDDB по сути? На одном острове родился такой индус тайванец Ти Кан который и все это начал. Идея господина Ти Кана была очень проста, каждый диск определяется почти уникальным id который состоит из контрольной суммы времени начала каждого из треков, общего времени звучания и общего количества треков. Одно время наш тайванец пополнял базу сам, а доброжелатели присылали ему на мыло описание диска и его id. Естественно однажды ему это надоело и в с конце концов это вылилось в СDDB, freedb, MusicBrainz и т.д.

Но я отклонился от темы его величества PERL. Чтобы получить список треков с freedb нам надо использовать простейший модуль/скрипт CDDB_get.pm и не забыть вставить в CD-ROM диск.

3. Что же все таки получилось?

В итоге мы имеем незамысловатый скрипт который при запуске ищет диск на freedb, по желанию выводит список всех подходящих вариантов, отсылает список песен этого диска на Last.fm, ждет 30 секунд чтобы вы успели вставить следующий диск и снова делает свое дело.
#!/usr/bin/perl -w

use Net::LastFM::Submission;
use CDDB_get qw( get_cddb );

my %config;
#CONFIG_______________________________________________________________________________
$config{CDDB_HOST}="freedb.freedb.org"; # cddb host
$config{CDDB_PORT}=8880; # cddb port
$config{CDDB_MODE}="cddb"; # cddb mode: cddb or http
$config{CD_DEVICE}="/dev/cdrom"; # cd device
$config{input}=0; # 1: ask user if more than one possibility, 0: no user interaction
$lfmuser='user';
$lfmpass='password';
#____________________________________________________________________________________

open (DB,">>musiclist.txt"); #just for stats

my $submit = Net::LastFM::Submission->new(
'user' => $lfmuser,
'password' => $lfmpass)
$submit->handshake;

%cd=get_cddb(\%config);

while ($previd ne $cd{id}){
unless(defined $cd{title}) { die "no cddb entry found"; }
print "artist: $cd{artist}\n","title: $cd{title}\n","year: $cd{year}\n","id: $cd{id}\n";
print DB $cd{artist}," - ",$cd{title}," \[$cd{year}\]\n";

my $n=1;
foreach my $i ( @{$cd{track}} ) {
print "$n: $i\n";

$submit->submit(
'artist' => $cd{artist},
'title' => $i,
'album' =>$cd{title},
'id' =>$n,
'time' => time - (180-($n+5))*60 # 3 hours back
);
$n++;
}

$previd=$cd{id};
print "_" x 20,"\n30 seconds pause for the next CD ...\n";
sleep(30);
%cd=get_cddb(\%config);
}


В итоге имеем заполненный профиль с опозданием на 3 часа:


Все это написано профаном, так что строго не судите. Также добавлю — это скорее всего не скрипт-реализация, а скрипт-идея и думаю, через неделю в код будет добавлена проверка того, что вводит пользователь и скробблинг с реальной длительностью песен. Плюс надо подумать какое время ставить, чтобы избежать “музыки будущего”. Идеальным вариантом был бы демон который при загрузки аудио диска пишет себе его id в базу, а ночью, к примеру, скробблит все треки из базы с сохранением реальной последовательности и времени, а по желанию несколько любимых песен скробблит много раз.
Tags:
Hubs:
+19
Comments 30
Comments Comments 30

Articles