I've been working on a script to be able to select music in mythmusic and copy it to a portable MP3 player or memory card.
I've managed this by adding a menu item in the music menu to copy the playlist.
Howto:
1) copy copyplaylist.pl to /usr/bin:
Code:
#!/usr/bin/perl
# Copy mythmusic playlist to a portable mp3 player or memory card
#
# based upon m3u2myth.pl by Joseph N. Mondloch
use Getopt::Long;
use DBI;
# database settings
my $DBuser = 'mythtv';
my $DBpass = 'mythtv';
my $DBhost = 'localhost';
my $dbh;
# playlist details
my $playlistname;
my $playlistid;
# paths to music files and output and finish sound
my $music = '/myth/music';
my $output;
my $sound = '/home/mythtv/sounds/BONK2.wav';
my $help = 0;
my $test =0;
my $mkartist = 0;
my $mkalbum = 0;
print "\n---------------------------------------\n";
print "Copy mythmusic playlist to device/path \n";
print "---------------------------------------\n\n";
GetOptions (
'name=s' => \$playlistname,
'to=s' => \$output,
'test' => sub { $test =1; },
'help' => sub { $help = 1; },
'mkartist' => sub { $mkartist =1; },
'mkalbum' => sub { $mkalbum =1; },
);
#connect to database
$dbh = DBI->connect("dbi:mysql:database=mythconverg;host=$DBhost;user=$DBuser;password=$DBpass") || die "$DBI::errstr";
# show help
if ( $help==1)
{
print "Usage:\n";
print " --name \t\t [playlist name to copy]\n";
print " --to \t\t [path to copy playlist files to]\n";
print " --test \t\t [test reads from database, but does not copy files or make directories]\n";
print " --mkartist \t\t [puts songs in artist directories]\n";
print " --mkalbum \t\t [puts songs in album directories (inside arist directories if --mkartist used]\n";
}
# check if output defined
if( defined($output) )
{
# copy the music bit
if (defined($playlistname))
{
# check if playlist defined
print "using defined playlist";
&getID($playlistname);
&readDBandCopy($playlistid);
}
else
{
# else get the default playlist songids
print "using default playlist\n";
$playlistname = 'default_playlist_storage';
&getID($playlistname);
&readDBandCopy($playlistid);
}
}
#play a sound
system("aplay -q $sound");
exit(0);
#---------------------------------------------------------------------------------------------------------
# Get playlist id from mythdatabase
#---------------------------------------------------------------------------------------------------------
sub getID {
my %playlistname = @_[0];
print "Playlist_name: $playlistname\n";
$sth = $dbh->prepare("SELECT playlist_id FROM music_playlists WHERE playlist_name=\"$playlistname\";");
$sth->execute || die "Unable to execute query: $dbh->errstr\n";
while($row = $sth->fetchrow_arrayref)
{
$playlistid = $row->[0];
}
print "Playlist_id: $playlistid\n";
}
#---------------------------------------------------------------------------------------------------------
# Read playlist from mythdatabase
#---------------------------------------------------------------------------------------------------------
sub readDBandCopy
{
my $playlistid = $_[0];
my @songids;
print "Retrieving playlist: $playlistid...\n";
$sth = $dbh->prepare("SELECT playlist_songs FROM music_playlists WHERE playlist_id=$playlistid;");
$sth->execute || die "Unable to execute query: $dbh->errstr\n";
while($row = $sth->fetchrow_arrayref)
{
@songids = split /,/, $row->[0];
}
#print "@songids\n";
print "Retrieving filepaths: $playlistid...\n";
foreach(@songids)
{
if ($_ < 0)
{
print "Playlist contains sub-playlist ($_)...\n";
readDBandCopy(0 - $_);
}
else
{
#get the filepath to copy from
$sth = $dbh->prepare("SELECT filename FROM music_songs WHERE song_id=$_;");
$sth->execute || die "Unable to execute query: $dbh->errstr\n";
while($row = $sth->fetchrow_arrayref)
{
$filename = $row->[0];
}
#file to copy from
$filein = $music."/".$filename;
#break this up to get the artist and album names
@dir = split(/\//, $filename);
$artistname = @dir[0];
$albumname = @dir[1];
#create the directory structure for the mp3 file
$fileout = $output."/".@dir[2];
if ($mkartist==1)
{
if ($test==0) {system("mkdir \"$output/$artistname\" ");}
$fileout = $output."/".$artistname."/".@dir[2];
}
if ($mkartist==1 && $mkalbum==1)
{
if ($test==0) {system("mkdir \"$output/$artistname/$albumname\" ");}
$fileout = $output."/".$artistname."/".$albumname."/".@dir[2];
}
if ($mkartist==0 && $mkalbum==1)
{
if ($test==0) {system("mkdir \"$output/$albumname\" ");}
$fileout = $output."/".$albumname."/".@dir[2];
}
#copy the files
if ($test==0)
{
print "Copying: \t $filein \n to:\t\t $fileout\n";
system("cp \"$filein\" \"$fileout\"");
}
else
{
print "Testing: \t $filein \n to:\t\t $fileout\n";
}
} #end of playlist check
} #end of foreach
} #end of sub
set permissions and make executable
chmod 777 copyplaylist.pl
2) add button/menus to /usr/share/mythtv .xml files
in musicmenu.xml add:
Code:
<button>
<type>MUSIC_COPY</type>
<text>Copy playlist to SDCard</text>
<action>MENU cp2mp3_menu.xml</action>
</button>
create a new menu cp2mp3_menu.xml like
Code:
<mythmenu name="cp2mp3">
<button>
<type>MUSIC_COPY</type>
<text>Copy in album directories</text>
<action>EXEC /usr/bin/copyplaylist.pl --to /media/usbdisk/ --mkalbum </action>
</button>
<button>
<type>MUSIC_COPY</type>
<text>Copy in artist directories</text>
<action>EXEC /usr/bin/copyplaylist.pl --to /media/usbdisk/ --mkartist</action>
</button>
<button>
<type>MUSIC_COPY</type>
<text>Copy in artist/album directories</text>
<action>EXEC /usr/bin/copyplaylist.pl --to /media/usbdisk/ --mkartist --mkalbum </action>
</button>
<button>
<type>MUSIC_Delete</type>
<text>Clear SDcard</text>
<action>EXEC rm -rf /media/usbdisk/* ; aplay -q /home/mythtv/sounds/BONK2.wav </action>
</button>
</mythmenu>
edit the action sections to copy to the correct paths and if more than one needed add extra buttons.
3) copy sounds to use, and edit the copyplaylist.pl and cp2mp3_menu.xml to use these.
In copyplaylist.pl:
my $sound = '/home/mythtv/sounds/BONK2.wav';
In cp2mp3_menu.xml
<action>EXEC rm -rf /media/usbdisk/* ; aplay -q /home/mythtv/sounds/BONK2.wav </action>
Notes:
Works for R5E50 although should work with other version if the output path is mounted first.
options for Usage:
--name [playlist name to copy]
--to [path to copy playlist files to]
--test [test reads from database, but does not copy files or make directories]
--mkartist [puts songs in artist directories]
--mkalbum [puts songs in album directories (inside arist directories if --mkartist used]
If no --name given it will use the default playlist (currently selected)
Problem:
Need to restart the frontend after selecting the music, otherwise it copys the old playlist.
Anyone got any ideas on how to fix this?