Repulser / Moosic

Host your own 24/7 Discord Music Bot!
135 stars 48 forks source link

Track Repeating #24

Open MoonFartFlam opened 6 years ago

MoonFartFlam commented 6 years ago

Is it possible to make the user's list of tracks play at least 75% of the total number of songs before repeating any already played in that loop? Sometimes, the same song comes on 3 times within a 10 song streak in a list of 50+ songs.

Ex. Such that if a user has 100 songs in their songs.txt file, the bot will play 75 (or 100 if it's easier) unique songs from that playlist before considering playing a repeat song.

pwhodges commented 6 years ago

This is rather typical of stock random functions, unfortunately. I've seen it in many programs (such as the Apache rewrite functionality for outputting a random file from a list).

pulverize commented 6 years ago

It's 100% possible to set this up. We can't blame this behavior on the way Math.Random works. I started work on it but am not a Java developer by profession so had some bumps in the road. My approach would be to represent the playlist as a wrapper of two underlying playlists, from which you would randomly move (and return) songs from one into the other until the first is empty.

pwhodges commented 6 years ago

I had in mind something similar - moving the playlist to a new copy randomly to shuffle it, then playing through the list in order, repeating the shuffle before playing it again.

pwhodges commented 6 years ago

I did it similarly to your idea. I added "AutoDone" which is declared identically to "AutoPlay", and then replaced "getRandomSong" with:

    private String getRandomSong() {
        synchronized (RANDOM) {
            if (AutoPlay.isEmpty()) {
                System.out.println("Copying songs back into queue for next cycle");
                for (String nextTrack : AutoDone) {
                    AutoPlay.add(nextTrack);
                }
                AutoDone.clear();
            }
            int trackPicked = RANDOM.nextInt(AutoPlay.size());
            String pickedTrack = AutoPlay.get(trackPicked);
            AutoDone.add(pickedTrack);
            AutoPlay.remove(trackPicked);
            return pickedTrack; 
        }
    }

This is running fine for me with 500 tracks in the list.