I have script with repeat to play random youtube audio with a list of url links.
The problem is that the random get too much same value urls when play next song so that I have to hear that song repeatly.
So Anyone have any idea to solve that problem. Thanks
For example:
I have list with 10 songs: audio_1ā¦audio_10
Iāll random it in the list and get the audio_3. At the next song, the audio_3 will be remove from the list and random the others one. And continue repeat to the last ones.
I encountered a similar challenge with changing the color of pool lights. Thereās a set of 8 colors from which one would be randomly selected. However, it didnāt āfeelā random because sometimes the same color would be selected twice in a row.
The solution is to initially randomize the order of the set of colors, namely to āshuffle the deckā, and then display the colors in sequence.
Thereās no shuffle filter in Jinja2 so the randomization (shuffling) has to be be done manually. With some help from pnbruckner, I managed to implement the Fisher-Yates shuffling algorithm as a template.
I helped someone else implement it for randomizing the order of a room-mopping scripts:
Let me know if it interests you and I can help you use it for randomizing the order of the media_players songs.
For example, copy-paste this into the Template Editor and experiment with it. Replace the listās contents with whatever items you require (like songs).
{% set players = [ "media_player.video_url_1", "media_player.video_url_2",
"media_player.video_url_3"] %}
{% set ns = namespace(x = players) %}
{% for i in range(ns.x | length - 1, 0, -1) %}
{% set j = range(0, i + 1) | random %}
{% if j != i %}
{% set ns.x = ns.x[:j]+[ns.x[i]]+ns.x[j+1:i]+[ns.x[j]]+ns.x[i+1:] %}
{% endif %}
{% endfor %}
{{ ns.x }}
That would work to eliminate the same song from playing twice in a row. What it wouldnāt do is eliminate the possibility of hearing it repeated within the set.
What if we have an array with all possible songs.
When play is started this array is copied to an input_text, then when a song needs to be picked the input text is read and one is picked from the array/text and removed.
When the input_text is empty it copies the complete list again?
FWIW, the concept of shuffling a set of songs and then playing the shuffled set in sequence is basically the function available in most media-playing apps. Emulating it with a template is challenging because thereās no shuffle filter. However, thatās what that for-loop does in the example posted above. Given a list, it produces a shuffled list. All thatās left is to simple iterate through the shuffled list; no song is repeated until the end of the list.
If you want to know more, check the posted link for the Fisher-Yates algorithm. It explains its operation and shows examples in several different programming languages. I used the python example as the basis for creating a Jinja2 template. As mentioned, I needed help with the list construction because list handling is rather limited in Home Assistantās implementation of Jinja2. To get a sense of that, compare the python version to the Jinja2 version.
If the shuffle function has satisfied your requirements, please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topicās title which signals to other users that this topic is resolved. This helps other users find answers to similar questions. For more information, refer to guideline 21 in the FAQ.
I came here to mention the Fisher-Yates algorithm too. I implemented it years ago on a project as a way to make (computationally easy and cheap) recommendations to users of an app. Anyway, it works and is a good suggestion. I also wanted to say that humans have a hard time believing true randomness. I can unfortunately not find a good reference for this now, but I remember from my research back then that Apple did implement Fisher-Yates on the iPod to shuffle music, but users didnāt like it. Here is a close article written about the effect: https://www.ripleys.com/weird-news/is-shuffle-random/. Iām mentioning this, because you might implement this and find it not satisfactory.
Do you have any other sources because thereās not really a lot of substance in that one.
The first part seems likes it was due to end-userās misunderstanding of the playerās shuffle function (it doesnāt keep re-shuffling the order, only when you request it). The second part doesnāt explain what Spotify did to satisfy customer expectations of randomness.
EDIT
Nevermind, I followed the rabbit hole to here:
some people donāt want the same artist playing two or three times within a short time period
Thatās solved by involving more keys than merely one (song title). I fell thatās not a failing of the shuffling algorithm but how it was used.
Thanks so much for reply,
thatās a great idea. Itās solve out my problem perfectly.
Your topic you share help me alot in making my own script. Thank you so much
Now that I understand the logic, I guess you can do a little optimization.
The range from which J is generated should not go to i+1 but i-1 because:
You are not interested in changing values that are higher than i (These have been handled)
and you are not interested in having i=i
and this way you donāt need the if close.
The result for the loop becomes:
{% for i in range(ns.x | length - 1, 1, -1) %}
{% set j = range(0, i - 1) | random %}
{% set ns.x = ns.x[:j]+ [ns.x[i]]+ns.x[j+1:i]+[ns.x[j]]+ns.x[i+1:] %}
{% endfor %}