diff options
author | Alasdair Campbell <alcoheca@gmail.com> | 2012-09-17 14:46:18 +0100 |
---|---|---|
committer | Alasdair Campbell <alcoheca@gmail.com> | 2012-10-09 10:55:44 +0100 |
commit | 5d2626f3186848f5d22e8702b231daf6208384da (patch) | |
tree | ed68fcf04655172ca5db95436980541d586156a6 | |
parent | 33ea3861daec0db858752637050332b351c92d07 (diff) |
[UPnP] fix: use Announcement manager to update metadata and volume statevariables
rather than every second in Application::ProcessSlow. Also handle play/pause
toggling.
-rw-r--r-- | xbmc/network/upnp/UPnPRenderer.cpp | 115 | ||||
-rw-r--r-- | xbmc/network/upnp/UPnPRenderer.h | 7 |
2 files changed, 84 insertions, 38 deletions
diff --git a/xbmc/network/upnp/UPnPRenderer.cpp b/xbmc/network/upnp/UPnPRenderer.cpp index f409357b52..f2605077c8 100644 --- a/xbmc/network/upnp/UPnPRenderer.cpp +++ b/xbmc/network/upnp/UPnPRenderer.cpp @@ -9,13 +9,35 @@ #include "guilib/GUIWindowManager.h" #include "pictures/GUIWindowSlideShow.h" #include "pictures/PictureInfoTag.h" +#include "interfaces/AnnouncementManager.h" #include "settings/Settings.h" #include "utils/URIUtils.h" +#include "utils/Variant.h" + +using namespace ANNOUNCEMENT; namespace UPNP { /*---------------------------------------------------------------------- +| CUPnPRenderer::CUPnPRenderer ++---------------------------------------------------------------------*/ +CUPnPRenderer::CUPnPRenderer(const char* friendly_name, bool show_ip /*= false*/, + const char* uuid /*= NULL*/, unsigned int port /*= 0*/) + : PLT_MediaRenderer(friendly_name, show_ip, uuid, port) +{ + CAnnouncementManager::AddAnnouncer(this); +} + +/*---------------------------------------------------------------------- +| CUPnPRenderer::~CUPnPRenderer ++---------------------------------------------------------------------*/ +CUPnPRenderer::~CUPnPRenderer() +{ + CAnnouncementManager::RemoveAnnouncer(this); +} + +/*---------------------------------------------------------------------- | CUPnPRenderer::SetupServices +---------------------------------------------------------------------*/ NPT_Result @@ -175,6 +197,58 @@ CUPnPRenderer::ProcessHttpRequest(NPT_HttpRequest& request, } /*---------------------------------------------------------------------- +| CUPnPRenderer::Announce ++---------------------------------------------------------------------*/ +void +CUPnPRenderer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) +{ + if (strcmp(sender, "xbmc") != 0) + return; + + NPT_AutoLock lock(m_state); + PLT_Service *avt, *rct; + + if (flag == Player) { + if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", avt))) + return; + if (strcmp(message, "OnPlay") == 0) { + avt->SetStateVariable("AVTransportURI", g_application.CurrentFile().c_str()); + avt->SetStateVariable("CurrentTrackURI", g_application.CurrentFile().c_str()); + + NPT_String meta; + if (NPT_SUCCEEDED(GetMetadata(meta))) { + avt->SetStateVariable("CurrentTrackMetadata", meta); + avt->SetStateVariable("AVTransportURIMetaData", meta); + } + + avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger())); + avt->SetStateVariable("TransportState", "PLAYING"); + } + else if (strcmp(message, "OnPause") == 0) { + avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger())); + avt->SetStateVariable("TransportState", "PAUSED_PLAYBACK"); + } + else if (strcmp(message, "OnSpeedChanged") == 0) { + avt->SetStateVariable("TransportPlaySpeed", NPT_String::FromInteger(data["speed"].asInteger())); + } + } + else if (flag == Application && strcmp(message, "OnVolumeChanged") == 0) { + if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:1", rct))) + return; + + CStdString buffer; + + buffer.Format("%ld", data["volume"].asInteger()); + rct->SetStateVariable("Volume", buffer.c_str()); + + buffer.Format("%ld", 256 * (data["volume"].asInteger() * 60 - 60) / 100); + rct->SetStateVariable("VolumeDb", buffer.c_str()); + + rct->SetStateVariable("Mute", data["muted"].asBoolean() ? "1" : "0"); + } +} + +/*---------------------------------------------------------------------- | CUPnPRenderer::UpdateState +---------------------------------------------------------------------*/ void @@ -182,11 +256,10 @@ CUPnPRenderer::UpdateState() { NPT_AutoLock lock(m_state); - PLT_Service *avt, *rct; + PLT_Service *avt; + if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", avt))) return; - if (NPT_FAILED(FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:1", rct))) - return; /* don't update state while transitioning */ NPT_String state; @@ -194,34 +267,13 @@ CUPnPRenderer::UpdateState() if(state == "TRANSITIONING") return; - CStdString buffer; - int volume; - if (g_settings.m_bMute) { - rct->SetStateVariable("Mute", "1"); - } else { - rct->SetStateVariable("Mute", "0"); - } - volume = g_application.GetVolume(); - - buffer.Format("%d", volume); - rct->SetStateVariable("Volume", buffer.c_str()); - - buffer.Format("%d", 256 * (volume * 60 - 60) / 100); - rct->SetStateVariable("VolumeDb", buffer.c_str()); + avt->SetStateVariable("TransportStatus", "OK"); if (g_application.IsPlaying() || g_application.IsPaused()) { - if (g_application.IsPaused()) { - avt->SetStateVariable("TransportState", "PAUSED_PLAYBACK"); - } else { - avt->SetStateVariable("TransportState", "PLAYING"); - } - - avt->SetStateVariable("TransportStatus", "OK"); - avt->SetStateVariable("TransportPlaySpeed", (const char*)NPT_String::FromInteger(g_application.GetPlaySpeed())); avt->SetStateVariable("NumberOfTracks", "1"); avt->SetStateVariable("CurrentTrack", "1"); - buffer = g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS); + CStdString buffer = g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS); avt->SetStateVariable("RelativeTimePosition", buffer.c_str()); avt->SetStateVariable("AbsoluteTimePosition", buffer.c_str()); @@ -234,17 +286,6 @@ CUPnPRenderer::UpdateState() avt->SetStateVariable("CurrentMediaDuration", "00:00:00"); } - avt->SetStateVariable("AVTransportURI", g_application.CurrentFile().c_str()); - avt->SetStateVariable("CurrentTrackURI", g_application.CurrentFile().c_str()); - - NPT_String metadata; - avt->GetStateVariableValue("AVTransportURIMetaData", metadata); - // try to recreate the didl dynamically if not set - if (metadata.IsEmpty()) { - GetMetadata(metadata); - } - avt->SetStateVariable("CurrentTrackMetadata", metadata); - avt->SetStateVariable("AVTransportURIMetaData", metadata); } else if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) { avt->SetStateVariable("TransportState", "PLAYING"); diff --git a/xbmc/network/upnp/UPnPRenderer.h b/xbmc/network/upnp/UPnPRenderer.h index 0a00ccbc17..b539399773 100644 --- a/xbmc/network/upnp/UPnPRenderer.h +++ b/xbmc/network/upnp/UPnPRenderer.h @@ -19,6 +19,7 @@ * */ #include "PltMediaRenderer.h" +#include "interfaces/IAnnouncer.h" namespace UPNP { @@ -30,13 +31,17 @@ public: }; class CUPnPRenderer : public PLT_MediaRenderer + , public ANNOUNCEMENT::IAnnouncer { public: CUPnPRenderer(const char* friendly_name, bool show_ip = false, const char* uuid = NULL, - unsigned int port = 0) : PLT_MediaRenderer(friendly_name, show_ip, uuid, port) {} + unsigned int port = 0); + virtual ~CUPnPRenderer(); + + virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); void UpdateState(); // Http server handler |