Fix media skip OSD metadata
This commit is contained in:
@@ -93,6 +93,20 @@ function playerKey(player) {
|
||||
return String(player.dbusName || player.desktopEntry || player.identity || "")
|
||||
}
|
||||
|
||||
function trackSignature(player) {
|
||||
if (!player) return ""
|
||||
return [
|
||||
player.trackTitle || "",
|
||||
player.trackArtist || "",
|
||||
player.trackAlbum || "",
|
||||
player.trackArtUrl || ""
|
||||
].join("\u001f")
|
||||
}
|
||||
|
||||
function trackChanged(previousSignature, player) {
|
||||
return trackSignature(player) !== String(previousSignature || "")
|
||||
}
|
||||
|
||||
function labelFor(player) {
|
||||
if (!player) return ""
|
||||
return player.trackTitle || player.identity || player.desktopEntry || ""
|
||||
@@ -120,6 +134,8 @@ if (typeof module !== "undefined") {
|
||||
playerAppLabel: playerAppLabel,
|
||||
playerHasPlaybackStream: playerHasPlaybackStream,
|
||||
playerKey: playerKey,
|
||||
trackSignature: trackSignature,
|
||||
trackChanged: trackChanged,
|
||||
labelFor: labelFor,
|
||||
osdMessage: osdMessage
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ Item {
|
||||
property var shell: null
|
||||
property string preferredPlayerKey: ""
|
||||
property var playerStartedAt: ({})
|
||||
property var pendingTrackOsd: null
|
||||
property int playSerial: 0
|
||||
|
||||
readonly property var players: Mpris.players ? Mpris.players.values : []
|
||||
@@ -238,6 +239,10 @@ Item {
|
||||
return MediaModel.osdMessage(player, fallback)
|
||||
}
|
||||
|
||||
function trackSignature(player) {
|
||||
return MediaModel.trackSignature(player)
|
||||
}
|
||||
|
||||
function showOsd(actionLabel, iconName, player) {
|
||||
if (!shell) return
|
||||
shell.summon("omarchy.osd", JSON.stringify({
|
||||
@@ -246,6 +251,39 @@ Item {
|
||||
}))
|
||||
}
|
||||
|
||||
function scheduleOsd(actionLabel, iconName, player, waitForTrackChange, beforeTrackSignature) {
|
||||
if (waitForTrackChange) {
|
||||
pendingTrackOsd = {
|
||||
actionLabel: actionLabel,
|
||||
iconName: iconName,
|
||||
player: player,
|
||||
playerKey: playerKey(player),
|
||||
before: beforeTrackSignature,
|
||||
attempts: 0
|
||||
}
|
||||
trackOsdTimer.restart()
|
||||
} else {
|
||||
Qt.callLater(function() { root.showOsd(actionLabel, iconName, player) })
|
||||
}
|
||||
}
|
||||
|
||||
function flushPendingTrackOsd(force) {
|
||||
var pending = pendingTrackOsd
|
||||
if (!pending) return
|
||||
|
||||
var player = playerForKey(pending.playerKey) || pending.player
|
||||
if (force || MediaModel.trackChanged(pending.before, player) || pending.attempts >= 10) {
|
||||
pendingTrackOsd = null
|
||||
trackOsdTimer.stop()
|
||||
root.showOsd(pending.actionLabel, pending.iconName, player)
|
||||
return
|
||||
}
|
||||
|
||||
pending.attempts = pending.attempts + 1
|
||||
pendingTrackOsd = pending
|
||||
trackOsdTimer.restart()
|
||||
}
|
||||
|
||||
function selectPlayer(key) {
|
||||
var player = playerForKey(key)
|
||||
if (!player || !hasMetadata(player)) return false
|
||||
@@ -334,6 +372,7 @@ Item {
|
||||
var key = playerKey(player)
|
||||
var actionLabel = "Play/pause"
|
||||
var iconName = "media"
|
||||
var beforeTrackSignature = trackSignature(player)
|
||||
var handled = false
|
||||
|
||||
if (action === "next") {
|
||||
@@ -386,7 +425,8 @@ Item {
|
||||
}
|
||||
|
||||
if (handled && key) preferredPlayerKey = key
|
||||
if (showFeedback !== false) Qt.callLater(function() { root.showOsd(actionLabel, iconName, player) })
|
||||
if (showFeedback !== false)
|
||||
scheduleOsd(actionLabel, iconName, player, handled && (action === "next" || action === "previous"), beforeTrackSignature)
|
||||
return handled
|
||||
}
|
||||
|
||||
@@ -398,6 +438,13 @@ Item {
|
||||
onTriggered: root.syncPlayingOrder()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: trackOsdTimer
|
||||
interval: 120
|
||||
repeat: false
|
||||
onTriggered: root.flushPendingTrackOsd(false)
|
||||
}
|
||||
|
||||
PwObjectTracker { objects: root.playbackStreams }
|
||||
|
||||
function statusJson() {
|
||||
|
||||
@@ -33,6 +33,10 @@ assert(media.playerHasPlaybackStream(
|
||||
), 'media matches players to playback streams')
|
||||
|
||||
assertEqual(media.playerKey({ dbusName: 'org.mpris.MediaPlayer2.spotify' }), 'org.mpris.MediaPlayer2.spotify', 'media derives stable player keys')
|
||||
const track = { trackTitle: 'Song', trackArtist: 'Artist', trackAlbum: 'Album', trackArtUrl: 'file:///cover.jpg' }
|
||||
const trackSignature = media.trackSignature(track)
|
||||
assert(!media.trackChanged(trackSignature, { ...track }), 'media detects unchanged track metadata')
|
||||
assert(media.trackChanged(trackSignature, { ...track, trackTitle: 'Next song' }), 'media detects changed track metadata')
|
||||
assertEqual(media.labelFor({ trackTitle: 'Song', identity: 'Spotify' }), 'Song', 'media labels players by track first')
|
||||
assertEqual(media.osdMessage({ trackTitle: 'Song', trackArtist: 'Artist' }, 'Fallback'), 'Song - Artist', 'media builds OSD messages')
|
||||
assertEqual(media.osdMessage(null, 'Fallback'), 'Fallback', 'media falls back OSD messages')
|
||||
|
||||
Reference in New Issue
Block a user