Replies: 5 comments 6 replies
-
|
It really could be issue with any part of rmpcd since its still an early software. It would be nice to get some easier stepss to reproduce. |
Beta Was this translation helpful? Give feedback.
-
|
Sorry for the late response. Unfortunately I can't find a reliable way to test this, is there a debug flag? I just have rmpcd running with these two scripts ---@type PlaycountPlugin
local M = {
enabled = true,
subscribed_channels = { "rmpcd.playcount" },
STICKER_NAME = "playCount",
MIN_DURATION_MS = 30000,
}
-- Local state - sufficient for single-instance plugin architecture
local timer_handle = nil
local function increment(file)
local sticker, err = mpd.get_song_sticker(file, M.STICKER_NAME)
if err then
log.error("Sticker error: " .. tostring(err))
return
end
local count = tonumber(sticker) or 0
mpd.set_song_sticker(file, M.STICKER_NAME, tostring(count + 1))
log.info("Count incremented for " .. file .. " (Total: " .. (count + 1) .. ")")
end
M.setup = function(self, args)
self.enabled = (args and args.enabled ~= nil) and args.enabled or true
end
M.message = function(self, _channel, message)
if message == "enable" then
self.enabled = true
log.info("Playcount enabled")
elseif message == "disable" then
self.enabled = false
log.info("Playcount disabled")
elseif message == "toggle" then
self.enabled = not self.enabled
log.info("Playcount toggled: " .. tostring(self.enabled))
end
end
M.song_change = function(self, _old, new_song)
-- Cancel previous timer immediately
if timer_handle then
timer_handle:cancel()
timer_handle = nil
end
if not self.enabled or not new_song or not new_song.file then
return
end
local file = new_song.file
local duration = new_song.duration or 0
-- Immediate increment for short songs
if duration < M.MIN_DURATION_MS then
increment(file)
return
end
-- Delayed increment for long songs (Wait 50%)
local delay = math.floor(duration / 3)
log.info("Waiting " .. delay .. "ms for " .. file)
-- Set new timer - no file check needed, timer was cancelled if song changed
timer_handle = sync.set_timeout(delay, function()
increment(file)
timer_handle = nil
end)
end
M.teardown = function(self)
if timer_handle then
timer_handle:cancel()
timer_handle = nil
end
end
return M---@class SleepPlugin : RmpcdPlugin<{}>
---@field stop_on_song_change boolean
---@field timeout_handle TimeoutHandle | nil
---@type SleepPlugin
local M = {
stop_on_song_change = false,
}
M.subscribed_channels = { "rmpcd.sleep" }
-- Parse duration: "10"=10s, "10m"=10min, "1h"=1hour, "i10m"=immediate stop after 10min
-- Returns: (milliseconds, is_immediate)
local function parse_duration(input)
if not input then return nil, false end
input = string.gsub(input, "%s+", "")
local immediate = false
if input:sub(1, 1):lower() == "i" then
immediate = true
input = input:sub(2)
end
if input == "" then return immediate and 0 or nil, immediate end
local num, suffix = input:match("^([%d%.]+)([smhd]?)$")
if not num then return nil, immediate end
local value = tonumber(num)
if not value then return nil, immediate end
local mult = ({s=1, m=60, h=3600, d=86400})[suffix] or 1
return value * mult * 1000, immediate
end
-- Helper to format ms into "Xm", "Xh", "Xs"
local function format_duration(ms)
local s = ms / 1000
if s >= 3600 then
local h = math.floor(s / 3600)
local m = math.floor((s % 3600) / 60)
return string.format("%dh %dm", h, m)
elseif s >= 60 then
return string.format("%dm", math.floor(s / 60))
else
return string.format("%ds", math.floor(s))
end
end
M.message = function(self, _channel, message)
if message == "cancel" then
self.stop_on_song_change = false
if self.timeout_handle then
self.timeout_handle:cancel()
self.timeout_handle = nil -- Fixed: Clear the handle after cancellation
end
process.spawn({ "rmpc", "remote", "status", "Cancelled playback sleep" })
return
end
local delay_ms, immediate = parse_duration(message)
if not delay_ms then
process.spawn({ "rmpc", "remote", "status", "Invalid format. Try: 10, 10m, 1h, i10m" })
return
end
if self.timeout_handle then
self.timeout_handle:cancel()
self.timeout_handle = nil -- Fixed: Also clear here before setting a new one
end
local display = format_duration(delay_ms)
local mode_text = immediate and " (immediate stop)" or ""
self.timeout_handle = sync.set_timeout(delay_ms, function()
if immediate then
mpd.stop()
process.spawn({ "rmpc", "remote", "status", "Playback stopped" })
else
self.stop_on_song_change = true
process.spawn({ "rmpc", "remote", "status", "Will stop after song finishes" })
end
self.timeout_handle = nil
end)
-- Success message
process.spawn({ "rmpc", "remote", "status", string.format("Sleep timer set for %s%s", display, mode_text) })
end
M.song_change = function(self, _old, _new)
if self.stop_on_song_change then
self.stop_on_song_change = false
mpd.stop()
process.spawn({ "rmpc", "remote", "status", "Stopped (sleep timer)" })
end
end
return M
---@type Config
local config = {
-- Point rmpcd to your mpd server
address = "127.0.0.1:6600",
}
rmpcd.install("plugins.sleep"):setup({
enabled = true
})
rmpcd.install("plugins.playcount"):setup({
enabled = true
})
return config
After some time ranging from hours to days problems start when mpd was idle |
Beta Was this translation helpful? Give feedback.
-
|
I don't know what changed but I don't have anymore issues. update / script |
Beta Was this translation helpful? Give feedback.
-
|
Nevermind still happens but only if the playback is in "paused" state. When I stop and walk away for day its fine but when it's paused you need to restart rmpcd. In rmpc if the state was paused for a while and you then try to add a song to a playlist or rate it, itwill be stuck at the song where you paused the playback. Even if you are already 10 songs further into the queue |
Beta Was this translation helpful? Give feedback.
-
|
Take your time and take care! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
When rmpcd is started via systemd my plugins sometimes stop working without a restart and sometimes even rmpcd itself just stops entirely when left running / idle for a while.
Could this be an issue with my plugins?
Beta Was this translation helpful? Give feedback.
All reactions