Voici le script python que j’ai écrit pour soumettre automatiquement à Last.fm les chansons qui sont diffusées sur ma radio Icecast.
Au fil du temps, j’ai publié dans ces colonnes différents tutoriels pour gérer une radio avec Icecast, à l’aide de Winamp, VirtualDJ, et SAM Broadcaster dont on pouvait créer un fichier texte qui pouvait ensuite être filtré puis utilisé avec un script PHP pour soumettre les chansons à Last.fm.
Il y a quelques semaines, Stéphan m’a contacté pour m’informer que le script PHP que j’utilisais jusqu’alors pour scrobbler les titres était maintenant incompatible avec PHP8, et qu’il lui fallait installer PHP7.4 spécifiquement pour le faire tourner.
Le script n’utilisait pas les dernières API de Last.fm non plus, donc c’était le bon moment de moderniser tout cela. J’en ai d’ailleurs profité pour servir le serveur Icecast en HTTPS.
Le choix de Python
Après de multiples essais, je me suis vite rendu compte que PHP n’était pas du tout adapté au scrobbling : la plupart des librairies PHP sont maintenant obsolètes (PHP8) ou ne sont plus maintenues car Last.fm est en perte de vitesse (par rapport à ce que c’était il y a quelques années).
Python, au contraire, est très simple à utiliser et il existe une librairie spécifique dédiée à l’API Last.fm qui nous permet de soumettre les titres simplement: pylast
.
Enfin, l’avantage de python
est qu’il est installé et mis à jour sur toutes les distributions Linux et MacOS nativement et donc cela rend le code portable et facile à transporter.
Outre Python 3, vous avez besoin du gestionnaire de paquets pip
:
apt install python3-pip
Vous avez également besoin de quelques modules supplémentaires, que l’on installe avec pip
:
python3 -m pip install --upgrade pip
pip3 install pylast requests
C’est tout ce qu’il vous faut au niveau des dépendances. Plus besoin de PHP ni de ses librairies, plus besoin de stocker le nom des titres dans un fichier texte, tout va se faire en direct depuis le serveur Icecast.
Last.FM Scrobbler for Icecast
Le script Last.FM Scrobbler for Icecast vérifie le statut du server Icecast toutes les 30 secondes. Si le serveur est démarré et que la radio joue, il récupère les informations de la chanson et les soumet à Last.fm, tout en vérifiant bien que la chanson n’est pas la même que la précédente. Cela évite tout doublon, ce qui fausserait les soumissions du compte.
Si le serveur Icecast n’est pas démarré, le script vous avertit et attend 5 minutes.
Si le serveur Icecast est démarré mais que le fichier status-json.xsl
ne contient pas les informations nécessaires, le script vous avertit et vous recommande de redémarrer votre webradio car la connexion avec Icecast est perdue.
On crée notre script:
nano /home/scripts/lastfm-scrobbler-icecast.py
Et on y ajoute:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#-----------------------------------------------------------------------
# Script name : Last.FM Scrobbler for Icecast
# Created By : Matt Biscay
# Created Date: 2023/01/24
# Author URI : https://www.skyminds.net
# Version : 1.0.0
# Copyright : 2023 SkyMinds.Net
# ----------------------------------------------------------------------
"""
This script will check the status of the icecast server every 30 sec and if the server is running, it will check for the currently playing track and scrobble it to LastFM if it's different from the last scrobbled track.
If the server is not running, the script will wait for 5 minutes before retrying.
It uses the pylast library to interact with the LastFM API.
@param API_KEY: the LastFM API key
@param API_SECRET: the LastFM API secret
@param username: the LastFM username
@param password: the LastFM password
@param icecast_url: the URL of the icecast server status page
"""
import pylast
import time
import requests
import json
# --------------------------------------------------
# --------- EDIT CONFIGURATION HERE ----------------
# --------------------------------------------------
# Your LastFM API key and secret
API_KEY = "LASTFM_API_KEY"
API_SECRET = "LASTFM_API_SECRET"
# The username and password of the user you want to authenticate
# and scrobble the track for
username = "LASTFM_USER"
password = "LASTFM_PWD"
# The URL of the Icecast server's status-json.xsl page
icecast_url = "http://icecast.example.com:8000/status-json.xsl"
# ------------------------------------------------
# ---------- END OF CONFIGURATION ---------------
# ------------------------------------------------
# Create a new LastFM network object
network = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET,
username=username, password_hash=pylast.md5(password))
# The previously scrobbled track name
previous_track = ""
print("# ------------------------------------------ #")
print("# Script: Last.FM Scrobbler for Icecast #")
print("# Author: Matt Biscay #")
print("# URL : https://www.skyminds.net #")
print("# ------------------------------------------ #")
print("")
while True:
try:
# Make a GET request to the status-json.xsl page
response = requests.get(icecast_url)
except requests.exceptions.ConnectionError as e:
print("Error: Icecast server is down.")
# Wait for 5 minutes before retrying
time.sleep(5*60)
continue
if response.status_code != 200:
print("Error: Icecast server is not running or there is some other error")
# Wait for 5 minutes before retrying
time.sleep(5*60)
continue
# Parse the JSON response
data = json.loads(response.text)
# Get the currently playing track information
if "icestats" in data and "source" in data["icestats"] and "artist" in data["icestats"]["source"] and "title" in data["icestats"]["source"]:
artist = data["icestats"]["source"]["artist"]
track = data["icestats"]["source"]["title"]
current_track = f'{artist} - {track}'
if current_track != previous_track:
# Scrobble the track
try:
timestamp = int(time.time())
network.scrobble(artist=artist, title=track, timestamp=timestamp)
print(f"Track scrobbled successfully: {current_track}")
previous_track = current_track
except pylast.WSError as e:
print("Error:", e)
# Wait for 30 seconds before checking for new tracks
time.sleep(30)
else:
print("Error: Icecast XML does not contain the required information. Restart your webradio.")
# Wait for 1 minutes before retrying
time.sleep(60)
continue
Code language: PHP (php)
Editez les variables dans la partie EDIT YOUR CONFIGURATION: vous avez besoin de votre clé API last.fm ainsi que la clé API secret, de votre nom d’utilisateur et mot de passe last.fm, et enfin l’adresse complète du fichier XML d’Icecast, status-json.xsl
.