lastfm scrobbler for icecast

Soumettre à Last.fm les chansons d’un flux Icecast

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)
        continueLangage du code : 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.

Lire Soumettre à Last.fm les chansons d’un flux Icecast

lycee gabriel guisthau nantes

Section Européenne Anglais au Lycée Guist’Hau

Qu’est-ce qu’une section européenne?

La section européenne permet aux élèves de renforcer la maîtrise de l’anglais, à l’oral comme à l’écrit, grâce à la pédagogie bilingue.

En dehors des cours de langue classiques avec ses objectifs linguistiques et culturels, les élèves suivent des cours d’Histoire-Géographie ou de Physique-Chimie en langue étrangère.

Au terme des trois années, les élèves se présentent au baccalauréat à l’épreuve de « section européenne » et peuvent obtenir une mention européenne.

Qu’est ce que la DNL?

Dans les cours de DNL (Discipline Non-Linguistique), les élèves communiquent en langue étrangère tout en restant concentrés sur une question d’Histoire, de Géographie ou de Physique-Chimie.

A titre d’exemple en Histoire-Géographie, on adopte un regard anglophone sur des questions au programme. Les cours de DNL renforcent ainsi non seulement la pratique de la langue, mais aussi les connaissances sur la culture anglophone. Les élèves apprennent à lire, expliquer et analyser des documents authentiques,

En Physique-Chimie, à partir de supports variés, les élèves vont produire des cartes mentales, des posters, réaliser des exposés, des vidéos en langue anglaise traitant des différentes parties du programme. Certains thèmes peuvent également être traités de façon expérimentale. Le but étant de savoir décrire et expliquer des phénomènes scientifiques en anglais, et éventuellement d’émettre son point de vue.

Au lycée Guist’hau, les élèves sont affectés dans les groupes de DNL (Histoire-Géographie et Physique-Chimie) de manière aléatoire, de manière à créer des groupes de DNL équilibrés au niveau du nombre d’élèves. Un réajustement est effectué en Première afin d’affiner la cohérence avec les spécialités choisies.

Quels sont les projets en section européenne?

La section européenne vise l’acquisition d’un niveau de langue soutenu et souhaite favoriser l’ouverture européenne et internationale des élèves.

La section européenne Anglais organise un voyage culturel pendant l’année de première. En terminale, les élèves passent le Cambridge English Certificate (CEC).

Quel est le cursus en section européenne?

Seconde européenne3h Anglais + 1h DNL (Histoire-Géographie ou Physique-Chimie)
Première européenne2h30 Anglais + 1h DNL
Terminale européenne2 h Anglais + 1h DNL
Horaires hebdomadaires en section Européenne Anglais

Notez bien qu’il n’est pas possible pour les élèves de choisir la matière de DNL: les élèves sont intégrés à la DNL Histoire-Géographie ou Physique-Chimie de manière aléatoire, pour former des groupes équilibrés.

Qu’est ce que la mention européenne?

Actuellement, la mention européenne pour le baccalauréat est validée si la note à l’épreuve écrite de langue est égale ou supérieure à 12/20 et si la note à l’épreuve orale de la discipline non linguistique est égale ou supérieure à 10/20.

La mention européenne donne une valeur ajoutée au diplôme de baccalauréat et représente un plus pour le parcours post-bac quelles que soient les études supérieures visées.

A qui s’adresse la section européenne?

Aux élèves motivés par la langue et la culture anglophone qui ont un bon niveau de langue et qui aiment s’impliquer en classe. Elle est ouverte aux élèves issus de sections européennes, mais aussi à ceux qui n’ont pas eu cette opportunité.

Le programme en anglais européen est identique à celui du tronc commun d’une classe classique. Cependant, le rythme de travail y est plus soutenu et les exigences renforcées, notamment en termes d’autonomie.

Lire Section Européenne Anglais au Lycée Guist’Hau

icecast ssl https cloudflare

Icecast en HTTPS avec Cloudflare et Nginx

Servir une radio Icecast en HTTP depuis une page HTTPS finit toujours par casser quelque chose. Le navigateur bloque le contenu mixte, le lecteur HTML5 refuse parfois le flux, et les appels vers le JSON de statut deviennent capricieux. Bref, la radio marche, mais seulement les jours pairs. Excellent pour le suspense, moins pour l’écoute.

La solution propre consiste à placer Icecast derrière Nginx, puis à laisser Nginx gérer HTTPS avec un certificat valide. Cloudflare reste devant le serveur, le flux sort en HTTPS sur le port standard 443, et Icecast continue tranquillement d’écouter en local sur son port habituel.

Dans ce guide, nous allons donc configurer une architecture simple, fiable et durable :

  • Cloudflare gère le DNS et le proxy HTTPS public ;
  • Nginx reçoit les requêtes HTTPS sur le port 443 ;
  • Nginx transmet les requêtes à Icecast en local ;
  • Icecast reste inaccessible directement depuis Internet ;
  • le lecteur audio peut être intégré sans erreur de contenu mixte.

Cette méthode évite aussi d’exposer une URL du type https://radio.example.com:8443/. Elle fonctionne, certes, mais elle sent un peu le garage ouvert avec la lumière allumée.

Lire Icecast en HTTPS avec Cloudflare et Nginx