Recursively scan directories for mp3s and pass them to mplayer

rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing
The command first deletes any old playlist calles playlist.tmp under /tmp. After that it recursively searches all direcotries under ~/mp3 and stores the result in /tmp/playlist.tmp. After havin created the playlist, the command will execute mplayer which will shuffle through the playlist. This command is aliased to m is aliased to `rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing' in my ~/.bashrc.
Sample Output
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.
Playing /home/hhanff/mp3/Alben/Sunrise Ave/On the way to wonderland/01-Choose to Be Me.mp3.

By: hhanff
2010-03-23 21:33:44

1 Alternatives + Submit Alt

What Others Think

By the way: Can anybody figure out how to do the same thing without creating a temporary playlist? I tried to pass the results of find to mplayer via xargs, but then the keyboard controls of mplayer won't function any more....
hhanff · 604 weeks and 4 days ago
What about 'find ~/mp3 -iname *.mp3 -exec mplayer -shuffle -loop {} \;' ? I am not at a *nix machine right now, so I can't test it, but something like this would not require a playlist.
philthomson · 604 weeks and 4 days ago
The '-iname' option on find will help if you have mp3's where the extension is .MP3 as opposed to .mp3
philthomson · 604 weeks and 4 days ago
My suggestion doesn't work, but I did google the problem with mplayer and found this: '' The suggested workaround only works for files with no spaces in them, but I'm sure there is some way to do it for all kinds of file names.
philthomson · 604 weeks and 4 days ago
"find blablabla | mplayer -playlist -" will build a playlist from stdin. Also, you should write "\*.mp3" instead of simply "*.mp3", otherwise your shell will expand * before it gets to find, and find will get a list of *-mp3's in cwd
benjamin · 604 weeks and 4 days ago
@philtomson: I found the same page yesterday but had not idea how to make it work... @ benjamin: find ~/mp3 -name "*.mp3" | mplayer -playlist - -shuffle -loop 0 does not allow to control mplayer with keyboard any more.... e.g. "next song" by hitting return... :/ Here's a better version which filters out all "audio books": rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 -not -name 'H?rb?cher' > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing
hhanff · 604 weeks and 4 days ago
Okay, this works: for i in "$(find . -type d)";do d=( $i/*.mp3 ); files=( "${files[@]}" "${d[@]}" );done; mplayer -shuffle -loop 0 "${files[@]}" ugly as hell though :D
benjamin · 604 weeks and 3 days ago
Sin!!! That's a big one...
hhanff · 604 weeks and 3 days ago
old topic, but i use this for the new car system (2014) so i can select the tracks i want to listen to in the new car from a vast list. ( 8G card and system requires play lists.) I know its not brilliant but does a job and may be a starting point for others. #!D:\Perl64\bin\perl.exe use strict; use warnings; #use File::Spec::Functions qw'no_upwards'; my $PLHeader="\n\n \n \n \n\n \n \n \n \n \n \n Others\n \n \n \n"; my $PLData=" my $PLTail=" \n \n"; my $PLID=""; my $InitDir; my $FileAll; my $FileRoot; my %OpenFile; if ($ARGV[0] eq ""){ $InitDir="M:"; }else{ $InitDir=$ARGV[0]; } FileAll="$InitDir\\_all.wpl"; open(PLALL, "> $FileAll") or die "Unable to open _all.wpl"; print PLALL $PLHeader; #$FileRoot="$InitDir\\"; #open(PLROOT, "> $FileRoot") or die "Unable to open"; #print PLROOT $PLHeader; sub Read_Dir { my $entry; my $dir = $_[0]; my $prevpath = $_[1]; my $DirLevel = $_[2]; my $DirPL; my $PLOpen="N"; my $PLName; my @Files; my @Dirs; my $wDir; print "\$dir=$dir, \$prevpath=$prevpath, \$DirLevel=$DirLevel\n"; if ( $prevpath eq "" ) { $wDir=$InitDir }else{ $wDir="$InitDir/$dir"; } opendir(DIRID, $wDir) || die "can't opendir $wDir $!"; print "\$InitDir=$InitDir, \$dir=$dir, \$wDir=$wDir\n"; @Files = grep { ( /\.mp3$/ || /\.m4a$/ || /\.wma$/ || /\.aac$/ || /\.aif$/ || /\.flac$/ ) && -f "$wDir/$_" } readdir DIRID; rewinddir( DIRID ); @Dirs = grep { !/^\./ && -d "$wDir/$_" } readdir DIRID; close DIRID; # print "Files ---------------->\n"; # print join(",\n",@Files); # print "Dirs ---------------->\n"; # print join(",\n",@Dirs); #exit 0; print "Process Files array for $wDir\n"; foreach $entry (@Files) { print "working on File - $entry\n"; # print "$PLOpen ,$dir, $InitDir \n"; #next if -l "$dir/$entry"; # symbolic link if ($PLOpen eq "N" ){ print "open playlist /n"; if ($dir eq $InitDir) { $PLName="_root.wpl"; # print "PLName = $PLName\n"; }else{ $PLName="$dir.wpl"; } open(PLDIR, "> $InitDir/$PLName") or die "Can not open $PLName\n"; print "Openned $InitDir/$PLName \n"; $PLOpen = "Y"; print PLDIR $PLHeader; } # # sort $PLNAME - not correct path to file. # if ( $dir eq $InitDir ) { print PLALL $PLData."/$entry\"/>\n"; print PLDIR $PLData."/$entry\"/>\n"; }else{ print PLALL $PLData."/$dir/$entry\"/>\n"; print PLDIR $PLData."/$dir/$entry\"/>\n"; # print "F - $entry \n"; } } print PLDIR $PLTail; close PLDIR; print "\n\nend of files------------------- print "$dir dir array count = $#Dirs\n"; $DirLevel++; foreach $entry (@Dirs) { next if $entry eq "." or $entry eq ".."; # system entries next if "$entry" eq "System Volume Information"; next if "$entry" eq "IndexerVolumeGuid"; print "D - $dir/$entry \n"; print "calling Read_Dir(\$entry,\$dir,\$DirLevel) - Read_Dir($entry,$dir,$DirLevel)\n"; Read_Dir($entry,$dir,$DirLevel); # recurse } } Read_Dir($InitDir,"",0); # our top-level directory print PLALL $PLTail; #print PLROOT $PLTail; close PLALL; #close PLROOT; exit 0;
gittingr · 361 weeks ago

What do you think?

Any thoughts on this command? Does it work on your machine? Can you do the same thing with only 14 characters?

You must be signed in to comment.

What's this? is the place to record those command-line gems that you return to again and again. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

Share Your Commands

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.


Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for: