Pull to refresh

Last.fm Scrobbling

Reading time11 min
Views5K

Начало работы


В пабле нет ни одной нормальной библиотеки для работы с Last.FM «Submission» API PHP, пришлось разбираться и писать самому…
Для начала Вам необходимо перейти на страницу регистрации вашего API аккаунта.
После ввода всех данных, Вам предоставят 2 ключа: публичный и секретный.
image

image
Все поля обязательны к заполнению:
  • Application/Device Name — Имя вашего приложения
  • Application/Device Description — Описание вашего приложения
  • Callback URL — Ссылка на страницу вашего php скрипта, где вы будете принимать token (см.ниже)

Общаемся с Last.FM


Теперь необходимо написать на почту submissions@last.fm для того чтобы Вам активировали собственный clientID.
Собственный clientID иметь в принципе не обязательно, но если вы хотите чтобы при прослушивании трека показывалось приложение, через которые проигрывается трек, то написать все же придется.

image
Вот немного смешной лог моей переписки:
Я: Здравствуйте.
Хочу приобрести собственный clientID для использования в моих запросах.
Сайт — vpleer.ru музыкальный поисковик. Хочу прикрутить scrobbling на last.fm
Спасибо
Adrian: Hey there,
I'm afraid I don't speak Russian, any way you could reword that request in English?
Regards, Adrian
Я: Okey, sorry for bad english..Hello.
I own clientID to use in my queries.
Website — vpleer.ru music search engine. I want to tie scrobbling to last.fm
Thanks. Understand me?)
Adrian: Hey there,
OK, I understood it this time. Your new client id is "***" — you should be able to start using this an hour from now. Happy scrobbling!
Regards, Adrian

Вот так вот =) Свой clientID я предпочел скрыть т.к. если будут какие-либо проблемы по запросам с моего client ID, то могут прикрыть. (По крайней мере так написано у них в API)

Приступаем к работе


Ваш пользователь должен перейти по ссылке: www.lastfm.ru/api/auth?api_key=MY_PUBLIC_KEY, где MY_PUBLIC_KEY это ваш публичный ключ.
Далее если пользователь соглашается работать с этим приложением, то его перенаправляет на тот самый Callback URL с одним единственным GET запросом 'token'…

<?php
    /*
     Coded by Isis (c) 2010
     Link: www.lastfm.ru/api/auth?api_key=8ea0be38326c1275db95968ab677cfb6
     */
    define('API_KEY', '8ea0be38326c1275db95968ab677cfb6');
    define('API_SECRET_KEY', 'b95968ab6775f7474a4db827be6bcf');
    define('CLIENT_ID', 'tst'); //Paste your clientID
    define('CLIENT_VERSION', '1.0');
    
    function xml2arr($xml, $recursive = false)
    {
        if(!$recursive)    $array = simplexml_load_string($xml); else $array = $xml ;
 
        $newArray    = array() ;
        $array         = (array)$array ;
        foreach($array as $key =>$value)
        {
            $value    = (array)$value ;
            if(isset($value[0]))    $newArray[$key] = trim($value[0]); else $newArray[$key] = xml2arr($value,true);
        }
        return $newArray ;
    }
    
    function loginLastFM($url, $type, $post = null)
    {
        if($ch    = curl_init($url))
        {
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Vpleer.ru Scrobbler.');
            $type = $type == 'get'    ?    curl_setopt($ch, CURLOPT_POST, 0)    :    curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
            curl_setopt($ch, CURLOPT_REFERER, 'http://www.lastfm.ru/api/');
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $content    = curl_exec($ch);
            curl_close($ch);
            return $content;
        }
        else
        {
            return 'notconnect';
        }
    }
    
    //1st step. Get token from $_GET['token']
    function getKey($token, $API_KEY, $API_SECRET_KEY)
    {
        $api_sig    = md5('api_key'.$API_KEY.'methodauth.getSessiontoken'.$token.$API_SECRET_KEY);
        $get        = 'method=auth.getSession&api_key='.$API_KEY.'&token='.$token.'&api_sig='.$api_sig;    
        $return        = xml2arr(loginLastFM('http://ws.audioscrobbler.com/2.0/', 'get', $get));
        return $return;
    }
    
    //handShake. Рукопожатие. Вызывается каждый раз когда что-либо не сработало
    function handShake($user, $key, $time, $CLIENT_ID, $CLIENT_VERSION, $API_KEY, $API_SECRET_KEY)
    {
        $handtoken    = md5($API_SECRET_KEY.$time);    
        $handget    = 'hs=true&p=1.2.1&c='.$CLIENT_ID.'&v='.$CLIENT_VERSION.'&u='.$user.'&t='.$time.'&a='.$handtoken.'&api_key='.$API_KEY.'&sk='.$key;
        $handshake    = loginLastFM('http://post.audioscrobbler.com/', 'get', $handget);
        $handecho    = explode("\n", $handshake);
        return $handecho;
    }
    
    //Посылаем на last.fm все данные песни на момент начала проигрывания
    function nowPlaying($session, $artist, $song, $duration)
    {
        $playget    = 's='.$session.'&a='.$artist.'&t='.$song.'&b=&l='.$duration.'&n=&m=';
        $playnow    = loginLastFM('http://post.audioscrobbler.com:80/np_1.2', 'post', $playget);
        return $playnow;
    }
    
    //Посылаем на last.fm все данные песни на момент окончания проигрывания или спустя 50% проигрывания трека
    function submission($session, $artist, $song, $duration, $starttime)
    {
        $subget        = 's='.$session.'&a[0]='.$artist.'&t[0]='.$song.'&i[0]='.$starttime.'&o[0]=P&r[0]=&l[0]='.$duration.'&b[0]=&n[0]=&m[0]=';
        $submission    = loginLastFM('http://post2.audioscrobbler.com:80/protocol_1.2', 'post', $subget);
        return $submission;
    }
    
    function doShake($fmuser, $fmkey, $time, $CLIENT_ID, $CLIENT_VERSION, $API_KEY, $API_SECRET_KEY)
    {
        $handshake    = handShake($fmuser, $fmkey, $time, $CLIENT_ID, $CLIENT_VERSION, $API_KEY, $API_SECRET_KEY);
        $handerror    = trim($handshake[0]);
        $session    = trim($handshake[1]);
        if($handerror == 'OK' && isset($session))
        {
            setcookie('fmsess', $session, time() + 3600 * 24 * 730, '/', '.'.$_SERVER['HTTP_HOST']);
            return 'OK';
        }
        else
        {
            return 'Error : '.$handerror;
        }
    }
    
    $time        = time();

    //Если к нам пришли ппервый раз с last.fm, то ставим куки с необходимыми данными
    if(isset($_GET['token']))
    {
        $return        = getKey($_GET['token'], API_KEY, API_SECRET_KEY);
        $error        = isset($return['error'])            ?    $return['error']            :    null;
        $key        = isset($return['session']['key'])    ?    $return['session']['key']    :    null;
        $user        = isset($return['session']['name'])    ?    $return['session']['name']    :    null;
        if(!isset($error) && isset($key) && isset($user))
        {
            setcookie('fmkey', $key, time() + 3600 * 24 * 730, '/', '.'.$_SERVER['HTTP_HOST']);
            setcookie('fmuser', $user, time() + 3600 * 24 * 730, '/', '.'.$_SERVER['HTTP_HOST']);
            setcookie('scrobb', 'on', time() + 3600 * 24 * 730, '/', '.'.$_SERVER['HTTP_HOST']);
            $a    = doShake($user, $key, $time, CLIENT_ID, CLIENT_VERSION, API_KEY, API_SECRET_KEY);
            header('Location: /scrobb/');
        }
        else
        {
            echo $error;
        }
    }
    
    //1й раз? Надо пожать ручку
    if(isset($_COOKIE['fmkey'], $_COOKIE['fmuser']) && !isset($_COOKIE['fmsess']) && (isset($_POST['nowplaying']) || isset($_POST['submission'])))
    {
        $a    = doShake($_COOKIE['fmuser'], $_COOKIE['fmkey'], $time, CLIENT_ID, CLIENT_VERSION, API_KEY, API_SECRET_KEY);
        echo $a;
    }
    
    //Начали играть!
    if(isset($_POST['nowplaying'], $_COOKIE['fmkey'], $_COOKIE['fmuser'], $_COOKIE['fmsess']))
    {
        $artist        = isset($_POST['artist'])    ?    urldecode($_POST['artist'])    :    'Undefined';
        $song        = isset($_POST['song'])        ?    urldecode($_POST['song'])        :    'Undefined';
        $duration    = isset($_POST['duration'])    ?    urldecode($_POST['duration'])    :    'Undefined';
        setcookie('fmtime', $time, time() + 600, '/', '.'.$_SERVER['HTTP_HOST']);
        echo $playnow    = nowPlaying($_COOKIE['fmsess'], $artist, $song, $duration);
        if(!strstr($playnow, 'OK'))
        {
            echo doShake($_COOKIE['fmuser'], $_COOKIE['fmkey'], $time, CLIENT_ID, CLIENT_VERSION, API_KEY, API_SECRET_KEY);
            //$playnow    = nowPlaying($_COOKIE['fmsess'], $artist, $song, $duration);
        }
    }
    
    //Отправляем на last.fm
    if(isset($_POST['submission'], $_COOKIE['fmkey'], $_COOKIE['fmuser'], $_COOKIE['fmsess']))
    {
        $artist        = isset($_POST['artist'])    ?    urldecode($_POST['artist'])        :    'Undefined';
        $song        = isset($_POST['song'])        ?    urldecode($_POST['song'])        :    'Undefined';
        $duration    = isset($_POST['duration'])    ?    urldecode($_POST['duration'])    :    'Undefined';
        $starttime    = isset($_COOKIE['fmtime'])    ?    $_COOKIE['fmtime']    : time();
        echo $submiss    = submission($_COOKIE['fmsess'], $artist, $song, $duration, $starttime);
        if(!strstr($submiss, 'OK'))
        {
            echo doShake($_COOKIE['fmuser'], $_COOKIE['fmkey'], $time, CLIENT_ID, CLIENT_VERSION, API_KEY, API_SECRET_KEY);
            //$submiss    = submission($_COOKIE['fmsess'], $artist, $song, $duration, $starttime);
        }
    }


* This source code was highlighted with Source Code Highlighter.

Описание


Теперь для того чтобы заскробблить трек на last.fm на начало проигрывания, Вам необходимо передать следующие $_POST параметры к этому скрипту:
  • nowplaying: 1
  • artist: artist
  • song: song
  • duration: 214(длительность композиции в секундах)

А чтобы уже совсем заскробблить трек, то такие параметры:
  • submission: 1
  • artist: artist
  • song: song
  • duration: 122(длительность композиции в секундах)

Скачать scrobb.php
Tags:
Hubs:
Total votes 46: ↑31 and ↓15+16
Comments30

Articles