mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-12-21 07:22:21 +00:00
Check all active players for "Playing" Status
This commit is contained in:
parent
8baa6d2a20
commit
3a22976fec
1 changed files with 10 additions and 71 deletions
|
|
@ -1,10 +1,10 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <list>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <ranges>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <os/media.h>
|
#include <os/media.h>
|
||||||
#include <os/logger.h>
|
#include <os/logger.h>
|
||||||
|
|
@ -22,13 +22,10 @@ static const char* DBusPath = "/org/freedesktop/DBus";
|
||||||
static const char* MPRIS2Interface = "org.mpris.MediaPlayer2";
|
static const char* MPRIS2Interface = "org.mpris.MediaPlayer2";
|
||||||
static const char* MPRIS2PlayerInterface = "org.mpris.MediaPlayer2.Player";
|
static const char* MPRIS2PlayerInterface = "org.mpris.MediaPlayer2.Player";
|
||||||
static const char* MPRIS2Path = "/org/mpris/MediaPlayer2";
|
static const char* MPRIS2Path = "/org/mpris/MediaPlayer2";
|
||||||
static const char* MPRIS2PlayerctldBus = "org.mpris.MediaPlayer2.playerctld";
|
|
||||||
|
|
||||||
static std::optional<std::thread> g_dbusThread;
|
static std::optional<std::thread> g_dbusThread;
|
||||||
static std::string g_playerctldBus;
|
|
||||||
static std::unordered_map<std::string, PlaybackStatus> g_playerStatus;
|
static std::unordered_map<std::string, PlaybackStatus> g_playerStatus;
|
||||||
static std::list<std::string> g_activePlayers;
|
static std::atomic<bool> g_isPlaying = false;
|
||||||
static std::atomic<PlaybackStatus> g_activeStatus;
|
|
||||||
|
|
||||||
static PlaybackStatus PlaybackStatusFromString(const char* str)
|
static PlaybackStatus PlaybackStatusFromString(const char* str)
|
||||||
{
|
{
|
||||||
|
|
@ -40,42 +37,16 @@ static PlaybackStatus PlaybackStatusFromString(const char* str)
|
||||||
return PlaybackStatus::Stopped;
|
return PlaybackStatus::Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ContainerHas(const auto& container, const auto& value)
|
|
||||||
{
|
|
||||||
return std::find(container.begin(), container.end(), value) != container.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateActiveStatus()
|
static void UpdateActiveStatus()
|
||||||
{
|
{
|
||||||
if (!g_activePlayers.empty())
|
g_isPlaying = std::ranges::any_of(
|
||||||
g_activeStatus = g_playerStatus[g_activePlayers.front()];
|
g_playerStatus | std::views::values,
|
||||||
else
|
[](PlaybackStatus status) { return status == PlaybackStatus::Playing; }
|
||||||
g_activeStatus = PlaybackStatus::Stopped;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateActivePlayers(const char* name, PlaybackStatus status)
|
static void UpdateActivePlayers(const char* name, PlaybackStatus status)
|
||||||
{
|
{
|
||||||
if (status == PlaybackStatus::Stopped)
|
|
||||||
{
|
|
||||||
// Don't remove playerctld from the queue, we want to prefer it for as long as it's available
|
|
||||||
if (!g_str_equal(name, g_playerctldBus.c_str()))
|
|
||||||
{
|
|
||||||
g_activePlayers.remove(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!ContainerHas(g_activePlayers, name))
|
|
||||||
{
|
|
||||||
// Prioritise playerctld if and when it appears
|
|
||||||
if (g_str_equal(name, g_playerctldBus.c_str()))
|
|
||||||
{
|
|
||||||
g_activePlayers.emplace_front(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_activePlayers.emplace_back(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_playerStatus.insert_or_assign(name, status);
|
g_playerStatus.insert_or_assign(name, status);
|
||||||
UpdateActiveStatus();
|
UpdateActiveStatus();
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +108,7 @@ static void DBusConnectionClosed(GDBusConnection* connection,
|
||||||
gpointer userData)
|
gpointer userData)
|
||||||
{
|
{
|
||||||
LOG_ERROR("D-Bus connection closed");
|
LOG_ERROR("D-Bus connection closed");
|
||||||
g_activeStatus = PlaybackStatus::Stopped;
|
g_isPlaying = false;
|
||||||
g_main_loop_quit((GMainLoop*)userData);
|
g_main_loop_quit((GMainLoop*)userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,15 +128,9 @@ static void DBusNameOwnerChanged(GDBusConnection* connection,
|
||||||
|
|
||||||
if (g_str_has_prefix(name, MPRIS2Interface))
|
if (g_str_has_prefix(name, MPRIS2Interface))
|
||||||
{
|
{
|
||||||
if (g_str_equal(name, MPRIS2PlayerctldBus))
|
|
||||||
{
|
|
||||||
g_playerctldBus = newOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldOwner[0])
|
if (oldOwner[0])
|
||||||
{
|
{
|
||||||
g_playerStatus.erase(oldOwner);
|
g_playerStatus.erase(oldOwner);
|
||||||
g_activePlayers.remove(oldOwner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateActiveStatus();
|
UpdateActiveStatus();
|
||||||
|
|
@ -206,11 +171,9 @@ static void MPRISPropertiesChanged(GDBusConnection* connection,
|
||||||
g_variant_unref(changed);
|
g_variant_unref(changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called upon connect to discover already active MPRIS2 players by looking for
|
/* Called upon CONNECT to discover already active MPRIS2 players by looking for
|
||||||
well-known bus names that begin with the MPRIS2 path.
|
well-known bus names that begin with the MPRIS2 path.
|
||||||
We determine what their priority would be when pushed to the player queue
|
g_playerStatus stores unique connection names,
|
||||||
based on their current status.
|
|
||||||
The queue (and accompanying data structures) stores unique connection names,
|
|
||||||
not their well-known ones, as the PropertiesChanged signal only provides the
|
not their well-known ones, as the PropertiesChanged signal only provides the
|
||||||
former. */
|
former. */
|
||||||
static void DBusListNamesReceived(GObject* object, GAsyncResult* res, gpointer userData)
|
static void DBusListNamesReceived(GObject* object, GAsyncResult* res, gpointer userData)
|
||||||
|
|
@ -221,13 +184,10 @@ static void DBusListNamesReceived(GObject* object, GAsyncResult* res, gpointer u
|
||||||
GVariant* tupleChild;
|
GVariant* tupleChild;
|
||||||
GVariantIter iter;
|
GVariantIter iter;
|
||||||
const gchar* name;
|
const gchar* name;
|
||||||
bool foundPlayerctld;
|
|
||||||
std::list<std::string> pausedPlayers;
|
|
||||||
|
|
||||||
connection = G_DBUS_CONNECTION(object);
|
connection = G_DBUS_CONNECTION(object);
|
||||||
error = NULL;
|
error = NULL;
|
||||||
response = g_dbus_connection_call_finish(connection, res, &error);
|
response = g_dbus_connection_call_finish(connection, res, &error);
|
||||||
foundPlayerctld = false;
|
|
||||||
|
|
||||||
if (!response)
|
if (!response)
|
||||||
{
|
{
|
||||||
|
|
@ -274,31 +234,10 @@ static void DBusListNamesReceived(GObject* object, GAsyncResult* res, gpointer u
|
||||||
g_variant_get(ownerResponse, "(&s)", &ownerName);
|
g_variant_get(ownerResponse, "(&s)", &ownerName);
|
||||||
status = MPRISGetPlaybackStatus(connection, ownerName);
|
status = MPRISGetPlaybackStatus(connection, ownerName);
|
||||||
|
|
||||||
// Prioritise playerctld, even if current playback status is stopped
|
|
||||||
if (!foundPlayerctld && g_str_equal(name, MPRIS2PlayerctldBus))
|
|
||||||
{
|
|
||||||
foundPlayerctld = true;
|
|
||||||
g_playerctldBus = ownerName;
|
|
||||||
g_activePlayers.emplace_front(ownerName);
|
|
||||||
}
|
|
||||||
else if (status != PlaybackStatus::Stopped)
|
|
||||||
{
|
|
||||||
if (status == PlaybackStatus::Playing)
|
|
||||||
{
|
|
||||||
g_activePlayers.emplace_back(ownerName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pausedPlayers.emplace_back(ownerName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_playerStatus.insert_or_assign(ownerName, status);
|
g_playerStatus.insert_or_assign(ownerName, status);
|
||||||
g_variant_unref(ownerResponse);
|
g_variant_unref(ownerResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put all the paused players at the end of the queue
|
|
||||||
g_activePlayers.splice(g_activePlayers.end(), pausedPlayers);
|
|
||||||
UpdateActiveStatus();
|
UpdateActiveStatus();
|
||||||
|
|
||||||
g_variant_unref(tupleChild);
|
g_variant_unref(tupleChild);
|
||||||
|
|
@ -385,5 +324,5 @@ bool os::media::IsExternalMediaPlaying()
|
||||||
g_dbusThread->detach();
|
g_dbusThread->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_activeStatus == PlaybackStatus::Playing;
|
return g_isPlaying;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue