Register
It is currently Fri Oct 31, 2014 9:01 am

Random


All times are UTC - 6 hours


Post new topic Reply to topic  [ 7 posts ] 
Author Message
 PostPosted: Sun Aug 02, 2009 11:07 am   

Joined: Sat May 30, 2009 5:56 am
Posts: 15
I have a script I made to play random media files I have stored in various locations. In determining which file to play, first I do an ls of all the directories and append the outputs to file.txt. Then, in order to select a random line from the file (which = one media file), I'm using this bit of code I found somewhere online:
Code:
LowerBound=1
RandomMax=32761
UpperBound=$(cat $file.txt | wc -l)
RandomLine=$(( $LowerBound + ($UpperBound * $RANDOM) / ($RandomMax + 1) ))
filetoplay=$(sed -n "$RandomLine{p;q;}" "$file.txt")

The randomness of this setup is pretty questionable. Out of over 500 media files, I seem to be stuck with the same 30 or 40 over and over. Even when I play in batches using a while/do loop and counting cycles to a predetermined number, I can end up with duplicate plays of media files. I believe it's because the $RANDOM variable works between 0-32761, and that math up there isn't enough to sufficiently scale it down to a few hundred.

Some more searching has led me to the fact that $RANDOM can be limited, by using $RANDOM%NN, where NN is a limiting number of your choice. Since it runs from zero to (NN-1), you have to add one to the equation such that (( [ $RANDOM%NN ] +1 )). I'd like to do away completely with much of the previous setup, and cut that process down a lot by, for example, renaming the "UpperBound" variable "max" and using it to limit the $RANDOM output as shown above. The problem is that I keep getting errors or strange outputs when I try to insert a variable into that setup. For example, (( [ $RANDOM%$MAX ] +1 )) just gives a syntax error. Using it like (( [ $RANDOM%${MAX} ] +1 )) gives a count from 0 to 2, with each digit followed by the actual value for the $max variable.

Can someone point me in a direction (either this one or something totally new) that will allow me to limit the output of the $RANDOM variable with the use of a second variable?


Top
 Profile  
 PostPosted: Mon Aug 03, 2009 1:04 am   
User avatar

Joined: Sat Jun 13, 2009 8:53 pm
Posts: 73
Location: Texas!
$RANDOM uses the process id as part of the seed, so if you are running the whole script repeatedly, the results may not be too random. The $Rand I use here is a bit better as far as absolute randomness goes. I'm not sure why your modular arithmetic failed, but the code given here produces the expected range.

Code:
Rand=`dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" "`
LowerBound=1
UpperBound=`cat file.txt | wc -l`
let "Range = $UpperBound - $LowerBound + 1"
let "RandomLine = $LowerBound + ($Rand % $Range)"
filetoplay=`sed -n "$RandomLine{p;q;}" "file.txt"`


If you want to generate an entire playlist randomly with no repeated songs, that's a bit more work. You would need to check to see that a song is not already in the playlist before you add it. I hope this helps. Let us know if you want to expand it or would like more explanation.


Top
 Profile  
 PostPosted: Mon Aug 03, 2009 11:00 am   

Joined: Sat May 30, 2009 5:56 am
Posts: 15
Thanks for the reply. I'm going to work that into my script right away. It may take some time to determine if it functions any better, but just looking at it, it seems as though it would. When I first found that bit of code online (I don't remember where, but credit is due to the original author), I had doubts as to whether it would perform well, and was surprised when it did. After the first few runs, I noticed I was already starting to see the same files popping up. That's the thing about random events, though.. even if it was the exact same one a few times in a row, how do you really know it's not random?

I have another post on here about making VLC play a random series of files.. That's the script I'm using this in. The first part of the script searches for the list in a particular location (the top level folder of the categorized media files I'm playing) and if it's not there, it creates it. You mentioned randomness without repeats.. I was going to work on another sed line (I think sed would be the way to go, though I could be wrong) that will, after the line has been chosen to feed to VLC, it would cut the line out of the list. That, of course, would change the number of items in the list, but should be reflected where "cat file.txt | wc -l" changes the upper boundary every time the script is run.


Image


Top
 Profile  
 PostPosted: Thu Aug 06, 2009 1:26 am   
User avatar

Joined: Sat Jun 13, 2009 8:53 pm
Posts: 73
Location: Texas!
Yes, credit for the random number generator should be given to James T. Dennis, found here: http://linuxgazette.net/issue55/tag/4.html.
Your plan for using sed to cut out the line sounds good -- nice solution!

Another relevant comic:
Image


Top
 Profile  
 PostPosted: Fri Aug 07, 2009 5:12 pm   

Joined: Sat May 30, 2009 5:56 am
Posts: 15
I've been using it in all my variations of the script pretty regularly for a few days now, and I can say I'm quite pleased with how it works compared to my older version. I notice that the higher the upperboundary is (i.e., the more files in a particular category) the less chance there is for repeats. For example, with 20 seasons of The Simpsons with 441 separate episodes, I've yet to notice a single repeat out of running it probably 8 or 9 times. But, with only six seasons of Sanford & Son at around 100 or so episodes, I've had the same episode get played twice in a row.

Thanks for the help. I'll come back and post up the whole script when I get the final sed line worked out that will eliminate repeats all together.


Last edited by uncertain on Sat Aug 22, 2009 4:49 pm, edited 1 time in total.

Top
 Profile  
 PostPosted: Thu Aug 13, 2009 10:44 pm   
User avatar

Joined: Sat Jun 13, 2009 8:53 pm
Posts: 73
Location: Texas!
Quote:
But, with only six seasons of Sanford & Son at around 100 or so episodes ...

That's way too much Sanford & Son, hah.
Quote:
Thanks for the help. I'll come back and post up the whole script when I get the final sed line worked out that will eliminate repeats all together.

You're quite welcome for the help. Please do post the final script -- you never know who might be interested in it.


Top
 Profile  
 PostPosted: Wed Aug 19, 2009 11:09 am   

Joined: Sat May 30, 2009 5:56 am
Posts: 15
The randomness you provided seems to work a lot better than my old version.

Here is the final product:
Code:
#!/bin/bash
#
# Creates a list of all video files in all selected folders and then
# plays so many random episodes with VLC Media Player.
# Created by Uncertain

# Filenames and paths.
path1=/path/to/folder/one
path2=/path/to/folder/two                  #If needed. Add more paths as necessary.
list=/location/of/list/episodes.txt
# Check for the list. If it exists, fine.
# If it doesn't exist, create it.
if [ -f $list ]
then
  echo "List found at $list"
   else
    echo "Episodes list not found. Creating list arranged by season & episode..." &&find $path1 -name '*.avi' -o -name '*.mpg' -o -name '*.mp4' -o -type f -size +20M | sort >> $list && echo "Done. List created at: $list"                             #Copy that command and add more path variables as they're used.
fi
# Set the number of episodes to play.
repeat=2
cycles=0
while  [ $cycles -ne $repeat ]
do
  echo $cycles
  cycles=$(( $cycles + 1 ))
# Read the list, select one random line.
Rand=`dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" "`
LowerBound=1
UpperBound=`cat $list | wc -l`
let "Range = $UpperBound - $LowerBound + 1"
let "RandomLine = $LowerBound + ($Rand % $Range)"
episode=`sed -n "$RandomLine{p;q;}" $list`
# open the random episode in VLC, play it fullscreen, and exit.
vlc -vvv --fullscreen "$episode" vlc://quit
# Close the episode count loop...
  done
# ...and then...
exit


That's the skeleton version. It should just be a matter of setting your actual path(s) to the $path variable(s) as needed, deciding where to store the list, and let it rip...

When I was first writing it, I was running it in the terminal often to debug it, hence the periodic echoes of what's going on. These could easily be removed with no ill effects (I think I got all but a couple of them).


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: popeye and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP