[MPlayer-dev-eng] [PATCH] Play previously played entries in shuffled playlist

Adam Buechler butchler at gmail.com
Sun Jul 15 20:43:54 CEST 2012


Allows you to play previously played entries again in a shuffled playlist
by stepping backward in the playtree. It does this by shuffling the
playtree as you step through it, choosing a random song and swapping it
with the next entry every time you're about to step onto an entry that
hasn't been played before.

It's kind of an ugly solution (can it even be called an iterator anymore if
it modifies the data structure as it iterates through it?), and I have a
feeling it might break anything that assumes that iterating through the
playtree won't change the playtree, so I understand if you don't want to
include the patch, but I've been using it for the past couple of weeks
without problems and it was a feature I missed a lot, so I just wanted to
share in case anyone else is interested.

The patch is really small, so here it is:

Index: playtree.c
===================================================================
--- playtree.c (revision 35025)
+++ playtree.c (working copy)
@@ -574,9 +574,7 @@
     iter->mode = PLAY_TREE_ITER_NORMAL;

   iter->file = -1;
-  if(iter->mode == PLAY_TREE_ITER_RND)
-    pt = play_tree_rnd_step(iter->tree);
-  else if( d > 0 ) {
+  if( d > 0 ) {
     int i;
     pt = iter->tree;
     for(i = d ; i > 0 && pt ; i--)
@@ -591,6 +589,28 @@
   } else
     pt = iter->tree;

+  if (iter->mode == PLAY_TREE_ITER_RND && (pt == NULL || !(pt->flags &
PLAY_TREE_RND_PLAYED))) {
+    // If the non-random stepping code above hit the end of the playtree or
+    // hit an entry that hasn't been played before, try to choose a random
entry.
+    pt = play_tree_rnd_step(iter->tree);
+
+    if (pt != NULL && pt != iter->tree) {
+      // Move the random entry to be immediately before or after the
current entry.
+      play_tree_remove(pt, 0, 0);
+
+      if (d > 0)
+        // Insert after
+        play_tree_insert_entry(iter->tree, pt);
+      else {
+        // Insert before
+        if (iter->tree->prev)
+          play_tree_insert_entry(iter->tree->prev, pt);
+        else
+          play_tree_prepend_entry(iter->tree, pt);
+      }
+    }
+  }
+
   if(pt == NULL) { // No next
     // Must we loop?
     if (iter->mode == PLAY_TREE_ITER_RND) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: shuffle-previous.diff
Type: application/octet-stream
Size: 1350 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20120715/ee5c22fd/attachment.obj>


More information about the MPlayer-dev-eng mailing list