Skip to content

Instantly share code, notes, and snippets.

Last active Sep 16, 2019
What would you like to do?
Script to submit the ISRCs stored on an Audio CD to MusicBrainz
# Script to submit the ISRCs stored on an Audio CD to MusicBrainz
# By Nicholas Humfrey <>
# Install the following Debian packages:
# icedax
# libmusicbrainz-discid-perl
# libterm-readpassword-perl
# libwebservice-musicbrainz-perl
# Version 0.5 - 29th May 2009
use MusicBrainz::DiscID;
use Term::ReadPassword;
use WebService::MusicBrainz;
use WebService::MusicBrainz::Release;
use strict;
use warnings;
# Which CD drive?
my $drive = $ARGV[0] || MusicBrainz::DiscID::default_device;
die "Unable to find audio CD in drive.\n" unless ($drive);
die "Error: CD-Rom device does not exist: $drive" unless (-e $drive);
print "Reading CD in drive: $drive\n";
# Locate icedax
my $icedax = `which icedax`;
die "Unable to find icedax command in your search path.\n" unless ($icedax);
# Read in ISRCs using Icedax
my $mcn = undef;
my @isrcs = ();
open(ICEDAX, "$icedax -D $drive -g -H -J -Q -v trackid 2>&1 |")
or die "Failed to run icedax command: $!";
while(<ICEDAX>) {
if (/T:\s+(\d+)\s+ISRC:\s+([A-Z]{2}-?\w{3}-?\d{2}-?\d{5})$/) {
my ($num, $isrc) = ($1-1, uc($2));
$isrc =~ s/\W//g;
$isrcs[$num] = $isrc;
} elsif (/Media catalog number: (.+)/i) {
$mcn = $1;
die "Failed to get ISRCs for disc.\n" unless (scalar(@isrcs) > 0);
# Read the DiscID using libdiscid (icedax doesn't always get it right)
my $disc = new MusicBrainz::DiscID($drive);
die "Failed to read DiscID: ".$disc->error_msg() if ( $disc->read() == 0 );
# Display what we parsed in
print "DiscID: ".$disc->id."\n";
print "MCN: ".$mcn."\n" if ($mcn);
for(my $i=0; $i<scalar(@isrcs); $i++) {
printf("Track %2.2d: %s\n", $i+1, $isrcs[$i] || '');
print "\n";
# Search MusicBrainz for release
my $ws = WebService::MusicBrainz::Release->new();
my $result = $ws->search({ DISCID => $disc->id });
my @releases = @{$result->release_list->releases};
if (scalar(@releases) < 1) {
print "Failed to find any matches for DiscID in MusicBrainz.\n";
print "You can submit the CD here:\n";
print $disc->submission_url()."\n";
printf("Found %d matches for DiscID:\n", scalar(@releases));
for(my $i=0; $i<scalar(@releases); $i++) {
my $release = $releases[$i];
printf("%2.2d) '%s' by '%s' (%s)\n", $i+1, $release->title, $release->artist->name, $release->id);
# FIXME: display release events here
# FIXME: display track list?
print "\nAre any of the above the correct disc? ";
die "Cancelled.\n" unless (<STDIN> =~ /(\d+)/);
my $release = $releases[$1-1];
print "\n";
# Create data to post to server
my @data = ();
my @tracks = @{$release->track_list->tracks};
for(my $i=0; $i<scalar(@tracks); $i++) {
my $track = $tracks[$i];
my $isrc = $isrcs[$i];
if (defined $isrc && $isrc ne '' && $isrc !~ /^0+$/) {
push(@data, "isrc=".$track->id.'%20'.$isrc);
# Check that we have something to submit
die "No valid ISRCs to submit." if (scalar(@data) < 1);
# Ask for MusicBrainz username and password
print "MusicBrainz Username: ";
my $username = <STDIN>; chomp($username);
my $password = read_password('Password: ');
# Send to Musicbrainz
my $ua = LWP::UserAgent->new;
$ua->credentials( '', '', $username, $password );
my $request = HTTP::Request->new( 'POST', '' );
my $response = $ua->request($request);
print $response->status_line."\n";
Copy link

njh commented Sep 16, 2019

You are probably better off using the much better Python script by @JonnyJD to submit ISRC to MusicBrainz:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment