пятница, 4 декабря 2009 г.

MOC + last.fm + русские тэги в UTF-8

Прочитал про этот плеер, понравился, начал пользоваться. Нашлись два маленьких неприятных момента: кривое отображение моих русскоязычных utf-8 тэгов и отсутствие скробблинга на last.fm. Чуток поковырявшись, оба решил, делаю пометку, чтобы не забыть как.

У меня нет раздела с windows, вся музыка хранится на ext3 разделе и тэги сконвертированы в utf-8 с помощью tag2utf. Но MOC отображает их точками, а если в конфиге выставить параметр ID3v1TagsEncoding=UTF-8, то решеточками. Оказалось, что проблема в тэгах ID3v1 и чтобы ее решить, надо их поудалять, а оставить ID3v2. Чтобы решать проблему комплексно, одновременно с конвертированием, надо делать так:
Ставим пакет python-mutagen(в ubuntu называется так). И даем команду

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

Команда перебирает все mp3 файлы в текущем каталоге и подкаталогах, обрабатывая их нужным образом. Готово, теперь вся наша музыка в пригодном для переваривания MOC'ом виде.

Теперь к скробблингу. Для его организации нам будет нужна опция OnSongChange в конфиге. Ее наличие зависит от версии MOC. Мне пришлось обновиться на вариант devel(2.5.0-alpha4), так как в обычном этой опции не было.
Кроме этого надо поставить пакет lastfmsubmitd. В конфиге(/etc/lastfmsubmitd.conf) прописать данные своего аккаунта. Если будет ругаться на отсутствие данных аккаунта, значит что-то с правами доступа к этому файлу.
Потом создать скрипт moc_submit_lastfm, вот такого содержания:

#!/usr/bin/env python

from datetime import datetime
from optparse import OptionParser
from subprocess import call, Popen, PIPE
import time

parser = OptionParser()
parser.add_option("-a", "--artist", dest="artist")
parser.add_option("-t", "--title", dest="title")
parser.add_option("-A", "--album", dest="album")
parser.add_option("-l", "--length", dest="length")

# Treating everything as bytestrings throughout seems to work OK even
# with non-ASCII characters in song titles etc (at least with a UTF-8
# locale).

def still_playing(artist, album, title):
p = Popen(["mocp", "-i"], stdout=PIPE)
out, err = p.communicate()
lines = out.split("\n")
for s in ["Artist: %s" % artist, "Album: %s" % album, "SongTitle: %s" % title]:
if not s in lines:
return False
return True

def submit_to_lastfm(artist, album, title, length):
args = ["/usr/lib/lastfmsubmitd/lastfmsubmit", "--artist", artist, "--title", title, "--length", length]
if album is not None:
args.extend(["--album", album])
call(args)

def main():
options, args = parser.parse_args()
if any(not options.__dict__.get(k) for k in ["artist", "title", "length"]):
print "All of artist, album, length must be specified"
exit(1)
if ":" in options.length:
mins, secs = options.length.split(":")
length = int(mins) * 60 + int(secs)
else:
length = int(options.length)
# wait until song is half played
wait = length/2

start = datetime.now()
while True:
time.sleep(5)
if not still_playing(options.artist, options.album, options.title):
exit(1)
if (datetime.now() - start).seconds > wait:
submit_to_lastfm(options.artist, options.album, options.title, options.length)
exit(0)

if __name__ == '__main__':
import sys
main()

И в конфиге .moc/config задать вышеуказанную OnSongChange:

OnSongChange = "/home/triklozoid/bin/moc_submit_lastfm --artist %a --title %t --length %d --album %r"

заменив путь на путь к созданному Вами скрипту.

Вот и все, вроде ничего не забыл.

Про скробблинг прочитал здесь, про перекодирование здесь, про MOC тут и там.


5 комментариев:

Юрий комментирует...

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

параметр -eCP1251 лишний раз все теги и так в UTF

triklozoid комментирует...

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

SoaT комментирует...

Спасибо большое. Действительно скроблит.
Интересно было бы по какому алгоритму. А то в коде совершенно ничего не понимаю ^)
Было бы ещё круто поиметь всякие плюшки, типо слушает сейчас в таком-то плеере =)

triklozoid комментирует...

Ого! Кто-то еще читает. :-)
Я когда статью писал, даже не читал код, но вообще там всё довольно понятно.
При смене песни, moc запускает скрипт, скрипт ждёт 5 секунд, проверяет играет ли еще эта песня, потом считает сколько времени прошло с начала песни и если это больше половины длины, то скробблит.
В таком-то плеере сходу не нашёл как указать, возможно lastfmsubmitd этого не умеет. С другой стороны он должен указывать себя и это правильно, ведь скробблинг идёт с него.

SoaT комментирует...

4 декабря 2009... только увидел) Однако рецепт оказался актуальным по сю-пору. За это сенкс большой.
А с кодом и плюшками попытаюсь тогда сам разобраться