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 || "")
|
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) {
|
function labelFor(player) {
|
||||||
if (!player) return ""
|
if (!player) return ""
|
||||||
return player.trackTitle || player.identity || player.desktopEntry || ""
|
return player.trackTitle || player.identity || player.desktopEntry || ""
|
||||||
@@ -120,6 +134,8 @@ if (typeof module !== "undefined") {
|
|||||||
playerAppLabel: playerAppLabel,
|
playerAppLabel: playerAppLabel,
|
||||||
playerHasPlaybackStream: playerHasPlaybackStream,
|
playerHasPlaybackStream: playerHasPlaybackStream,
|
||||||
playerKey: playerKey,
|
playerKey: playerKey,
|
||||||
|
trackSignature: trackSignature,
|
||||||
|
trackChanged: trackChanged,
|
||||||
labelFor: labelFor,
|
labelFor: labelFor,
|
||||||
osdMessage: osdMessage
|
osdMessage: osdMessage
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Item {
|
|||||||
property var shell: null
|
property var shell: null
|
||||||
property string preferredPlayerKey: ""
|
property string preferredPlayerKey: ""
|
||||||
property var playerStartedAt: ({})
|
property var playerStartedAt: ({})
|
||||||
|
property var pendingTrackOsd: null
|
||||||
property int playSerial: 0
|
property int playSerial: 0
|
||||||
|
|
||||||
readonly property var players: Mpris.players ? Mpris.players.values : []
|
readonly property var players: Mpris.players ? Mpris.players.values : []
|
||||||
@@ -238,6 +239,10 @@ Item {
|
|||||||
return MediaModel.osdMessage(player, fallback)
|
return MediaModel.osdMessage(player, fallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function trackSignature(player) {
|
||||||
|
return MediaModel.trackSignature(player)
|
||||||
|
}
|
||||||
|
|
||||||
function showOsd(actionLabel, iconName, player) {
|
function showOsd(actionLabel, iconName, player) {
|
||||||
if (!shell) return
|
if (!shell) return
|
||||||
shell.summon("omarchy.osd", JSON.stringify({
|
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) {
|
function selectPlayer(key) {
|
||||||
var player = playerForKey(key)
|
var player = playerForKey(key)
|
||||||
if (!player || !hasMetadata(player)) return false
|
if (!player || !hasMetadata(player)) return false
|
||||||
@@ -334,6 +372,7 @@ Item {
|
|||||||
var key = playerKey(player)
|
var key = playerKey(player)
|
||||||
var actionLabel = "Play/pause"
|
var actionLabel = "Play/pause"
|
||||||
var iconName = "media"
|
var iconName = "media"
|
||||||
|
var beforeTrackSignature = trackSignature(player)
|
||||||
var handled = false
|
var handled = false
|
||||||
|
|
||||||
if (action === "next") {
|
if (action === "next") {
|
||||||
@@ -386,7 +425,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (handled && key) preferredPlayerKey = key
|
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
|
return handled
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,6 +438,13 @@ Item {
|
|||||||
onTriggered: root.syncPlayingOrder()
|
onTriggered: root.syncPlayingOrder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: trackOsdTimer
|
||||||
|
interval: 120
|
||||||
|
repeat: false
|
||||||
|
onTriggered: root.flushPendingTrackOsd(false)
|
||||||
|
}
|
||||||
|
|
||||||
PwObjectTracker { objects: root.playbackStreams }
|
PwObjectTracker { objects: root.playbackStreams }
|
||||||
|
|
||||||
function statusJson() {
|
function statusJson() {
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ assert(media.playerHasPlaybackStream(
|
|||||||
), 'media matches players to playback streams')
|
), 'media matches players to playback streams')
|
||||||
|
|
||||||
assertEqual(media.playerKey({ dbusName: 'org.mpris.MediaPlayer2.spotify' }), 'org.mpris.MediaPlayer2.spotify', 'media derives stable player keys')
|
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.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({ trackTitle: 'Song', trackArtist: 'Artist' }, 'Fallback'), 'Song - Artist', 'media builds OSD messages')
|
||||||
assertEqual(media.osdMessage(null, 'Fallback'), 'Fallback', 'media falls back OSD messages')
|
assertEqual(media.osdMessage(null, 'Fallback'), 'Fallback', 'media falls back OSD messages')
|
||||||
|
|||||||
Reference in New Issue
Block a user