Site Loader


Radionomy, c’est quoi ?

Radionomy est un service web qui permet d’écouter ou de créer gratuitement une webradio très facilement et avec beaucoup de fonctionnalités. Parmi celles-ci, on retrouve différentes petites API qui permettent de communiquer depuis votre site avec des informations de votre radio Radionomy.

Que proposent ces API ?

Il y a actuellement 4 API. Je vais toutes les présenter, montrer comment les utiliser et donner des petits « tips » pour bien les exploiter (mise en cache, …).

Voici la liste des API:

  • Top Tracks: Récupère les titres les plus diffusés de la radio sur une période donnée
  • Tracklist: Récupère les 50 derniers morceaux diffusés sur la radio
  • Current Song: Récupère le titre joué actuellement sur la radio
  • Current Audience: Récupère le nombre d’auditeurs (sur tous les players) écoutant votre radio

Quelles sont les difficultés de leur utilisation ?

Toutes les API ont une limite d’appels afin de ne pas overflowed les serveurs de Radionomy. Çela implique de ne pas appeler une API toutes les 5s, et donc de mettre en cache le résultat, car si vous disposez de 20.000 auditeurs sur votre site qui chargent en même temps une API, une mauvaise surprise vous attend.

Mais pas de panique, à la fin de ce tutoriel, vous aurez toutes les clés pour maîtriser ces notions !

Mise en place du PHP

Fonctionnement

Nous allons en fait créer une API « tampon » à celles de Radionomy. C’est-à-dire que nous allons appeler une URL du genre http://monsite.com/api.php?api=tracklist&callmeback=no. Cela permettra de regrouper toutes les API en une seule, qui met en cache et qui ne demande pas vos informations d’API Radionomy !

Préparation des outils

Nous allons tout d’abord créer le fichier api.php qui va gérer les appels d’API et la mise en cache.

Une fois le fichier créé, nous allons tout de suite créer les outils que l’on utilisera pour toutes les API, à commencer par les infos de votre API:

<?php
    // ...

    // UID de la radio
    $uid = "votreuid";
    // API Key de la radio
    $apikey = "votreapikey";

Les infos d’API sont récupérables dans votre Radiomanager.

Nous allons ensuite mettre en place une petite fonction qui retourne un paramètre GET (paramètre dans l’URL), ou une valeur donnée si celui-ci n’est pas précisé (cela peut paraître bête, mais cela rendra le code bien plus propre). Je vais mettre une version « longue » qui est plus simple à comprendre, et une version condensée pour aller plus vite. A vous de choisir:

<?php
    // ...

    // Version "longue"
    function getParam($id, $default)
    {
        // Version longue:
        if (isset($_GET[$id]))
            return $_GET[$id];
        else
            return $default;
    }
    // Version "compressée"
    function getParam($id, $default)
    {
        return (isset($_GET[$id])) ? $_GET[$id] : $default;
    }

Construction des URL

Afin de faire une API assez flexible, nous allons créer une seule fonction qui va générer l’UR grâce à l’utilisation d’un tableau qui contiendra les paramètres de l’API.

Le tableau sera de la forme suivante:

array(
    "nom du paramètre" => "valeure par défaut",
    "nom du paramètre" => "valeure par défaut",
    ...
);

Cette fonction a donc besoin de l’URL de base, de l’UID, de l’API Key et des paramètres à chercher dans l’URL:

<?php
    // ...

    function buildUrl($url, $uid, $apikey, $params)
    {
        // On ajoute l'uid, l'apikey et le retour en XML à l'URL
        $url .= "?radiouid=$uid&apikey=$apikey&type=xml";

        // Maintenant on va parcourir les paramètres pour les ajouter en utiliser getParam()
        foreach ($params as $key => $value) {
            $url .= "&$key=" . getParam($key, $value);
        }


        // Et on retourne l'URL construit
        return $url;
    }

Création des tableaux pour chaque API

En sachant que l’on va récupérer l’API souhaitée grâce à un paramètre GET, nous allons créer un tableau qui contiendra le nom de chaque API, leur URL et leurs paramètres en valeur.

Je vais donc vous donner le tableau entier, mais commenté, pour comprendre chaque paramètre de chaque API:

<?php
    // ...

    $api_infos = array(
        // API Top Tracks
        "toptracks" => array(
            "url" => "http://api.radionomy.com/toptracks.cfm",
            "params" => array(
                //  le nombre de morceaux souhaités (de 1 à 50) (défaut = 1)
                "amount" => "1",
                // le nombre de jours à prendre à compte (maximum 7)
                "days" => "1",
                // ajoute l'url de la couverture du titre dans la réponse (YES ou NO)
                "cover" => "NO",
            )
        ),
        // API Tracklist
        "tracklist" => array(
            "url" => "http://api.radionomy.com/tracklist.cfm",
            "params" => array(
                // le nombre de morceaux souhaités (de 1 à 50) (défaut = 1)
                "amount" => "1",
                // ajoute l'url de la couverture du titre dans la réponse (YES ou NO)
                "cover" => "NO"
            )
        ),
        // API Current Song
        "currentsong" => array(
            "url" => "http://api.radionomy.com/currentsong.cfm",
            "params" => array(
                // ajoute l'url de la couverture du titre dans la réponse (YES ou NO)
                "cover" => "NO"
            )
        ),
        // API Current Audience
        "audience" => array(
            "url" => "http://api.radionomy.com/currentaudience.cfm",
            "params" => array()
        ),
    );

Vous êtes maintenant prêt à appeler l’API très facilement !

Ce qui est plus embêtant, c’est de manipuler le XML en PHP, mais avant tout, il faut récupérer l’API demandée en paramètre, et choisir une API par défaut:

<?php
    // ...

    $api_call = getParam('api', 'toptracks');

Et on va maintenant appeler l’API grâce à un Contexte de flux et notre constructeur d’URL.

<?php
    // ...

    $context = stream_context_create(array('http' => array('timeout' => 30)));
    $url = buildUrl($api_infos[$api_call]["url"], $uid, $apikey, $api_infos[$api_call]["params"]);
    $response = @file_get_contents($url);

La variable $response contient maintenant notre précieux XML. Cependant, comme dit en introduction, il faut limiter les appels et donc mettre en cache les réponses.

Mise en cache

On a maintenant une API fonctionnelle, seulement on risque de ne pas respecter les limites d’appels à l’API de Radionomy. Il va donc falloir mettre en cache la réponse.

Pour ce faire, nous allons écrire les résultats dans un fichier et afficher son contenu. Pour savoir quand mettre à jour le fichier, il faut distinguer deux cas:

  • L’API CurrentSong qui limite les appels en fonction du temps de la musique. C’est-à-dire qu’on peut la rappeler une fois la durée de la musique finie
  • Les autres API que l’on peut appeler toutes les 5 minutes

Préparation

On va donc construire notre code de façon à pouvoir gérer ces deux cas.

On va commencer par initialiser les variables suivantes:

<?php
    // ...

    // Dossier qui contiendras les fichiers de cache (il y en aura plusieurs)
    $cache_dir = "https://kodebreaker.eu/cache/";
    // Le fichier cache de l'api voulu (ex: ./cache/currentsong.txt)
    $cache = $cache_dir . $api_call . ".txt";
    // On garde le timestamp de l'execution de côté
    $curr_time = time();
    // Fichier qui contiendra le timestamp pour indiquer quand rappeler l'API CurrentSong
    $callmeback_file = $cache_dir . "callmeback.txt";
    // Variable qui dira si il faut rappeler l'API Radionomy ou juste lire le fichier
    $valid = false;

Détecter quand rappeler l’API

Maintenant, nous allons chercher à savoir quand faut-il rappeler l’API ou juste lire le fichier cache, en utilisant la variable $valid.

L’API CurrentSong nous donne une info très pratique: le Callmeback.

Cette variable contient le temps en millisecondes avant lequel il faudra rappeler l’API. On va donc utiliser le timestamp actuel, et lui rajouter le callmeback pour avoir le timestamp après lequel on peut rappeler l’API. Le résultat sera stocké dans notre fichier $callmeback_file.

Pour le moment on va juste vérifier s’il faut rappeler l’API ou non:

<?php
    //...

    // Si on est sur l'api currentsong
    if ($api_call == "currentsong") {
        // Si le fichier existe, on récupère le timestamp, on le compare avec le timestamp actuel.
        if(@file_exists($callmeback_file))
            $valid = (file_get_contents($callmeback_file) >= $curr_time) ? false : true;
        else { // Sinon on créer le fichier et on doit donc appeler appeler l'api par la suite pour le remplir
            touch($callmeback_file);
            $valid = true;
        }
    }

Et maintenant, pour les autres API, ce sera plus simple: on récupère la date de la dernière modification du fichier cache, et on le compare à notre timestamp actuel moins 5 minutes

<?php
    // ...

    // Si on est sur l'api currentsong
    if ($api_call == "currentsong") {
        // Si le fichier existe, on récupère le timestamp, on le compare avec le timestamp actuel.
        if(@file_exists($callmeback_file))
            $valid = (file_get_contents($callmeback_file) >= $curr_time) ? false : true;
        else { // Sinon on créer le fichier et on doit donc appeler appeler l'api par la suite pour le remplir
            touch($callmeback_file);
            $valid = true;
        }
    }
    else {
        $expire = $curr_time - 310; // 310 pour avoir un peu de marge
        $valid = (@file_exists($cache) && @filemtime($cache) > $expire) ? false : true;
    }

Rappeler l’API et/ou lire le fichier cache

Si $valid vaut true, on doit rappeler l’API et remplir le fichier cache.

<?php
    // ...

    if ($valid) {
    }

Nous allons ensuite créer le fichier de cache, s’il n’existe pas

<?php
    // ...

    if ($valid) {
        if (!@file_exists($cache))
            touch($cache);
    }

Maintenant nous allons prendre la partie qui appelle l’API et la déplacer ici

<?php
    // ...

    if ($valid) {
        if (!@file_exists($cache))
            touch($cache);

        $context = stream_context_create(array('http' => array('timeout' => 30)));
        $url = buildUrl($api_infos[$api_call]["url"], $uid, $apikey, $api_infos[$api_call]["params"]);
        $response = @file_get_contents($url);
    }

Si on a une réponse, on l’écrit dans le fichier de cache

<?php
    // ...

    if ($valid) {
        if (!@file_exists($cache))
            touch($cache);
        $context = stream_context_create(array('http' => array('timeout' => 30)));
        $url = buildUrl($api_infos[$api_call]["url"], $uid, $apikey, $api_infos[$api_call]["params"]);
        $response = @file_get_contents($url);

        if($response) {
            @file_put_contents($cache, $response);
        }
    }

Enfin, si c’est l’API CurrentSong, on met à jour le Callmeback en faisant le calcul: $curr_time + [callmeback], en sachant que le timestamp est en secondes et callmeback en milliseconds, il faudra le diviser par 1000:

<?php
    // ...

    if ($valid) {
        if (!@file_exists($cache))
            touch($cache);
        $context = stream_context_create(array('http' => array('timeout' => 30)));
        $url = buildUrl($api_infos[$api_call]["url"], $uid, $apikey, $api_infos[$api_call]["params"]);
        $response = @file_get_contents($url);
        if($response) {
            @file_put_contents($cache, $response);

            if ($api_call == "currentsong") {
                $xml = new SimpleXMLElement($response);
                @file_put_contents($callmeback_file, $curr_time + ($xml->track->callmeback / 1000));
            }
        }
    }

Il ne nous reste plus qu’à lire et afficher le contenu du fichier cache !

Afficher le résultat

Je vais vous montrer comment afficher le contenu de l’API en XML et en JSON (je préfère pour ma part manipuler le JSON)

Retour en XML

Il faut préciser au navigateur que nous envoyons du XML en précisant le header Content-Type la valeur application/xml, puis en faisant simplement un echo du contenu du fichier cache:

<?php
    // ...

    header('Content-Type: application/xml');
    echo file_get_contents($cache);

Retour en JSON

Il faut cette fois-ci faire quelques manipulations avec notre contenu. Nous allons d’abord créer un Objet XML, pour ensuite pouvoir l’encoder en JSON avec la fonction json_encode.
Cette fois-ci le Content-Type sera sur application/json, ce qui donne:

<?php
    // ...

    header('Content-Type: application/json');
    echo json_encode(simplexml_load_string(file_get_contents($cache)));

Utilisation de votre API

Votre API est maintenant prête à être utilisée en appelant l’url:
http://[votresite]/chemin_vers_le_fichier.php?api=[api_à_appeler]

Et si vous souhaitez ajouter des paramètres en fonction de l’API:
http://[votresite]/chemin_vers_le_fichier.php?api=[api_à_appeler]&[param1]=[value1]&[param2]=[value2]

Remerciements et téléchargement

Merci d’avoir lu ce tutoriel. Je vous laisse ci-joint un zip qui contient l’API en XML et JSON avec le dossier cache etc…

Post Author: Alexandre Navaro

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *