mpv icon indicating copy to clipboard operation
mpv copied to clipboard

--shuffle option doesn't work as expected when multiple dirs passed

Open adrianopol opened this issue 5 years ago • 5 comments

Environment

  • mpv:
$ mpv --version
mpv 0.32.0 Copyright © 2000-2020 mpv/MPlayer/mplayer2 projects
 built on UNKNOWN
ffmpeg library versions:
   libavutil       56.31.100
   libavcodec      58.54.100
   libavformat     58.29.100
   libswscale      5.5.100
   libavfilter     7.57.100
   libswresample   3.5.100
ffmpeg version: 4.2.3
  • OS: Gentoo Linux; mpv ebuild: https://gitweb.gentoo.org/repo/gentoo.git/tree/media-video/mpv/mpv-0.32.0-r1.ebuild
  • Window manager: XFCE (4.14-r2)

Reproduction steps

Run mpv --shuffle dir1 dir2 dir3.

Expected behavior

mpv takes all files from dir{1,2,3} recursively and shuffles them before playing.

Actual behavior

mpv takes random directory among dir{1,2,3}, shuffles files in it, and plays. Then takes another directory, and so on.

Log file

mpv.log.gz

adrianopol avatar Jul 15 '20 19:07 adrianopol

Looks similar to https://github.com/mpv-player/mpv/issues/3134 ? I'm not saying this should be closed as "won't fix" too. Just linking related things. P.S. also, if anyone have workaround solution (like user script, maybe?) I would very appreciate sharing it

UnkwUsr avatar May 21 '24 23:05 UnkwUsr

UPD: seems I found workaround: using find/fd utility to list all files, which makes single flat playlist.

fd -tf --exec-batch mpv

UnkwUsr avatar May 21 '24 23:05 UnkwUsr

mpv --shuffle dir1 --playlist=dir2 --playlist=dir3 is a workaround.

guidocella avatar May 22 '24 07:05 guidocella

mpv --shuffle dir1 --playlist=dir2 --playlist=dir3 is a workaround.

@guidocella what if dir2 have subdirs let's say dir4 and dir5, and moreover dir4 also have some subdirs... ?

UnkwUsr avatar May 22 '24 12:05 UnkwUsr

They get expanded.

guidocella avatar May 22 '24 14:05 guidocella

This is a piece of Lua script that might be of help to those of us who keep their playlists inside huge directory trees (bear with me, I'm just a novice Lua programmer):

-- A script that, on sub-playlist (a sub-directory with more than 1 entry) discovery,
-- shuffles just the sub-playlist entries into the collection of all the main-playlist
-- entries which comes after the current playlist entry then resumes playback.
-- Not as fast as the playlist-shuffle command but it never touches the already played
-- playlist entries. What is really needed is a playlist-shuffle-section command.

local shuffler_state = "enabled" -- toggled off when 'shuffler_state = "disabled"'
local shuffling_task_data = nil
local default_hook_priority = 50

math.randomseed(os.time())

mp.register_event("end-file", function(ev)
  if shuffler_state == "enabled"
    and ev.reason == "redirect" and ev.playlist_insert_num_entries > 1 then
    -- sub-playlist discovered
    -- 1. preparing a new sub-playlist shuffling task
    shuffling_task_data = {
      pl_cnt = mp.get_property_number("playlist/count"),
      pl_pos = mp.get_property_number("playlist-pos"),
      pl_ine = ev.playlist_insert_num_entries
    }
  end
end)

mp.add_hook("on_after_end_file", default_hook_priority, function(ho)
  if shuffler_state == "enabled" and shuffling_task_data then
    -- 2. executing the new sub-playlist shuffling task
    local swap_src_idx = shuffling_task_data["pl_pos"]
    local swap_dst_idx = math.random(swap_src_idx, shuffling_task_data["pl_cnt"] - 1)

    if swap_src_idx < swap_dst_idx then
      -- playback will continue with the shuffled playlist section's first entry
      mp.commandv("playlist-play-index", swap_dst_idx)

      -- doing the actual swapping here (!order is important!)
      mp.commandv("playlist-move", swap_src_idx, swap_dst_idx)
      mp.commandv("playlist-move", swap_dst_idx, swap_src_idx)
    end

    for i = 1, shuffling_task_data["pl_ine"] - 2 do
      swap_src_idx = shuffling_task_data["pl_pos"] + i
      swap_dst_idx = math.random(swap_src_idx, shuffling_task_data["pl_cnt"] - 1)

      if swap_dst_idx - swap_src_idx > 1 then
        -- doing the actual swapping here (!order is important!)
        mp.commandv("playlist-move", swap_src_idx, swap_dst_idx)
        mp.commandv("playlist-move", swap_dst_idx, swap_src_idx)
      end
    end

    shuffling_task_data = nil
  end
end)

gonubana avatar Nov 04 '24 14:11 gonubana