Page 1 of 1

Plugin to Play through playlist and then shuffle

Posted: 19 Mar 2017 11:23
by Jonno_FTW
Hi,

I'm trying to make a simple extension that works in the following manner:

1. User presses button and playlist is shuffled and begins playing
2. At the end of the last playlist item, the playlist is shuffled again
3. Playing loops to the start without stopping.

I'd like to loop instead of calling playlist.stop() and playlist.start() because stop brings you back to the playlist UI.

My code is here:

Code: Select all

function descriptor() return { title = "Shuffle Playlist", version = "1.1.1", shortdesc = "Shuffle Playlist", description = "Shuffles playlists once they are finished", author = "Jonathan Mackenzie", capabilities = {"playing-listener", "meta-listener", "input-listener"} } end function activate() vlc.playlist.loop('on') resetOn = nil shuf() vlc.playlist.play() return true end function deactivate() vlc.playlist.loop('off') vlc.playlist.stop() vlc.deactivate() return true end function close() vlc.deactivate() end function input_changed() -- related to capabilities={"input-listener"} in descriptor() -- triggered by Start/Stop media input event vlc.msg.dbg("[Shuffle] input changed currentId: " ..vlc.playlist.current()) end function meta_changed() -- related to capabilities={"meta-listener"} in descriptor() -- triggered by available media input meta data? vlc.msg.dbg("[Shuffle] meta changed currentId : " .. vlc.playlist.current()) if(vlc.playlist.current()==resetOn) then shuf() end end function playing_changed() vlc.msg.dbg("[Shuffle] playing changed currentId: "..vlc.playlist.current()) end function shuf() math.randomseed(os.time()) local pl = vlc.playlist.get("normal", false) local randomList = {} for i, v in ipairs(pl.children) do if v.duration == -1 then v.duration = 0 end randomList[#randomList + 1] = v end local swap for i = 1, #randomList do swap = math.random(#randomList) randomList[i], randomList[swap] = randomList[swap], randomList[i] end vlc.playlist.clear() vlc.playlist.enqueue(randomList) vlc.playlist.goto(randomList[1].id) resetOn = randomList[#randomList].id vlc.msg.dbg("[Shuffle] Playlist shuffled! Reset on id: ".. resetOn) return true end
But the problem is that it doesn't shuffle and start at the end of the playlist (VLC crashes). How can I tell when I get to the end of the last item? I understand meta_changed is called at the end of each item, but how do I actually detect that this is the case?

Re: Plugin to Play through playlist and then shuffle

Posted: 19 Mar 2017 13:30
by mederi
I have not checked/tested your script yet, perhaps later. I am not sure whether it is possible to find a reliable dynamic solution. Sampler (PG) introduces a static solution that works. It helps you to generate a shuffled playlist. You can enqueue many feeds to prepare long playlist (some kind of static loop). "Autofeed on last track" option is not reliable there (*remark in HELP).

Re: Plugin to Play through playlist and then shuffle

Posted: 20 Mar 2017 04:30
by Jonno_FTW
After getting some advice on IRC, I came up with the following (turns out you can tell if it's the end of an item by checking it's current time):

Code: Select all

function descriptor() return { title = "Shuffle Playlist", version = "1.1.3", shortdesc = "Shuffle Playlist", description = "Shuffles playlists once they are finished", author = "Jonathan Mackenzie", capabilities = {"input-listener", "playing-listener", "meta-listener"} } end function activate() vlc.playlist.loop('on') vlc.playlist.play() played = {vlc.playlist.current()} return true end function deactivate() vlc.playlist.loop('off') vlc.playlist.stop() vlc.deactivate() return true end function close() vlc.deactivate() end function meta_changed() -- related to capabilities={"meta-listener"} in descriptor() -- triggered by available media input meta data? local current = vlc.playlist.current() local input = vlc.object.input() local elapsed = vlc.var.get(input, "time") local total = vlc.var.get(input, "length") local diff = total - elapsed if diff <= 0 then local found = false for id,v in pairs(played) do if v == current then found = true end end if found then --if played[current] == true then played = {} vlc.playlist.sort("random") vlc.msg.dbg("[Shuffle] shuffling") else table.insert(played, current) local out = "" for id,v in pairs(played) do out = out ..v.. " " end vlc.msg.dbg("[Shuffle] Played: "..out) end end -- vlc.msg.dbg("[Shuffle] ".. elapsed.. "/".. total .. " diff= ".. tostring(total - elapsed)) end function input_changed() end function playing_changed() -- vlc.msg.dbg("[Shuffle] playing changed to "..vlc.playlist.current()) end