diff --git a/src/detection/media/media_windows.cpp b/src/detection/media/media_windows.cpp index 927549b24..aaf9da919 100644 --- a/src/detection/media/media_windows.cpp +++ b/src/detection/media/media_windows.cpp @@ -227,12 +227,64 @@ static const char* getMedia(FFMediaResult* result, bool saveCover) { break; } - abi_t* FF_AUTO_RELEASE_COM_OBJECT session = NULL; - hr = manager->GetCurrentSession(reinterpret_cast(&session)); + FF_A_CLEANUP(deleteHstring) HSTRING playerId = NULL; - if (FAILED(hr) || !session) { - error = "winrt: GetCurrentSession() failed"; - break; + abi_t* FF_AUTO_RELEASE_COM_OBJECT session = NULL; + if (instance.config.general.playerName.length) { + abi_t>* FF_AUTO_RELEASE_COM_OBJECT sessions = NULL; + hr = manager->GetSessions(reinterpret_cast(&sessions)); + if (FAILED(hr) || !sessions) { + error = "winrt: GetSessions() failed"; + break; + } + uint32_t sessionCount = 0; + hr = sessions->get_Size(&sessionCount); + if (FAILED(hr)) { + error = "winrt: GetSessions().get_Size() failed"; + break; + } + for (uint32_t i = 0; i < sessionCount; i++) { + abi_t* FF_AUTO_RELEASE_COM_OBJECT currentSession = NULL; + hr = sessions->GetAt(i, reinterpret_cast(¤tSession)); + if (FAILED(hr) || !currentSession) { + continue; + } + + hr = currentSession->get_SourceAppUserModelId(reinterpret_cast(&playerId)); + if (FAILED(hr) || !playerId) { + continue; + } + + ffStrbufSetHstring(&result->playerId, playerId); + + if (ffStrbufContainIgnCase(&result->playerId, &instance.config.general.playerName)) { + session = currentSession; + currentSession = NULL; // Don't release the session object + break; + } + deleteHstring(&playerId); + ffStrbufClear(&result->playerId); + } + + if (!session) { + error = "winrt: No media session found with the specified player name"; + break; + } + } else { + hr = manager->GetCurrentSession(reinterpret_cast(&session)); + + if (FAILED(hr) || !session) { + error = "winrt: GetCurrentSession() failed"; + break; + } + + hr = session->get_SourceAppUserModelId(reinterpret_cast(&playerId)); + if (FAILED(hr)) { + error = "winrt: get_SourceAppUserModelId() failed"; + break; + } + + ffStrbufSetHstring(&result->playerId, playerId); } abi_t* FF_AUTO_RELEASE_COM_OBJECT mediaProps = NULL; @@ -273,15 +325,6 @@ static const char* getMedia(FFMediaResult* result, bool saveCover) { } } - FF_A_CLEANUP(deleteHstring) HSTRING playerId = NULL; - hr = session->get_SourceAppUserModelId(reinterpret_cast(&playerId)); - if (FAILED(hr)) { - error = "winrt: get_SourceAppUserModelId() failed"; - break; - } - - ffStrbufSetHstring(&result->playerId, playerId); - FF_A_CLEANUP(deleteHstring) HSTRING title = NULL; if (SUCCEEDED(mediaProps->get_Title(reinterpret_cast(&title)))) { ffStrbufSetHstring(&result->song, title); diff --git a/src/options/general.c b/src/options/general.c index 8f4f7cf5f..1083a97cc 100644 --- a/src/options/general.c +++ b/src/options/general.c @@ -31,11 +31,11 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va } } else if (unsafe_yyjson_equals_str(key, "detectVersion")) { options->detectVersion = yyjson_get_bool(val); + } else if (unsafe_yyjson_equals_str(key, "playerName")) { + ffStrbufSetJsonVal(&options->playerName, val); } #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) - else if (unsafe_yyjson_equals_str(key, "playerName")) { - ffStrbufSetJsonVal(&options->playerName, val); - } else if (unsafe_yyjson_equals_str(key, "dsForceDrm")) { + else if (unsafe_yyjson_equals_str(key, "dsForceDrm")) { if (yyjson_is_str(val)) { int value; const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { @@ -74,11 +74,11 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key options->processingTimeout = ffOptionParseInt32(key, value); } else if (ffStrEqualsIgnCase(key, "--detect-version")) { options->detectVersion = ffOptionParseBoolean(value); + } else if (ffStrEqualsIgnCase(key, "--player-name")) { + ffOptionParseString(key, value, &options->playerName); } #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) - else if (ffStrEqualsIgnCase(key, "--player-name")) { - ffOptionParseString(key, value, &options->playerName); - } else if (ffStrEqualsIgnCase(key, "--ds-force-drm")) { + else if (ffStrEqualsIgnCase(key, "--ds-force-drm")) { if (ffOptionParseBoolean(value)) { options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_TRUE; } else if (ffStrEqualsIgnCase(value, "sysfs-only")) { @@ -104,19 +104,17 @@ void ffOptionsInitGeneral(FFOptionsGeneral* options) { options->processingTimeout = 5000; options->multithreading = true; options->detectVersion = true; + ffStrbufInit(&options->playerName); #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) - ffStrbufInit(&options->playerName); options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE; #elif defined(_WIN32) options->wmiTimeout = 5000; #endif } -void ffOptionsDestroyGeneral(FF_A_UNUSED FFOptionsGeneral* options) { -#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) +void ffOptionsDestroyGeneral(FFOptionsGeneral* options) { ffStrbufDestroy(&options->playerName); -#endif } void ffOptionsGenerateGeneralJsonConfig(FFdata* data, FFOptionsGeneral* options) { @@ -129,10 +127,10 @@ void ffOptionsGenerateGeneralJsonConfig(FFdata* data, FFOptionsGeneral* options) yyjson_mut_obj_add_bool(doc, obj, "detectVersion", options->detectVersion); -#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) - yyjson_mut_obj_add_strbuf(doc, obj, "playerName", &options->playerName); +#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) + switch (options->dsForceDrm) { case FF_DS_FORCE_DRM_TYPE_FALSE: yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", false); diff --git a/src/options/general.h b/src/options/general.h index a5d3f4630..080d70c04 100644 --- a/src/options/general.h +++ b/src/options/general.h @@ -12,10 +12,10 @@ typedef struct FFOptionsGeneral { bool multithreading; int32_t processingTimeout; bool detectVersion; + FFstrbuf playerName; // Module options that cannot be put in module option structure #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(__GNU__) - FFstrbuf playerName; FFDsForceDrmType dsForceDrm; #elif defined(_WIN32) int32_t wmiTimeout;