LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 04-18-2013, 09:07 PM   #1
Dman58
Member
 
Registered: Nov 2010
Location: The Danger Zone
Distribution: Slackware & everything else in a VM
Posts: 294

Rep: Reputation: 31
How to randomly "cd" for cli mplayer music files


What's up LQ,

Dman here and I have a question. But 1st let me give a scenario.

I have been using Mplayer through Terminal to play my music files via cli in order to boost my cli knowledge. I generally "cd" to the path of whichever album I would like to play and type:

Example
Code:
mplayer -shuffle *.*m*
Which will play .mp3, .m4a, & wma

Problem is Me Really, I haven't got the insight in order to play the files as I would via a GUI application which tends to have tons of bells n whistles. For example randomly playing files that are generally in different locations.

Instead of copying specific files into a directory / playlist on the fly I would rather do 1 of 2 things. Either randomly "cd" to 1 of my many many music directories or recursively "cd" from: example - Artists main directory to a sub containing that same artists album.

I hope I stated that clearly.

Some might say just use the GUI but I think it can be accomplished via cli but with a little more effort. Plus I am just trying to gain more cli knowledge.

Is this the part where I start reading about for loops and while conditions or something or other?
 
Old 04-19-2013, 02:27 AM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,360

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Yep :

Actually, bookmark these for ref (if you haven't already)
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/

That being said you can start from these 2 that talk about RANDOM
http://stackoverflow.com/questions/2...-a-bash-script
http://tldp.org/LDP/abs/html/randomvar.html

Basically store the dirnames in an array, then generate a RANDOM num in that range and cd to the array element of that number.
 
Old 04-19-2013, 11:18 AM   #3
Dman58
Member
 
Registered: Nov 2010
Location: The Danger Zone
Distribution: Slackware & everything else in a VM
Posts: 294

Original Poster
Rep: Reputation: 31
Ok will do. Guess I have some homework for the weekend then.

Thanks chrism01!
 
Old 04-19-2013, 07:16 PM   #4
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Do you mean something like:
Code:
find -name \*.\*m\* -exec mplayer -shuffle {} +
 
Old 04-19-2013, 07:26 PM   #5
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
i found this on another members signature:
Code:
 
[schneidz@hyper ~]$ cat stuff/netcat.ksh
#!/bin/bash
PL=$(find /root/user/music -name "*.mp3")
NUM=$(echo $PL |wc -w)
{
while true; do
r=$(($RANDOM%$NUM))
s=$(echo $PL |cut -d ' ' -f$r)
echo "HTTP/1.0 200 OK\nContent-Type: audio/x-mp3stream\n\n"
dd if=$s bs=1024
done
} | nc -l -s address -p 8020
also look into the file command to find files of the type.
 
Old 04-19-2013, 07:35 PM   #6
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
I wouldn't use find for this, since even with the "-exec +" variant there is no guarantee that all found files will land in the mplayer command, if the number is large enough find will still split this into separate commands, so that you won'get real random playing.

I think this is a case for the shell functions, here pattern matching. I use Zsh, so I would use
Code:
mplayer -shuffle **/*.m*
to search for files that match the pattern *.m* in all sub-directories.
That should also work on Bash, but it may help to have a look at the Bash manuals.
 
Old 04-20-2013, 04:17 AM   #7
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,803

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by Dman58 View Post
Instead of copying specific files into a directory / playlist on the fly I would rather do 1 of 2 things. Either randomly "cd" to 1 of my many many music directories or recursively "cd" from: example - Artists main directory to a sub containing that same artists album.
Seems clear enough. Sounds like you have a similar directory structure to mine: artist -> album [-> disc number, if needed] -> track (named as: tracknumber-title). (It is the natural way to store music files for transfer to my Cowon D2.)

If you're using Banshee, I think you can configure it to recognize the underlying directory/file structure. Check the "File Organization" section of the "Edit->Preferences->Source Specific" menu.

What I've been doing since the days when I used Alsaplayer (still my favorite but it doesn't seem to work any more) is to flatten the directory structure by creating symbolic links to the actual music files. To do this I wrote a Perl script that walks the tree of music files and created a symbolic link for each track in a subdirectory ($HOME/music/playlist) and then have the music player use that subdirectory as its "library". I use the album name (or the disk number for multidisc sets), the track number and track name in the name of the symbolic link. (Note: I recently ran into a flaw in my scheme where two albums wound up having a song by the same title as the same track number on their respective albums and I added the album name to the link name. A real rare bug that I might have fix would be if there turned out to be identically named tracks on the Nth disc of two (or more but that would be insanely rare) multidisk sets. I'd probably just insert a random number in the link name if there's a name clash.)

Even if Banshee doesn't need to see that flattened tree, it seems to work just fine. I used it with Amarok as well with no problems.

HTH...

--
Rick
 
Old 04-21-2013, 03:51 PM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Quote:
Originally Posted by schneidz View Post
i found this on another members signature: ...
I see a couple of problems with that script. Starting here:

Code:
PL=$(find /root/user/music -name "*.mp3")
...
s=$(echo $PL |cut -d ' ' -f$r)
Bad, bad, bad. Any file with whitespace in it would be impossible to handle. It really needs to be converted into an array instead.

It also shouldn't need to rely on external commands like wc and cut.

Code:
 
#!/bin/bash

# to safely set the array:
while IFS='' read -rd '' fname; do
    pl_array+=( "$fname" )
done < <( find /root/user/music -name "*.mp3" -print0 )

# Or bash's globstar could probably be used instead.
# just ensure there are no recursive symlinks first.
# shopt -s globstar
# pl_array=( **/*.mp3 )

num=${#pl_array[@]}

{   while true; do
        r=$(( RANDOM % num ))

        echo "HTTP/1.0 200 OK\nContent-Type: audio/x-mp3stream\n\n"
        dd if=${pl_array[r]} bs=1024
    done
} | nc -l -s address -p 8020

exit 0
Notice also that this is a truly random player, not shuffled, and will repeat songs. Nor is there any way to break out of the loop. One idea around this would be to remove duplicates and have it exit when the file list is empty.

Code:
{   while [[ -n ${pl_array[@]} ]]; do
        num=${#pl_array[@]}
        r=$(( RANDOM % num ))

        echo "HTTP/1.0 200 OK\nContent-Type: audio/x-mp3stream\n\n"
        dd if=${pl_array[r]} bs=1024

        unset pl_array[r]
        pl_array=( ${pl_array[@]} )  #re-indexes the array for the next pass

    done
} | nc -l -s address -p 8020

Last edited by David the H.; 04-21-2013 at 03:58 PM. Reason: fixed tags
 
Old 04-25-2013, 04:27 AM   #9
Dman58
Member
 
Registered: Nov 2010
Location: The Danger Zone
Distribution: Slackware & everything else in a VM
Posts: 294

Original Poster
Rep: Reputation: 31
Thank you all for your help, I appreciate the feedback.

@TobiSGD
Your response is actually more of what I was looking for. Very simple and to the point.

Code:
mplayer -shuffle **/*.m*
I didn't realize that the double asterisk would include sub-directories. That along with -shuffle makes my selection random enough for my tastes.

To everyone else Thank You very much I will experiment with those other suggestions as well in the near future. Most importantly read up on shell scripting, regular expressions, and everything else I need to better my understanding.
 
Old 04-25-2013, 12:21 PM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
** is the new (from v.4) bash globstar advanced globbing pattern, which I believe was copied over from ksh. You may have to enable it first with "shopt -s globstar". When followed by "/" it expands into a list of all subdirectories, allowing for recursive matching of file globbing patterns.

There is one weakness with it, however. If the file tree contains any directory symlinks that point back to a parent node it will get caught in a perpetual loop and chew up your memory. So be judicial in how you use it.
 
Old 04-25-2013, 12:55 PM   #11
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
Quote:
Originally Posted by David the H. View Post
There is one weakness with it, however. If the file tree contains any directory symlinks that point back to a parent node it will get caught in a perpetual loop and chew up your memory. So be judicial in how you use it.
FWIW, this doesn't happen with Zsh.
 
Old 04-25-2013, 03:12 PM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
I'm sure it doesn't. Since it is new to bash, obviously not all the bugs have been worked out yet. It'll probably get fixed in time.
 
Old 04-25-2013, 04:53 PM   #13
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by TobiSGD View Post
I wouldn't use find for this, since even with the "-exec +" variant there is no guarantee that all found files will land in the mplayer command, if the number is large enough find will still split this into separate commands, so that you won'get real random playing.

I think this is a case for the shell functions, here pattern matching. I use Zsh, so I would use
Code:
mplayer -shuffle **/*.m*
to search for files that match the pattern *.m* in all sub-directories.
Are you sure this won't end up with the same problem? I'm reasonably sure that shell will refuse to run a command if the command line is too long (or if not shell, than kernel). Than again, Linux limits the number of arguments at 0x7FFFFFFF.
 
Old 04-25-2013, 06:54 PM   #14
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
If the number of files is large enough you will of course run into issues, but that would for me be the point to switch to a script to emulate shuffle without those limitations. The version with find you suggested does not circumvent those limitations, so using find in that way when the shell itself can do the job brings no advantages. FWIW, I just tried my solution on a directory with about 5300 MP3s and it worked without a problem. I am not sure how to test if find would already have splitted such a large number of files.
 
Old 04-27-2013, 01:28 AM   #15
Dman58
Member
 
Registered: Nov 2010
Location: The Danger Zone
Distribution: Slackware & everything else in a VM
Posts: 294

Original Poster
Rep: Reputation: 31
Well it works just fine for me and I'm using it with 1000's of music files spread across a ton of directories.

LQ is the best! Thanks again.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Organizing music files alphabetically but skipping the "The_" in artist names a21210 Linux - Newbie 12 11-19-2012 04:18 PM
Linux10.10 Where to down load "Demux " plugin for "Amorak" music bluesman1951 Linux - Newbie 10 10-28-2011 01:08 AM
"Error loading (music) files into library" Odyssey1942 Linux - Newbie 3 09-08-2006 07:02 AM
How can I put "Wave" music files on a AUDIO CD to play in my car? Balarabay1 SUSE / openSUSE 4 05-22-2006 10:19 PM
i just finished typing "./configure" and "make" in mplayer directory... kublador Linux - General 4 02-22-2003 03:12 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 09:15 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration