Music listening via Last.fm

Once upon a time, before the Raspberry Pi allowed for cheap DIY projects, I purchased a Logitech Squeezebox Radio. The greatest feature was the music streaming service of Last.fm. Then came Spotify and others; and Last.fm eventually ceased streaming.

But, what it’s always done (setup dependent), is log what you listen to via its scrobbling service. Effectively, every time you listen to Spotify, radio stations, music on your smart phone… you POST data (track, song title, album, artist etc.) to your Last.fm account.

My musical taste hasn’t changed much over a decade, as I’m too long in the tooth to change my listening flavour, which is predominantly the music I grew up with in the 80s and 90s. Of course, I’m not adverse to discovering great new music, but most people have a staple diet.

Recently however, my listening library has been blemished by my children’s listening habits as they monopolise the devices around the house. I love them with all my heart. But we’ve got to do something about their tastes in music.

So, I’m automating a weekly script to grab the top 5 artists per week – scrobbled from various sources to my Last.fm account. Regular monitoring will tell if their listening is outweighing mine.

I make use of the Last.fm api. I’m using Perl, and although there are a few dedicated modules available to garner data from Last.fm, I’ll stick to LWP::UserAgent as the client, and place all the required parameters into the url.

Oh… and let’s visualise the results with a bar chart.

The script

##########################
# last fm weekly artists #
##########################

# top 5 weekly artists to barchart
# not using Last FM cpan module

#!/usr/bin/perl
use strict ;
use warnings ;
use LWP::UserAgent;
use JSON qw(decode_json);
use Config::Tiny;
use POSIX qw (strftime);
use GD::Graph::bars;

my $date = strftime "%e-%b-%Y",localtime;

my $config_file = "$ENV{HOME}/.lastfm.cnf";
die "$config_file not there" unless -e $config_file;

my $config = Config::Tiny->read($config_file);

my $user    = $config->{lastfm}->{user};
my $api_key = $config->{lastfm}->{api_key};
                  
my $base_url    = "http://ws.audioscrobbler.com/2.0";
my $method_url  = "user.getweeklyartistchart";
my $format      = "json";

my $request_url = "$base_url/?method=$method_url&user=$user&api_key=$api_key&format=$format";

# send the request and decode json to perl data structure
# not too much held in memory - no need for content_reference
# or write to disk
my $ua        = LWP::UserAgent->new();
my $request   = $ua->get($request_url);
my $json      = $request->decoded_content;
my $perl_data = decode_json($json);

my (@artists, @playcounts);

# only need the top 5 weekly artists in barchart
my $x = 0;
DATUM:
foreach my $thing ( @{$perl_data->{weeklyartistchart}->{artist} } ) {
$x++;
push (@artists,$thing->{'name'});
push (@playcounts,$thing->{'playcount'});
# exit when 5 is reached
last DATUM if $x == 5;
}

# artists and playcounts to bar chart
# create the layout
my $data = GD::Graph::Data->new( [ \@artists,\@playcounts ] );
my $graph =  GD::Graph::bars->new();

$graph->set(
x_label => 'ARTISTS',
y_label => 'PLAYCOUNT',
x_labels_vertical => 1,
bar_spacing       => 1,
title   => "Last.fm data $date",
) or die $graph->error;

$graph->plot($data) or die $graph->error;

# barchart to image file
my $file = "WeeklyArtists_$date.png";
open (my $picture,'>',$file) or die "Cannot open file $file $!";
binmode $picture;
print $picture $graph->gd->png;
close $picture;
exit;

Which gives me a little image file that displays…

All looks ok. The last artist I know little about. But, if you’ve ever seen the movie Drive (2011), then this is a standout track https://www.youtube.com/watch?v=-DSVDcw6iW8.

It’s quite easy to build on this, and obtain different data from Last.fm. If you don’t yet scrobble to Last.fm and you’d like to; simply head over to https://www.last.fm/ and create an account. Then on whatever listening platform; Spotify, Deezer etc. enable scrobbling from the settings.

To my knowledge, Amazon Music does not scrobble to Last.fm – so this might prove a forlorn exercise.

Until the next time.