- 0 Talk
-
Hack:album
album is a perl script, that replaces songs from an album with the playlist. if "add" is given as the second parameter, the songs are added instead of replaced.
Replace the /home/matze/mp3 string with your own music directory!
Todo:
- Detect multiple disc albums
- Sort by release date
Needed Modules:
- Audio::MPD::Collection
- Audio::MPD
- MP3::Tag
- Sort::Array
Example
Edit
matze@nazareth ~ % album Neil\ Young 1: Mirror Ball - (1995) 2: Harvest Moon - (1992) 3: Tonight's the Night - (1975) 4: On The Beach - (1974) 5: Decade (disc 1) - (2002) 6: Decade (disc 2) - (2002) 7: Are You Passionate? - (2002) 8: An Acoustic Tale of Greendale (disc 1) - () 9: An Acoustic Tale of Greendale (disc 2) - () 10: After the Gold Rush - (1970) 11: Harvest - (1972) 12: On the Beach - (1974) 13: Comes a Time - (1978) 14: Afternoon Acoustic - () 15: Silver & Gold - (2000) Please select:
Source code
Edit
#!/usr/bin/perl
#Author: Matthias Küch
#Contact: mail a t matthias-kuech d o t de
#License: GPL2
use Audio::MPD::Collection;
use Audio::MPD;
use MP3::Tag;
use Sort::Array;
use Sort::Array qw(
Sort_Table
Discard_Duplicates
);
# Find compilations (with various artists) and drop them from the selection
sub dropCompilations
{
my(@albumList) = @_;
my $i = 0;
my @albumListcleaned;
foreach my $album (@albumList)
{
my @temp = $mpd->collection->songs_from_album($album);
my $tempArtist = @temp[0]->artist();
if ($tempArtist eq @ARGV[0] )
{
@albumListcleaned[$i] = $album;
$i++;
}
}
return @albumListcleaned;
}
# Select year of album
sub getYearByAlbum
{
my $mpd = Audio::MPD->new();
my($album) = @_;
my @temp = $mpd->collection->songs_from_album($album);
my $filename = "/home/matze/mp3/".@temp[0]->file();
my $mp3 = MP3::Tag->new($filename);
$mp3->get_tags;
my $year = substr($mp3->year,0,4);
if ($year > 0){ return $year; }
else {return "";}
}
sub sortByRelease
{
my(@albumList) = @_;
return @albumListSorted;
}
$mpd = Audio::MPD->new();
# Generates an array with all albums with given artist in it
my @albums = $mpd->collection->albums_by_artist(@ARGV[0]);
my $i = 0;
@albums = dropCompilations(@albums);
my $anzahl = @albums;
if ($anzahl eq 0)
{
print "Artist not found\n";
exit;
}
my @albumArray;
while ($i < $anzahl)
{
@albumArray = ( @albumArray, @albums[$i], getYearByAlbum(@albums[$i]) );
print (($i+1).": ".@albums[$i]." - (".getYearByAlbum(@albums[$i]).") \n");
$i++;
}
@data = Sort_Table(
cols => '2',
field => '2',
sorting => 'ascending',
structure => 'single',
data => \@albumArray,
);
print "Please select:\n";
my $auswahl = <STDIN>;
if ($auswahl eq "q")
{
exit();
}
$auswahl--;
# Fetch songs from album
my @album = $mpd->collection->songs_from_album(@albums[$auswahl]);
if (@ARGV[1] ne "add")
{
$mpd->playlist->clear();
}
foreach $song (@album)
{ # If the artist is the given one, add it
if ($song->artist() eq @ARGV[0])
{
$mpd->playlist->add( $song->file() );
}
}
# Set album feeling (no repeating, no random play)
$mpd->repeat( 0 );
$mpd->random( 0 );
# If the second parameter is "add" add them to the playlist instead of replacing it
if (@ARGV[1] ne "add")
{
$mpd->play(0);
}
print "Playing: ".@ARGV[0]." - ".@albums[$auswahl]."\n";
print qx(mpc playlist);
For those who don't have all their album years saved you will want to add an if statement around the year look up in getyearbyalbum as get_tags don't like not getting a value it seems:
sub getYearByAlbum
{
my $mpd = Audio::MPD->new();
my($album) = @_;
my @temp = $mpd->collection->songs_from_album($album);
my $filename = "/mnt/bigger/Music".@temp[0]->file();
my $mp3 = MP3::Tag->new($filename);
if ($mp3)
{
$mp3->get_tags;
my $year = substr($mp3->year,0,4);
} else {return "";}
if ($year > 0){ return $year; }
else {return "";}
}
Bit of a hack around, does a look up for artist giving a list if no single match found. Looks 'orrible cause I had to teach myself perl to write this. Made the script a lot more usable with a disjointed/disfunctional tags in the music directory (like mine).
#!/usr/bin/perl
#Author: Matthias Küch
#Contact: mail a t matthias-kuech d o t de
#Contributer: Nik Anachi
#Contact: nik d o t anachi a t g m a i l
#License: GPL2
use Audio::MPD::Collection;
use Audio::MPD;
use MP3::Tag;
use Sort::Array;
use Sort::Array qw(
Sort_Table
Discard_Duplicates
);
# Find compilations (with various artists) and drop them from the selection
sub dropCompilations
{
my(@albumList) = @_;
my $i = 0;
my @albumListcleaned;
foreach my $album (@albumList)
{
my @temp = $mpd->collection->songs_from_album($album);
my $tempArtist = @temp[0]->artist();
if ($tempArtist eq @ARGV[0] )
{
@albumListcleaned[$i] = $album;
$i++;
}
}
return @albumListcleaned;
}
# Select year of album
sub getYearByAlbum
{
my $mpd = Audio::MPD->new();
my($album) = @_;
my @temp = $mpd->collection->songs_from_album($album);
my $filename = "/mnt/bigger/Music".@temp[0]->file();
my $mp3 = MP3::Tag->new($filename);
if ($mp3)
{
$mp3->get_tags;
my $year = substr($mp3->year,0,4);
} else {return "";}
if ($year > 0){ return $year; }
else {return "";}
}
sub sortByRelease
{
my(@albumList) = @_;
return @albumListSorted;
}
sub matchArtist
{
my $mpd = Audio::MPD->new();
my @words = $mpd->collection->all_artists;
my $length = @words;
my ($word) = @_;
my $worldlength = length($word);
my $part = 'nothingimportant';
my @match = ();
my @lastmatch = ("No Matches");
my $pos = 1;
my $sanity = 10;
my $i = 0;
my $matchlength = 0;
while ($sanity > 0)
{
@lastmatch = @match;
@match = ();
$part = substr($word, 0, $pos);
while($i < $length)
{
if (@words[$i] =~ m/^($part)/i) {push(@match, @words[$i]);}
$i++;
}
$i =0;
$matchlength = @match;
if ($matchlength == 1) {return @match[0];}
if ($matchlength > 1) {$pos++;}
else {return @lastmatch;}
if($pos > $worldlength) {return @match;}
$sanity--;
}
print "We are INSANE\n";
}
$mpd = Audio::MPD->new();
# Generates an array with all albums with given artist in it
my @artists = matchArtist(@ARGV[0]);
my $artlen = @artists;
my $ii=0;
my $artsel = 1;
if($artlen > 1)
{
print "We couldn't find an exact match for you malformed expression, choose!:\n";
while ($ii < $artlen)
{
print (($ii+1).": ".@artists[$ii]. "\n");
$ii++;
}
print "Please select:\n";
$artsel = <STDIN>;
# chomp($artsel);
if ($artsel == "q")
{
exit();
}
if ($artsel >= $artlen)
{
print "If your not going to be serious, PISS OFF\n";
exit();
}
}
$artsel--;
print @artists[$artsel]."\n";
my @albums = $mpd->collection->albums_by_artist(@artists[$artsel]);
# my @albums = $mpd->collection->albums_by_artist(@ARGV[0]);
my $i = 0;
# @albums = dropCompilations(@albums);
my $anzahl = @albums;
if ($anzahl eq 0)
{
print "Artist not found\n";
exit;
}
my @albumArray;
while ($i < $anzahl)
{
@albumArray = ( @albumArray, @albums[$i], getYearByAlbum(@albums[$i]) );
print (($i+1).": ".@albums[$i]." - (".getYearByAlbum(@albums[$i]).") \n");
$i++;
}
@data = Sort_Table(
cols => '2',
field => '2',
sorting => 'ascending',
structure => 'single',
data => \@albumArray,
);
print "Please select:\n";
my $auswahl = <STDIN>;
if ($auswahl eq "q")
{
exit();
}
$auswahl--;
# Fetch songs from album
my @album = $mpd->collection->songs_from_album(@albums[$auswahl]);
if (@ARGV[1] ne "add")
{
$mpd->playlist->clear();
}
foreach $song (@album)
{ # If the artist is the given one, add it
if ($song->artist() eq @artists[$artsel])
{
$mpd->playlist->add( $song->file() );
}
}
# Set album feeling (no repeating, no random play)
$mpd->repeat( 0 );
$mpd->random( 0 );
# If the second parameter is "add" add them to the playlist instead of replacing it
if (@ARGV[1] ne "add")
{
$mpd->play(0);
}
print "Playing: ".@artists[$artsel]." - ".@albums[$auswahl]."\n";
print qx(mpc playlist);
I think the whole code could be cleaned up a lot. Had enough for one day.
-- Anachi