Skip to content

Reverse playlist order button #987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tomasklaen opened this issue Sep 11, 2024 Discussed in #986 · 3 comments
Open

Reverse playlist order button #987

tomasklaen opened this issue Sep 11, 2024 Discussed in #986 · 3 comments

Comments

@tomasklaen
Copy link
Owner

tomasklaen commented Sep 11, 2024

Discussed in #986

Originally posted by Dkzn September 11, 2024
I think this would be very useful for youtube playlists for example.


Once I implement menu buttons.

@MiKoto-Railgun
Copy link

So much time has passed, do you still have this plan?

@tomasklaen
Copy link
Owner Author

Yes, but I don't have much time to donate atm. Currently I mostly just fix bugs, and implement features that are either very easy to add (couple minutes of work), or something that I personally want or is bugging me. And this is something that I personally don't need, and will require bunch of work.

@Sneakpeakcss
Copy link
Contributor

Sneakpeakcss commented Mar 23, 2025

So much time has passed, do you still have this plan?

I tried making one when the button API was added, but i had an issue with proper state detection. The only reliable method i found was observing playlist, which is a bit questionable, especially for large playlists with thousands of entries.

reversePlaylist.lua
local utils = require "mp.utils"

function takePlaylistSnapshot()
    local playlist = mp.get_property_native("playlist")
    local playlist_id_total = 0
    for i = 1, #playlist do
        playlist_id_total = playlist_id_total + playlist[i].id
    end
    return playlist_id_total
end

function toggleButtonState(init)
    if not init then button_state = not button_state end
    mp.commandv("script-message-to", "uosc", "set-button", "reverse-playlist-button", utils.format_json({
        icon = "cached",
        active = button_state,
        tooltip = "Reverse Playlist",
        command = { "script-message-to", mp.get_script_name(), "reversePlaylist" },
    }))
    if not init and not button_state then
        previous_playlist_snapshot = nil
        current_snapshot = nil
        mp.unobserve_property(buttonState)
    end
end

function buttonState()
    if debounce then return end
    debounce = mp.add_timeout(0.1, function()
        if button_state then
            current_snapshot = takePlaylistSnapshot()
            if previous_playlist_snapshot == nil then
                previous_playlist_snapshot = current_snapshot
            elseif current_snapshot ~= previous_playlist_snapshot then
                toggleButtonState()
                previous_playlist_snapshot = current_snapshot
            end
        end
        debounce = nil
    end)
end

function reversePlaylist(keybind)
    local current_pos = mp.get_property_number("playlist-pos-1")
    local entries_num = mp.get_property_number("playlist-count")
    if entries_num == 0 and button_state then
        toggleButtonState()
        return
    elseif entries_num == 0 then
        mp.osd_message("Playlist is empty")
        return
    end
    -- Unobserve before reversing to avoid slowdown on big playlists
    mp.unobserve_property(buttonState)
    -- idle-active
    if current_pos == -1 and entries_num > 0 then
        current_pos = 1
    end
    for i = current_pos + 1, entries_num do
        mp.commandv("playlist-move", i - 1, current_pos - 1)
    end
    for i = current_pos - 1, 1, -1 do
        mp.commandv("playlist-move", i - 1, entries_num)
    end
    toggleButtonState()
    if button_state and not keybind then
        mp.observe_property("playlist", "none", buttonState)
    end
end

-- Init uosc button
toggleButtonState(true)
mp.register_script_message("reversePlaylist", reversePlaylist)

controls=button:reverse-playlist-button

It does work, but the observer also triggers on file change, which is not exactly preferable when you're manually jumping between files multiple times per second.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants