Last active
October 23, 2022 21:02
-
-
Save njh/9159699 to your computer and use it in GitHub Desktop.
Script to submit the ISRCs stored on an Audio CD to MusicBrainz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# Script to submit the ISRCs stored on an Audio CD to MusicBrainz | |
# | |
# By Nicholas Humfrey <njh@aelius.com> | |
# | |
# | |
# 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`; | |
chomp($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>) { | |
chomp; | |
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; | |
} | |
} | |
close(ICEDAX); | |
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"; | |
exit(-1); | |
} | |
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->timeout(10); | |
$ua->env_proxy; | |
$ua->credentials( 'musicbrainz.org:80', 'musicbrainz.org', $username, $password ); | |
my $request = HTTP::Request->new( 'POST', 'http://musicbrainz.org/ws/1/track/' ); | |
$request->content(join('&',@data)); | |
$request->content_type('application/x-www-form-urlencoded'); | |
my $response = $ua->request($request); | |
print $response->status_line."\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You are probably better off using the much better Python script by @JonnyJD to submit ISRC to MusicBrainz:
https://jonnyjd.github.io/musicbrainz-isrcsubmit/