summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Config.cpp419
-rw-r--r--Config.h208
-rw-r--r--ControlServer.cpp42
-rw-r--r--ControlServer.h33
-rw-r--r--Directory.cpp359
-rw-r--r--Directory.h107
-rw-r--r--Media.cpp103
-rw-r--r--Media.h78
-rw-r--r--MediaContainer.cpp151
-rw-r--r--MediaContainer.h99
-rw-r--r--PVideo.cpp715
-rw-r--r--PVideo.h154
-rw-r--r--PlexHTTPRequestHandler.cpp569
-rw-r--r--PlexHTTPRequestHandler.h67
-rw-r--r--PlexHelper.cpp31
-rw-r--r--PlexHelper.h17
-rw-r--r--PlexReqHandlerFactory.cpp27
-rw-r--r--PlexReqHandlerFactory.h23
-rw-r--r--PlexServer.cpp263
-rw-r--r--PlexServer.h178
-rw-r--r--Plexservice.cpp597
-rw-r--r--Plexservice.h70
-rw-r--r--Stream.cpp52
-rw-r--r--Stream.h45
-rw-r--r--SubscriptionManager.cpp545
-rw-r--r--SubscriptionManager.h196
-rw-r--r--XmlObject.cpp318
-rw-r--r--XmlObject.h66
-rw-r--r--browserGrid.cpp762
-rw-r--r--browserGrid.h139
-rw-r--r--cPlexOsdItem.cpp54
-rw-r--r--cPlexOsdItem.h64
-rw-r--r--detailView.cpp317
-rw-r--r--detailView.h60
-rw-r--r--device.cpp109
-rw-r--r--device.h75
-rw-r--r--displayReplaySD.cpp43
-rw-r--r--displayReplaySD.h46
-rw-r--r--hlsPlayer.cpp1393
-rw-r--r--hlsPlayer.h226
-rw-r--r--hlsPlayerControl.cpp640
-rw-r--r--hlsPlayerControl.h91
-rw-r--r--m3u8Parser.cpp189
-rw-r--r--m3u8Parser.h43
-rw-r--r--pictureCache.cpp260
-rw-r--r--pictureCache.h81
-rw-r--r--playlist.cpp8
-rw-r--r--playlist.h12
-rw-r--r--plex.cpp398
-rw-r--r--plex.h67
-rw-r--r--plexOsd.cpp398
-rw-r--r--plexOsd.h60
-rw-r--r--plexSdOsd.cpp748
-rw-r--r--plexSdOsd.h73
-rw-r--r--plexgdm.cpp468
-rw-r--r--plexgdm.h120
-rw-r--r--services.h17
-rw-r--r--tokendefinitions.h262
-rw-r--r--user.cpp42
-rw-r--r--user.h18
-rw-r--r--viewGridNavigator.cpp460
-rw-r--r--viewGridNavigator.h135
-rw-r--r--viewHeader.cpp79
-rw-r--r--viewHeader.h32
64 files changed, 6790 insertions, 6731 deletions
diff --git a/Config.cpp b/Config.cpp
index c8eb1aa..0a4ab5f 100644
--- a/Config.cpp
+++ b/Config.cpp
@@ -1,127 +1,130 @@
#include "Config.h"
-const char* Config::viewModeNames[]
-{
- "Cover",
- "List",
- "Detail"
-};
+const char *Config::viewModeNames[]
+ {
+ "Cover",
+ "List",
+ "Detail"
+ };
Config::Config() {
- s_username = "username";
- s_password = "password";
- CoverGridColumns = 7;
- CoverGridRows = 2;
- ListGridColumns = 1;
- ListGridRows = 12;
- DetailGridColumns = 1;
- DetailGridRows = 4;
- ExtrasGridColumns = 4;
- ExtrasGridRows = 1;
-
- UseMpv = false;
- UseAc3 = true;
- ScrollByPage = true;
- ScrollAllAround = true;
- BufferSize = 1;
-
- DefaultViewMode = ViewMode::Cover;
-
- ViewEntry en;
- en.Name = "Recently Added";
- en.PlexPath = "/library/recentlyAdded";
- m_viewentries.push_back(en);
-
- ViewEntry en2;
- en2.Name = "On Deck";
- en2.PlexPath = "/library/onDeck";
- m_viewentries.push_back(en2);
-
- ViewEntry en3;
- en3.Name = "Library";
- en3.PlexPath = "/library/sections";
- m_serverViewentries.push_back(en3);
-
- ViewEntry en4;
- en4.Name = "Video Channels";
- en4.PlexPath = "/video";
- m_serverViewentries.push_back(en4);
-
+ s_username = "username";
+ s_password = "password";
+ CoverGridColumns = 7;
+ CoverGridRows = 2;
+ ListGridColumns = 1;
+ ListGridRows = 12;
+ DetailGridColumns = 1;
+ DetailGridRows = 4;
+ ExtrasGridColumns = 4;
+ ExtrasGridRows = 1;
+
+ UseMpv = false;
+ UseAc3 = true;
+ ScrollByPage = true;
+ ScrollAllAround = true;
+ BufferSize = 1;
+
+ DefaultViewMode = ViewMode::Cover;
+
+ ViewEntry en;
+ en.Name = "Recently Added";
+ en.PlexPath = "/library/recentlyAdded";
+ m_viewentries.push_back(en);
+
+ ViewEntry en2;
+ en2.Name = "On Deck";
+ en2.PlexPath = "/library/onDeck";
+ m_viewentries.push_back(en2);
+
+ ViewEntry en3;
+ en3.Name = "Library";
+ en3.PlexPath = "/library/sections";
+ m_serverViewentries.push_back(en3);
+
+ ViewEntry en4;
+ en4.Name = "Video Channels";
+ en4.PlexPath = "/video";
+ m_serverViewentries.push_back(en4);
+
}
std::string Config::GetUUID() {
- if(s_uuid.empty()) {
- using Poco::UUIDGenerator;
- using Poco::UUID;
- UUIDGenerator &generator = UUIDGenerator::defaultGenerator();
- UUID uuid(generator.createRandom());
- s_uuid = uuid.toString();
- }
- return s_uuid;
+ if (s_uuid.empty()) {
+ using Poco::UUIDGenerator;
+ using Poco::UUID;
+ UUIDGenerator &generator = UUIDGenerator::defaultGenerator();
+ UUID uuid(generator.createRandom());
+ s_uuid = uuid.toString();
+ }
+ return s_uuid;
}
-void Config::SetUUID(const char* uuid) {
- if (uuid) s_uuid = std::string(uuid);
+void Config::SetUUID(const char *uuid) {
+ if (uuid) s_uuid = std::string(uuid);
}
std::string Config::GetHostname() {
- if(s_hostname.empty()) {
- char hostname[1024];
- gethostname(hostname, 1024);
- s_hostname = std::string(hostname);
- }
- return s_hostname;
+ if (s_hostname.empty()) {
+ char hostname[1024];
+ gethostname(hostname, 1024);
+ s_hostname = std::string(hostname);
+ }
+ return s_hostname;
}
std::string Config::GetLanguage() {
- return "de";
+ return "de";
}
std::string Config::GetUsername() {
- return s_username;
+ return s_username;
}
std::string Config::GetPassword() {
- return s_password;
+ return s_password;
}
-bool Config::Parse(const char *name, const char *value)
-{
- //dsyslog("[plex]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
- bool parsed = true;
- if (strcasecmp(name, "HideMainMenuEntry") == 0) Config::GetInstance().HideMainMenuEntry = atoi(value) ? true : false;
- else if (strcasecmp(name, "UsePlexAccount") == 0) Config::GetInstance().UsePlexAccount = atoi(value) ? true : false;
- else if (strcasecmp(name, "UseCustomTranscodeProfile") == 0) Config::GetInstance().UseCustomTranscodeProfile = atoi(value) ? true : false;
- else if (strcasecmp(name, "Username") == 0) Config::GetInstance().s_username = std::string(value);
- else if (strcasecmp(name, "Password") == 0) Config::GetInstance().s_password = std::string(value);
- else if (strcasecmp(name, "UUID") == 0) Config::GetInstance().SetUUID(value);
- else if (strcasecmp(name, "UseConfiguredServer") == 0) Config::GetInstance().UseConfiguredServer = atoi(value) ? true : false;
- else if (strcasecmp(name, "ServerHost") == 0) Config::GetInstance().s_serverHost = std::string(value);
- else if (strcasecmp(name, "ServerPort") == 0) Config::GetInstance().ServerPort = atoi(value);
- else if (strcasecmp(name, "CoverGridColumns") == 0) Config::GetInstance().CoverGridColumns = atoi(value);
- else if (strcasecmp(name, "CoverGridRows") == 0) Config::GetInstance().CoverGridRows = atoi(value);
- else if (strcasecmp(name, "DetailGridColumns") == 0) Config::GetInstance().DetailGridColumns = atoi(value);
- else if (strcasecmp(name, "DetailGridRows") == 0) Config::GetInstance().DetailGridRows = atoi(value);
- else if (strcasecmp(name, "ListGridColumns") == 0) Config::GetInstance().ListGridColumns = atoi(value);
- else if (strcasecmp(name, "ListGridRows") == 0) Config::GetInstance().ListGridRows = atoi(value);
- else if (strcasecmp(name, "ExtrasGridColumns") == 0) Config::GetInstance().ExtrasGridColumns = atoi(value);
- else if (strcasecmp(name, "ExtrasGridRows") == 0) Config::GetInstance().ExtrasGridRows = atoi(value);
- else if (strcasecmp(name, "UseMpv") == 0) Config::GetInstance().UseMpv = atoi(value) ? true : false;
- else if (strcasecmp(name, "ScrollByPage") == 0) Config::GetInstance().ScrollByPage = atoi(value) ? true : false;
- else if (strcasecmp(name, "ScrollAllAround") == 0) Config::GetInstance().ScrollAllAround = atoi(value) ? true : false;
- else if (strcasecmp(name, "UseAc3") == 0) Config::GetInstance().UseAc3 = atoi(value) ? true : false;
- else if (strcasecmp(name, "BufferSize") == 0) Config::GetInstance().BufferSize = atoi(value);
- else parsed = false;
-
- if(!parsed) {
- // Parse ViewEntries
-
- }
-
- return parsed;
+bool Config::Parse(const char *name, const char *value) {
+ //dsyslog("[plex]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
+ bool parsed = true;
+ if (strcasecmp(name, "HideMainMenuEntry") == 0)
+ Config::GetInstance().HideMainMenuEntry = atoi(value) ? true : false;
+ else if (strcasecmp(name, "UsePlexAccount") == 0) Config::GetInstance().UsePlexAccount = atoi(value) ? true : false;
+ else if (strcasecmp(name, "UseCustomTranscodeProfile") == 0)
+ Config::GetInstance().UseCustomTranscodeProfile = atoi(value) ? true : false;
+ else if (strcasecmp(name, "Username") == 0) Config::GetInstance().s_username = std::string(value);
+ else if (strcasecmp(name, "Password") == 0) Config::GetInstance().s_password = std::string(value);
+ else if (strcasecmp(name, "UUID") == 0) Config::GetInstance().SetUUID(value);
+ else if (strcasecmp(name, "UseConfiguredServer") == 0)
+ Config::GetInstance().UseConfiguredServer = atoi(value) ? true : false;
+ else if (strcasecmp(name, "ServerHost") == 0) Config::GetInstance().s_serverHost = std::string(value);
+ else if (strcasecmp(name, "ServerPort") == 0) Config::GetInstance().ServerPort = atoi(value);
+ else if (strcasecmp(name, "CoverGridColumns") == 0) Config::GetInstance().CoverGridColumns = atoi(value);
+ else if (strcasecmp(name, "CoverGridRows") == 0) Config::GetInstance().CoverGridRows = atoi(value);
+ else if (strcasecmp(name, "DetailGridColumns") == 0) Config::GetInstance().DetailGridColumns = atoi(value);
+ else if (strcasecmp(name, "DetailGridRows") == 0) Config::GetInstance().DetailGridRows = atoi(value);
+ else if (strcasecmp(name, "ListGridColumns") == 0) Config::GetInstance().ListGridColumns = atoi(value);
+ else if (strcasecmp(name, "ListGridRows") == 0) Config::GetInstance().ListGridRows = atoi(value);
+ else if (strcasecmp(name, "ExtrasGridColumns") == 0) Config::GetInstance().ExtrasGridColumns = atoi(value);
+ else if (strcasecmp(name, "ExtrasGridRows") == 0) Config::GetInstance().ExtrasGridRows = atoi(value);
+ else if (strcasecmp(name, "UseMpv") == 0) Config::GetInstance().UseMpv = atoi(value) ? true : false;
+ else if (strcasecmp(name, "ScrollByPage") == 0) Config::GetInstance().ScrollByPage = atoi(value) ? true : false;
+ else if (strcasecmp(name, "ScrollAllAround") == 0)
+ Config::GetInstance().ScrollAllAround = atoi(value) ? true : false;
+ else if (strcasecmp(name, "UseAc3") == 0) Config::GetInstance().UseAc3 = atoi(value) ? true : false;
+ else if (strcasecmp(name, "BufferSize") == 0) Config::GetInstance().BufferSize = atoi(value);
+ else parsed = false;
+
+ if (!parsed) {
+ // Parse ViewEntries
+
+ }
+
+ return parsed;
}
@@ -132,9 +135,8 @@ bool Config::Parse(const char *name, const char *value)
/**
** Process key for setup menu.
*/
-eOSState cMyMenuSetupPage::ProcessKey(eKeys key)
-{
- return cMenuSetupPage::ProcessKey(key);
+eOSState cMyMenuSetupPage::ProcessKey(eKeys key) {
+ return cMenuSetupPage::ProcessKey(key);
}
/**
@@ -142,117 +144,116 @@ eOSState cMyMenuSetupPage::ProcessKey(eKeys key)
**
** Import global config variables into setup.
*/
-cMyMenuSetupPage::cMyMenuSetupPage(void)
-{
- strn0cpy(Username, Config::GetInstance().s_username.c_str(), STRING_SIZE);
- strn0cpy(Password, Config::GetInstance().s_password.c_str(), STRING_SIZE);
- strn0cpy(Uuid, Config::GetInstance().GetUUID().c_str(), STRING_SIZE);
- strn0cpy(ServerHost, Config::GetInstance().s_serverHost.c_str(), STRING_SIZE);
- ServerPort = Config::GetInstance().ServerPort;
- UseConfiguredServer = Config::GetInstance().UseConfiguredServer;
- HideMainMenuEntry = Config::GetInstance().HideMainMenuEntry;
- UseCustomTranscodeProfile = Config::GetInstance().UseCustomTranscodeProfile;
- UsePlexAccount = Config::GetInstance().UsePlexAccount;
- CoverGridColumns = Config::GetInstance().CoverGridColumns;
- CoverGridRows = Config::GetInstance().CoverGridRows;
- DetailGridColumns = Config::GetInstance().DetailGridColumns;
- DetailGridRows = Config::GetInstance().DetailGridRows;
- ListGridColumns = Config::GetInstance().ListGridColumns;
- ListGridRows = Config::GetInstance().ListGridRows;
- ExtrasGridColumns = Config::GetInstance().ExtrasGridColumns;
- ExtrasGridRows = Config::GetInstance().ExtrasGridRows;
- UseMpv = Config::GetInstance().UseMpv;
- ScrollByPage = Config::GetInstance().ScrollByPage;
- ScrollAllAround = Config::GetInstance().ScrollAllAround;
- DefaultViewMode = Config::GetInstance().DefaultViewMode;
- UseAc3 = Config::GetInstance().UseAc3;
- BufferSize = Config::GetInstance().BufferSize;
-
-
- Add(new cMenuEditBoolItem(tr("Hide main menu entry"), (int*)&HideMainMenuEntry, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Use AC3 instead of aac Audio"), (int*)&UseAc3, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Use Mpv Plugin (If Availiable)"), (int*)&UseMpv, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditIntItem(tr("Buffer size for playing, in MB"), &BufferSize, 1, 128));
-
- Add(new cMenuEditBoolItem(tr("Scroll by Page"), (int*)&ScrollByPage, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Scroll all around"), (int*)&ScrollAllAround, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Use custom transcoding profile"), (int*)&UseCustomTranscodeProfile, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Use Plex account"), (int*)&UsePlexAccount, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditStrItem(tr("Plex Username"), Username, STRING_SIZE));
- Add(new cMenuEditStrItem(tr("Plex Password"), Password, STRING_SIZE));
-
- Add(new cMenuEditBoolItem(tr("Use Custom Server"), (int*)&UseConfiguredServer, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditStrItem(tr("Server Host"), ServerHost, STRING_SIZE));
- Add(new cMenuEditIntItem(tr("Server Port"), &ServerPort));
-
- Add(new cMenuEditStraItem(tr("Default View Mode"), &DefaultViewMode, 3, Config::viewModeNames));
-
- Add(new cMenuEditIntItem(tr("Cover Grid Columns"), &CoverGridColumns));
- Add(new cMenuEditIntItem(tr("Cover Grid Rows"), &CoverGridRows));
-
- Add(new cMenuEditIntItem(tr("Detail Grid Columns"), &DetailGridColumns));
- Add(new cMenuEditIntItem(tr("Detail Grid Rows"), &DetailGridRows));
-
- Add(new cMenuEditIntItem(tr("List Grid Columns"), &ListGridColumns));
- Add(new cMenuEditIntItem(tr("List Grid Rows"), &ListGridRows));
-
- Add(new cMenuEditIntItem(tr("Extras Grid Columns"), &ExtrasGridColumns));
- Add(new cMenuEditIntItem(tr("Extras Grid Rows"), &ExtrasGridRows));
-
- cMenuEditStrItem* devUUID = new cMenuEditStrItem(tr("Current UUID"), Uuid, STRING_SIZE);
- devUUID->SetSelectable(false);
- Add(devUUID);
+cMyMenuSetupPage::cMyMenuSetupPage(void) {
+ strn0cpy(Username, Config::GetInstance().s_username.c_str(), STRING_SIZE);
+ strn0cpy(Password, Config::GetInstance().s_password.c_str(), STRING_SIZE);
+ strn0cpy(Uuid, Config::GetInstance().GetUUID().c_str(), STRING_SIZE);
+ strn0cpy(ServerHost, Config::GetInstance().s_serverHost.c_str(), STRING_SIZE);
+ ServerPort = Config::GetInstance().ServerPort;
+ UseConfiguredServer = Config::GetInstance().UseConfiguredServer;
+ HideMainMenuEntry = Config::GetInstance().HideMainMenuEntry;
+ UseCustomTranscodeProfile = Config::GetInstance().UseCustomTranscodeProfile;
+ UsePlexAccount = Config::GetInstance().UsePlexAccount;
+ CoverGridColumns = Config::GetInstance().CoverGridColumns;
+ CoverGridRows = Config::GetInstance().CoverGridRows;
+ DetailGridColumns = Config::GetInstance().DetailGridColumns;
+ DetailGridRows = Config::GetInstance().DetailGridRows;
+ ListGridColumns = Config::GetInstance().ListGridColumns;
+ ListGridRows = Config::GetInstance().ListGridRows;
+ ExtrasGridColumns = Config::GetInstance().ExtrasGridColumns;
+ ExtrasGridRows = Config::GetInstance().ExtrasGridRows;
+ UseMpv = Config::GetInstance().UseMpv;
+ ScrollByPage = Config::GetInstance().ScrollByPage;
+ ScrollAllAround = Config::GetInstance().ScrollAllAround;
+ DefaultViewMode = Config::GetInstance().DefaultViewMode;
+ UseAc3 = Config::GetInstance().UseAc3;
+ BufferSize = Config::GetInstance().BufferSize;
+
+
+ Add(new cMenuEditBoolItem(tr("Hide main menu entry"), (int *) &HideMainMenuEntry, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditBoolItem(tr("Use AC3 instead of aac Audio"), (int *) &UseAc3, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditBoolItem(tr("Use Mpv Plugin (If Availiable)"), (int *) &UseMpv, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditIntItem(tr("Buffer size for playing, in MB"), &BufferSize, 1, 128));
+
+ Add(new cMenuEditBoolItem(tr("Scroll by Page"), (int *) &ScrollByPage, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditBoolItem(tr("Scroll all around"), (int *) &ScrollAllAround, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditBoolItem(tr("Use custom transcoding profile"), (int *) &UseCustomTranscodeProfile, trVDR("no"),
+ trVDR("yes")));
+ Add(new cMenuEditBoolItem(tr("Use Plex account"), (int *) &UsePlexAccount, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditStrItem(tr("Plex Username"), Username, STRING_SIZE));
+ Add(new cMenuEditStrItem(tr("Plex Password"), Password, STRING_SIZE));
+
+ Add(new cMenuEditBoolItem(tr("Use Custom Server"), (int *) &UseConfiguredServer, trVDR("no"), trVDR("yes")));
+ Add(new cMenuEditStrItem(tr("Server Host"), ServerHost, STRING_SIZE));
+ Add(new cMenuEditIntItem(tr("Server Port"), &ServerPort));
+
+ Add(new cMenuEditStraItem(tr("Default View Mode"), &DefaultViewMode, 3, Config::viewModeNames));
+
+ Add(new cMenuEditIntItem(tr("Cover Grid Columns"), &CoverGridColumns));
+ Add(new cMenuEditIntItem(tr("Cover Grid Rows"), &CoverGridRows));
+
+ Add(new cMenuEditIntItem(tr("Detail Grid Columns"), &DetailGridColumns));
+ Add(new cMenuEditIntItem(tr("Detail Grid Rows"), &DetailGridRows));
+
+ Add(new cMenuEditIntItem(tr("List Grid Columns"), &ListGridColumns));
+ Add(new cMenuEditIntItem(tr("List Grid Rows"), &ListGridRows));
+
+ Add(new cMenuEditIntItem(tr("Extras Grid Columns"), &ExtrasGridColumns));
+ Add(new cMenuEditIntItem(tr("Extras Grid Rows"), &ExtrasGridRows));
+
+ cMenuEditStrItem *devUUID = new cMenuEditStrItem(tr("Current UUID"), Uuid, STRING_SIZE);
+ devUUID->SetSelectable(false);
+ Add(devUUID);
}
/**
** Store setup.
*/
-void cMyMenuSetupPage::Store(void)
-{
- Config::GetInstance().s_username = std::string(Username);
- Config::GetInstance().s_password = std::string(Password);
- Config::GetInstance().HideMainMenuEntry = HideMainMenuEntry;
- Config::GetInstance().UseCustomTranscodeProfile = UseCustomTranscodeProfile;
- Config::GetInstance().UsePlexAccount = UsePlexAccount;
- Config::GetInstance().UseConfiguredServer = UseConfiguredServer;
- Config::GetInstance().s_serverHost = std::string(ServerHost);
- Config::GetInstance().ServerPort = ServerPort;
- Config::GetInstance().CoverGridColumns = CoverGridColumns;
- Config::GetInstance().CoverGridRows = CoverGridRows;
- Config::GetInstance().DetailGridColumns = DetailGridColumns;
- Config::GetInstance().DetailGridRows = DetailGridRows;
- Config::GetInstance().ListGridColumns = ListGridColumns;
- Config::GetInstance().ListGridRows = ListGridRows;
- Config::GetInstance().ExtrasGridColumns = ExtrasGridColumns;
- Config::GetInstance().ExtrasGridRows = ExtrasGridRows;
- Config::GetInstance().DefaultViewMode = (ViewMode)DefaultViewMode;
- Config::GetInstance().UseMpv = UseMpv;
- Config::GetInstance().ScrollByPage = ScrollByPage;
- Config::GetInstance().ScrollAllAround = ScrollAllAround;
- Config::GetInstance().UseAc3 = UseAc3;
- Config::GetInstance().BufferSize = BufferSize;
-
- SetupStore("UseCustomTranscodeProfile", Config::GetInstance().UseCustomTranscodeProfile);
- SetupStore("HideMainMenuEntry", Config::GetInstance().HideMainMenuEntry);
- SetupStore("UsePlexAccount", Config::GetInstance().UsePlexAccount);
- SetupStore("Username", Config::GetInstance().s_username.c_str());
- SetupStore("Password", Config::GetInstance().s_password.c_str());
- SetupStore("UUID", Config::GetInstance().GetUUID().c_str());
- SetupStore("UseConfiguredServer", Config::GetInstance().UseConfiguredServer);
- SetupStore("ServerHost", Config::GetInstance().s_serverHost.c_str());
- SetupStore("ServerPort", Config::GetInstance().ServerPort);
- SetupStore("CoverGridColumns", Config::GetInstance().CoverGridColumns);
- SetupStore("CoverGridRows", Config::GetInstance().CoverGridRows);
- SetupStore("DetailGridColumns", Config::GetInstance().DetailGridColumns);
- SetupStore("DetailGridRows", Config::GetInstance().DetailGridRows);
- SetupStore("ListGridColumns", Config::GetInstance().ListGridColumns);
- SetupStore("ListGridRows", Config::GetInstance().ListGridRows);
- SetupStore("ExtrasGridColumns", Config::GetInstance().ExtrasGridColumns);
- SetupStore("ExtrasGridRows", Config::GetInstance().ExtrasGridRows);
- SetupStore("DefaultViewMode", Config::GetInstance().DefaultViewMode);
- SetupStore("UseMpv", Config::GetInstance().UseMpv);
- SetupStore("ScrollByPage", Config::GetInstance().ScrollByPage);
- SetupStore("ScrollAllAround", Config::GetInstance().ScrollAllAround);
- SetupStore("UseAc3", Config::GetInstance().ScrollAllAround);
- SetupStore("BufferSize", Config::GetInstance().BufferSize);
+void cMyMenuSetupPage::Store(void) {
+ Config::GetInstance().s_username = std::string(Username);
+ Config::GetInstance().s_password = std::string(Password);
+ Config::GetInstance().HideMainMenuEntry = HideMainMenuEntry;
+ Config::GetInstance().UseCustomTranscodeProfile = UseCustomTranscodeProfile;
+ Config::GetInstance().UsePlexAccount = UsePlexAccount;
+ Config::GetInstance().UseConfiguredServer = UseConfiguredServer;
+ Config::GetInstance().s_serverHost = std::string(ServerHost);
+ Config::GetInstance().ServerPort = ServerPort;
+ Config::GetInstance().CoverGridColumns = CoverGridColumns;
+ Config::GetInstance().CoverGridRows = CoverGridRows;
+ Config::GetInstance().DetailGridColumns = DetailGridColumns;
+ Config::GetInstance().DetailGridRows = DetailGridRows;
+ Config::GetInstance().ListGridColumns = ListGridColumns;
+ Config::GetInstance().ListGridRows = ListGridRows;
+ Config::GetInstance().ExtrasGridColumns = ExtrasGridColumns;
+ Config::GetInstance().ExtrasGridRows = ExtrasGridRows;
+ Config::GetInstance().DefaultViewMode = (ViewMode) DefaultViewMode;
+ Config::GetInstance().UseMpv = UseMpv;
+ Config::GetInstance().ScrollByPage = ScrollByPage;
+ Config::GetInstance().ScrollAllAround = ScrollAllAround;
+ Config::GetInstance().UseAc3 = UseAc3;
+ Config::GetInstance().BufferSize = BufferSize;
+
+ SetupStore("UseCustomTranscodeProfile", Config::GetInstance().UseCustomTranscodeProfile);
+ SetupStore("HideMainMenuEntry", Config::GetInstance().HideMainMenuEntry);
+ SetupStore("UsePlexAccount", Config::GetInstance().UsePlexAccount);
+ SetupStore("Username", Config::GetInstance().s_username.c_str());
+ SetupStore("Password", Config::GetInstance().s_password.c_str());
+ SetupStore("UUID", Config::GetInstance().GetUUID().c_str());
+ SetupStore("UseConfiguredServer", Config::GetInstance().UseConfiguredServer);
+ SetupStore("ServerHost", Config::GetInstance().s_serverHost.c_str());
+ SetupStore("ServerPort", Config::GetInstance().ServerPort);
+ SetupStore("CoverGridColumns", Config::GetInstance().CoverGridColumns);
+ SetupStore("CoverGridRows", Config::GetInstance().CoverGridRows);
+ SetupStore("DetailGridColumns", Config::GetInstance().DetailGridColumns);
+ SetupStore("DetailGridRows", Config::GetInstance().DetailGridRows);
+ SetupStore("ListGridColumns", Config::GetInstance().ListGridColumns);
+ SetupStore("ListGridRows", Config::GetInstance().ListGridRows);
+ SetupStore("ExtrasGridColumns", Config::GetInstance().ExtrasGridColumns);
+ SetupStore("ExtrasGridRows", Config::GetInstance().ExtrasGridRows);
+ SetupStore("DefaultViewMode", Config::GetInstance().DefaultViewMode);
+ SetupStore("UseMpv", Config::GetInstance().UseMpv);
+ SetupStore("ScrollByPage", Config::GetInstance().ScrollByPage);
+ SetupStore("ScrollAllAround", Config::GetInstance().ScrollAllAround);
+ SetupStore("UseAc3", Config::GetInstance().ScrollAllAround);
+ SetupStore("BufferSize", Config::GetInstance().BufferSize);
}
diff --git a/Config.h b/Config.h
index 5d87ca0..d840fc2 100644
--- a/Config.h
+++ b/Config.h
@@ -17,83 +17,95 @@
#define STRING_SIZE 256
struct ViewEntry {
- std::string Name;
- std::string PlexPath;
+ std::string Name;
+ std::string PlexPath;
};
enum ViewMode {
- Cover = 0,
- List = 1,
- Detail = 2
+ Cover = 0,
+ List = 1,
+ Detail = 2
};
-class Config
-{
-
+class Config {
+
public:
- static Config& GetInstance() {
- static Config instance;
- return instance;
- }
- static const char* viewModeNames[];
-
- std::string s_username;
- std::string s_password;
- std::string s_serverHost;
- int ServerPort;
-
- bool HideMainMenuEntry;
- bool UseCustomTranscodeProfile;
- bool UsePlexAccount;
- bool UseConfiguredServer;
- bool UseAc3;
- int BufferSize;
-
- int CoverGridColumns;
- int CoverGridRows;
-
- int ListGridColumns;
- int ListGridRows;
-
- int DetailGridColumns;
- int DetailGridRows;
-
- int ExtrasGridColumns;
- int ExtrasGridRows;
-
- ViewMode DefaultViewMode;
-
- std::vector<ViewEntry> m_viewentries;
- std::vector<ViewEntry> m_serverViewentries;
-
- bool ScrollByPage;
- bool ScrollAllAround;
- bool UseMpv;
-
- std::string GetUUID();
- void SetUUID(const char* uuid);
- std::string GetHostname();
- std::string GetLanguage();
- std::string GetUsername();
- std::string GetPassword();
- //int ThumbHeight() { return 1080 / CoverGridRows; };
- //int ThumbWidth() { return 1920 / CoverGridColumns; };
- //int ArtHeight() { return 1080 / 4; };
- //int ArtWidth() { return 1920 / 4; };
- int ThumbHeight() { return 1080; };
- int ThumbWidth() { return 1920; };
- int ArtHeight() { return 1080; };
- int ArtWidth() { return 1920; };
- int BannerHeight() { return 1080 / 2; };
- int BannerWidth() { return 1920 / 2; };
-
- bool Parse(const char *name, const char *value);
-
+ static Config &GetInstance() {
+ static Config instance;
+ return instance;
+ }
+
+ static const char *viewModeNames[];
+
+ std::string s_username;
+ std::string s_password;
+ std::string s_serverHost;
+ int ServerPort;
+
+ bool HideMainMenuEntry;
+ bool UseCustomTranscodeProfile;
+ bool UsePlexAccount;
+ bool UseConfiguredServer;
+ bool UseAc3;
+ int BufferSize;
+
+ int CoverGridColumns;
+ int CoverGridRows;
+
+ int ListGridColumns;
+ int ListGridRows;
+
+ int DetailGridColumns;
+ int DetailGridRows;
+
+ int ExtrasGridColumns;
+ int ExtrasGridRows;
+
+ ViewMode DefaultViewMode;
+
+ std::vector<ViewEntry> m_viewentries;
+ std::vector<ViewEntry> m_serverViewentries;
+
+ bool ScrollByPage;
+ bool ScrollAllAround;
+ bool UseMpv;
+
+ std::string GetUUID();
+
+ void SetUUID(const char *uuid);
+
+ std::string GetHostname();
+
+ std::string GetLanguage();
+
+ std::string GetUsername();
+
+ std::string GetPassword();
+
+ //int ThumbHeight() { return 1080 / CoverGridRows; };
+ //int ThumbWidth() { return 1920 / CoverGridColumns; };
+ //int ArtHeight() { return 1080 / 4; };
+ //int ArtWidth() { return 1920 / 4; };
+ int ThumbHeight() { return 1080; };
+
+ int ThumbWidth() { return 1920; };
+
+ int ArtHeight() { return 1080; };
+
+ int ArtWidth() { return 1920; };
+
+ int BannerHeight() { return 1080 / 2; };
+
+ int BannerWidth() { return 1920 / 2; };
+
+ bool Parse(const char *name, const char *value);
+
private:
- Config();
- std::string s_uuid;
- std::string s_hostname;
+ Config();
+
+ std::string s_uuid;
+ std::string s_hostname;
};
@@ -104,38 +116,38 @@ private:
/**
** Play plugin menu setup page class.
*/
-class cMyMenuSetupPage:public cMenuSetupPage
-{
- protected:
- char Username[STRING_SIZE];
- char Password[STRING_SIZE];
- char Uuid[STRING_SIZE];
- char ServerHost[STRING_SIZE];
- int ServerPort;
- int UseConfiguredServer;
- int HideMainMenuEntry;
- int UseCustomTranscodeProfile;
- int UsePlexAccount;
- int CoverGridColumns;
- int CoverGridRows;
- int DetailGridColumns;
- int DetailGridRows;
- int ListGridColumns;
- int ListGridRows;
- int ExtrasGridColumns;
- int ExtrasGridRows;
- int DefaultViewMode;
- int UseMpv;
- int ScrollByPage;
- int ScrollAllAround;
- int UseAc3;
- int BufferSize;
+class cMyMenuSetupPage : public cMenuSetupPage {
+protected:
+ char Username[STRING_SIZE];
+ char Password[STRING_SIZE];
+ char Uuid[STRING_SIZE];
+ char ServerHost[STRING_SIZE];
+ int ServerPort;
+ int UseConfiguredServer;
+ int HideMainMenuEntry;
+ int UseCustomTranscodeProfile;
+ int UsePlexAccount;
+ int CoverGridColumns;
+ int CoverGridRows;
+ int DetailGridColumns;
+ int DetailGridRows;
+ int ListGridColumns;
+ int ListGridRows;
+ int ExtrasGridColumns;
+ int ExtrasGridRows;
+ int DefaultViewMode;
+ int UseMpv;
+ int ScrollByPage;
+ int ScrollAllAround;
+ int UseAc3;
+ int BufferSize;
virtual void Store(void);
- public:
- cMyMenuSetupPage(void);
- virtual eOSState ProcessKey(eKeys); // handle input
+public:
+ cMyMenuSetupPage(void);
+
+ virtual eOSState ProcessKey(eKeys); // handle input
};
#endif // CONFIG_H
diff --git a/ControlServer.cpp b/ControlServer.cpp
index 31363ae..5344e44 100644
--- a/ControlServer.cpp
+++ b/ControlServer.cpp
@@ -1,31 +1,27 @@
#include "ControlServer.h"
-namespace plexclient
-{
+namespace plexclient {
-ControlServer::ControlServer()
-{
- m_pSvs = new Poco::Net::ServerSocket(3200);;
- m_pSrv = new Poco::Net::HTTPServer(new PlexReqHandlerFactory, *m_pSvs, new Poco::Net::HTTPServerParams);
-}
+ ControlServer::ControlServer() {
+ m_pSvs = new Poco::Net::ServerSocket(3200);;
+ m_pSrv = new Poco::Net::HTTPServer(new PlexReqHandlerFactory, *m_pSvs, new Poco::Net::HTTPServerParams);
+ }
-void ControlServer::Stop()
-{
- Cancel(1);
- // Stop the HTTPServer
- m_pSrv->stop();
-}
+ void ControlServer::Stop() {
+ Cancel(1);
+ // Stop the HTTPServer
+ m_pSrv->stop();
+ }
-void ControlServer::Action()
-{
- isyslog("[plex] Starting Controlserver...");
- // start the HTTPServer
- m_pSrv->start();
- while(Running()) {
- SubscriptionManager::GetInstance().Notify();
- cCondWait::SleepMs(1000);
- }
-}
+ void ControlServer::Action() {
+ isyslog("[plex] Starting Controlserver...");
+ // start the HTTPServer
+ m_pSrv->start();
+ while (Running()) {
+ SubscriptionManager::GetInstance().Notify();
+ cCondWait::SleepMs(1000);
+ }
+ }
}
diff --git a/ControlServer.h b/ControlServer.h
index 8546fa7..e742fb3 100644
--- a/ControlServer.h
+++ b/ControlServer.h
@@ -12,29 +12,28 @@
#include <vdr/thread.h>
-namespace plexclient
-{
+namespace plexclient {
-class ControlServer : public cThread
-{
+ class ControlServer : public cThread {
-public:
- static ControlServer& GetInstance() {
- static ControlServer instance;
- return instance;
- }
- void Stop();
+ public:
+ static ControlServer &GetInstance() {
+ static ControlServer instance;
+ return instance;
+ }
-protected:
- void Action();
+ void Stop();
-private:
- ControlServer();
+ protected:
+ void Action();
- Poco::Net::ServerSocket *m_pSvs;
- Poco::Net::HTTPServer *m_pSrv;
+ private:
+ ControlServer();
-};
+ Poco::Net::ServerSocket *m_pSvs;
+ Poco::Net::HTTPServer *m_pSrv;
+
+ };
}
diff --git a/Directory.cpp b/Directory.cpp
index d4cbb09..91511b3 100644
--- a/Directory.cpp
+++ b/Directory.cpp
@@ -3,187 +3,190 @@
#include <Poco/Format.h>
#include "tokendefinitions.h"
-namespace plexclient
-{
-
-Directory::Directory(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent)
-{
- m_pParent = parent;
- m_pServer = Server;
-
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
-
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Directory") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
-
- m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
- m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
- m_iLeafCount = GetNodeValueAsInt(pAttribs->getNamedItem("leafCount"));
- m_iViewedLeafCount = GetNodeValueAsInt(pAttribs->getNamedItem("viewedLeafCount"));
- m_iChildCount = GetNodeValueAsInt(pAttribs->getNamedItem("childCount"));
- m_fRating = GetNodeValueAsDouble(pAttribs->getNamedItem("rating"));
- m_iYear = GetNodeValueAsInt(pAttribs->getNamedItem("year"));
- m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
- m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
- m_sKey = GetNodeValue(pAttribs->getNamedItem("key"));
- m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
- m_sTitle1 = GetNodeValue(pAttribs->getNamedItem("title1"));
- m_sTitle2 = GetNodeValue(pAttribs->getNamedItem("title2"));
- m_sParentTitle = GetNodeValue(pAttribs->getNamedItem("parentTitle"));
- m_sComposite = GetNodeValue(pAttribs->getNamedItem("composite"));
- m_sLanguage = GetNodeValue(pAttribs->getNamedItem("language"));
- m_sUuid = GetNodeValue(pAttribs->getNamedItem("uuid"));
- m_tUpdatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("updatedAt"));
- m_tCreatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("createdAt"));
- m_eType = GetNodeValueAsMediaType(pAttribs->getNamedItem("type"));
- m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
- m_sParentSummary = GetNodeValue(pAttribs->getNamedItem("parentSummary"));
- m_sStudio = GetNodeValue(pAttribs->getNamedItem("studio"));
-
- pAttribs->release();
- } else if(Poco::icompare(pChildNode->nodeName(), "Genre") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vGenre.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Role") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vRole.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
- }
- pChildNode = it.nextNode();
- }
- if(m_sTitle2.empty()) m_sTitle2 = parent->m_sTitle2;
-}
-
-std::string Directory::GetTitle()
-{
- std::string seriesTitle = m_sParentTitle;
- if(seriesTitle.empty() && m_pParent)
- seriesTitle = m_pParent->m_sParentTitle;
-
- switch(m_eType) {
- case MediaType::SEASON:
- return Poco::format(tr("%s - Season %d"), seriesTitle, m_iIndex);
- default:
- return m_sTitle;
- }
-}
+namespace plexclient {
+
+ Directory::Directory(Poco::XML::Node *pNode, PlexServer *Server, MediaContainer *parent) {
+ m_pParent = parent;
+ m_pServer = Server;
+
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
+
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Directory") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+
+ m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
+ m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
+ m_iLeafCount = GetNodeValueAsInt(pAttribs->getNamedItem("leafCount"));
+ m_iViewedLeafCount = GetNodeValueAsInt(pAttribs->getNamedItem("viewedLeafCount"));
+ m_iChildCount = GetNodeValueAsInt(pAttribs->getNamedItem("childCount"));
+ m_fRating = GetNodeValueAsDouble(pAttribs->getNamedItem("rating"));
+ m_iYear = GetNodeValueAsInt(pAttribs->getNamedItem("year"));
+ m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
+ m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
+ m_sKey = GetNodeValue(pAttribs->getNamedItem("key"));
+ m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
+ m_sTitle1 = GetNodeValue(pAttribs->getNamedItem("title1"));
+ m_sTitle2 = GetNodeValue(pAttribs->getNamedItem("title2"));
+ m_sParentTitle = GetNodeValue(pAttribs->getNamedItem("parentTitle"));
+ m_sComposite = GetNodeValue(pAttribs->getNamedItem("composite"));
+ m_sLanguage = GetNodeValue(pAttribs->getNamedItem("language"));
+ m_sUuid = GetNodeValue(pAttribs->getNamedItem("uuid"));
+ m_tUpdatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("updatedAt"));
+ m_tCreatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("createdAt"));
+ m_eType = GetNodeValueAsMediaType(pAttribs->getNamedItem("type"));
+ m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
+ m_sParentSummary = GetNodeValue(pAttribs->getNamedItem("parentSummary"));
+ m_sStudio = GetNodeValue(pAttribs->getNamedItem("studio"));
+
+ pAttribs->release();
+ } else if (Poco::icompare(pChildNode->nodeName(), "Genre") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vGenre.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Role") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vRole.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+ }
+ pChildNode = it.nextNode();
+ }
+ if (m_sTitle2.empty()) m_sTitle2 = parent->m_sTitle2;
+ }
+
+ std::string Directory::GetTitle() {
+ std::string seriesTitle = m_sParentTitle;
+ if (seriesTitle.empty() && m_pParent)
+ seriesTitle = m_pParent->m_sParentTitle;
+
+ switch (m_eType) {
+ case MediaType::SEASON:
+ return Poco::format(tr("%s - Season %d"), seriesTitle, m_iIndex);
+ default:
+ return m_sTitle;
+ }
+ }
#ifdef SKINDESIGNER
-void Directory::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached)
-{
- if(clear) grid->ClearTokens();
- grid->AddIntToken((int)(eTokenGridInt::viewmode), Config::GetInstance().DefaultViewMode);
- grid->AddStringToken((int)(eTokenGridStr::title), m_sTitle.c_str());
- grid->AddIntToken((int)(eTokenGridInt::viewgroup), (int)m_pParent->m_eViewGroup);
-
- // Thumb, Cover, Episodepicture
- bool cached = false;
- if(!ThumbUri().empty()) {
- std::string thumb = cPictureCache::GetInstance().GetPath(ThumbUri(), Config::GetInstance().ThumbWidth(), Config::GetInstance().ThumbHeight(), cached, OnCached, this);
- if (cached) grid->AddStringToken((int)(eTokenGridStr::thumb), thumb.c_str());
- }
- grid->AddIntToken((int)(eTokenGridInt::hasthumb), cached);
-
- // Fanart
- cached = false;
- if(!ArtUri().empty()) {
- std::string art = cPictureCache::GetInstance().GetPath(ArtUri(), Config::GetInstance().ArtWidth(), Config::GetInstance().ArtHeight(), cached);
- if (cached) grid->AddStringToken((int)(eTokenGridStr::art), art.c_str());
- }
- grid->AddIntToken((int)(eTokenGridInt::hasart), cached);
-
- if(m_eType == MediaType::UNDEF || m_eType == MediaType::MOVIE || m_eType == MediaType::PHOTO) {
- grid->AddIntToken((int)(eTokenGridInt::isdirectory), true);
- }
-
- vector<int> loopInfo;
- loopInfo.push_back(m_vRole.size());
- loopInfo.push_back(m_vGenre.size());
- grid->SetLoop(loopInfo);
-
- int actloopIndex = grid->GetLoopIndex("roles");
- int i = 0;
- for(auto it = m_vRole.begin(); it != m_vRole.end(); it++) {
- grid->AddLoopToken(actloopIndex, i, (int)(eTokenGridActorLst::roles), it->c_str());
- i++;
- }
-
- int genloopIndex = grid->GetLoopIndex("genres");
- i = 0;
- for(auto it = m_vGenre.begin(); it != m_vGenre.end(); it++) {
- grid->AddLoopToken(genloopIndex, i, (int)(eTokenGridGenresLst::genres), it->c_str());
- i++;
- }
-
- if(m_eType == MediaType::SHOW) {
- grid->AddIntToken((int)(eTokenGridInt::isshow), true);
- grid->AddStringToken((int)(eTokenGridStr::summary), m_sSummary.c_str());
- grid->AddIntToken((int)(eTokenGridInt::leafCount), m_iLeafCount);
- grid->AddIntToken((int)(eTokenGridInt::viewedLeafCount), m_iViewedLeafCount);
- grid->AddIntToken((int)(eTokenGridInt::childCount), m_iChildCount);
- grid->AddIntToken((int)(eTokenGridInt::rating), m_fRating*10);
- grid->AddStringToken((int)(eTokenGridStr::ratingstring), Poco::format("%.1f", m_fRating).c_str());
- grid->AddStringToken((int)(eTokenGridStr::studio), m_sStudio.c_str());
-
- grid->AddIntToken((int)(eTokenGridInt::year), m_iYear);
- }
-
- if(m_eType == MediaType::SEASON) {
- grid->AddIntToken((int)(eTokenGridInt::isseason), true);
-
- std::string summary = m_sParentSummary;
- if(m_sParentSummary.empty() && m_pParent)
- summary = m_pParent->m_sSummary;
-
- grid->AddStringToken((int)(eTokenGridStr::summary), summary.c_str());
- grid->AddIntToken((int)(eTokenGridInt::season), m_iIndex);
- grid->AddIntToken((int)(eTokenGridInt::leafCount), m_iLeafCount);
- grid->AddIntToken((int)(eTokenGridInt::viewedLeafCount), m_iViewedLeafCount);
-
- std::string seriesTitle = m_sParentTitle;
- if(seriesTitle.empty() && m_pParent)
- seriesTitle = m_pParent->m_sParentTitle;
-
- grid->AddStringToken((int)(eTokenGridStr::seriestitle), seriesTitle.c_str());
- grid->AddIntToken((int)(eTokenGridInt::year), m_pParent->m_iParentYear);
- }
-
- // Banner, Seriesbanner
- if(m_pParent && !m_pParent->m_sBanner.empty()) {
- cached = false;
- std::string banner = cPictureCache::GetInstance().GetPath(m_pServer->GetUri() + m_pParent->m_sBanner, Config::GetInstance().BannerWidth(), Config::GetInstance().BannerHeight(), cached, OnCached, this);
- if(cached) {
- grid->AddIntToken((int)(eTokenGridInt::hasbanner), cached);
- grid->AddStringToken((int)(eTokenGridStr::banner), banner.c_str());
- }
- }
-}
-#endif
-std::string Directory::ArtUri()
-{
- if(!m_sArt.empty()) {
- if(m_sArt.find("http://") != std::string::npos) return m_sArt;
- if(m_sArt[0] == '/') return m_pServer->GetUri() + m_sArt;
- return m_pServer->GetUri() + '/' + m_sArt;
- }
- if(m_pParent) return m_pParent->ArtUri();
- return "";
-}
+ void Directory::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear,
+ std::function<void(cGridElement *)> OnCached) {
+ if (clear) grid->ClearTokens();
+ grid->AddIntToken((int) (eTokenGridInt::viewmode), Config::GetInstance().DefaultViewMode);
+ grid->AddStringToken((int) (eTokenGridStr::title), m_sTitle.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::viewgroup), (int) m_pParent->m_eViewGroup);
+
+ // Thumb, Cover, Episodepicture
+ bool cached = false;
+ if (!ThumbUri().empty()) {
+ std::string thumb = cPictureCache::GetInstance().GetPath(ThumbUri(), Config::GetInstance().ThumbWidth(),
+ Config::GetInstance().ThumbHeight(), cached,
+ OnCached, this);
+ if (cached) grid->AddStringToken((int) (eTokenGridStr::thumb), thumb.c_str());
+ }
+ grid->AddIntToken((int) (eTokenGridInt::hasthumb), cached);
+
+ // Fanart
+ cached = false;
+ if (!ArtUri().empty()) {
+ std::string art = cPictureCache::GetInstance().GetPath(ArtUri(), Config::GetInstance().ArtWidth(),
+ Config::GetInstance().ArtHeight(), cached);
+ if (cached) grid->AddStringToken((int) (eTokenGridStr::art), art.c_str());
+ }
+ grid->AddIntToken((int) (eTokenGridInt::hasart), cached);
+
+ if (m_eType == MediaType::UNDEF || m_eType == MediaType::MOVIE || m_eType == MediaType::PHOTO) {
+ grid->AddIntToken((int) (eTokenGridInt::isdirectory), true);
+ }
+
+ vector<int> loopInfo;
+ loopInfo.push_back(m_vRole.size());
+ loopInfo.push_back(m_vGenre.size());
+ grid->SetLoop(loopInfo);
+
+ int actloopIndex = grid->GetLoopIndex("roles");
+ int i = 0;
+ for (auto it = m_vRole.begin(); it != m_vRole.end(); it++) {
+ grid->AddLoopToken(actloopIndex, i, (int) (eTokenGridActorLst::roles), it->c_str());
+ i++;
+ }
+
+ int genloopIndex = grid->GetLoopIndex("genres");
+ i = 0;
+ for (auto it = m_vGenre.begin(); it != m_vGenre.end(); it++) {
+ grid->AddLoopToken(genloopIndex, i, (int) (eTokenGridGenresLst::genres), it->c_str());
+ i++;
+ }
+
+ if (m_eType == MediaType::SHOW) {
+ grid->AddIntToken((int) (eTokenGridInt::isshow), true);
+ grid->AddStringToken((int) (eTokenGridStr::summary), m_sSummary.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::leafCount), m_iLeafCount);
+ grid->AddIntToken((int) (eTokenGridInt::viewedLeafCount), m_iViewedLeafCount);
+ grid->AddIntToken((int) (eTokenGridInt::childCount), m_iChildCount);
+ grid->AddIntToken((int) (eTokenGridInt::rating), m_fRating * 10);
+ grid->AddStringToken((int) (eTokenGridStr::ratingstring), Poco::format("%.1f", m_fRating).c_str());
+ grid->AddStringToken((int) (eTokenGridStr::studio), m_sStudio.c_str());
+
+ grid->AddIntToken((int) (eTokenGridInt::year), m_iYear);
+ }
+
+ if (m_eType == MediaType::SEASON) {
+ grid->AddIntToken((int) (eTokenGridInt::isseason), true);
+
+ std::string summary = m_sParentSummary;
+ if (m_sParentSummary.empty() && m_pParent)
+ summary = m_pParent->m_sSummary;
+
+ grid->AddStringToken((int) (eTokenGridStr::summary), summary.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::season), m_iIndex);
+ grid->AddIntToken((int) (eTokenGridInt::leafCount), m_iLeafCount);
+ grid->AddIntToken((int) (eTokenGridInt::viewedLeafCount), m_iViewedLeafCount);
+
+ std::string seriesTitle = m_sParentTitle;
+ if (seriesTitle.empty() && m_pParent)
+ seriesTitle = m_pParent->m_sParentTitle;
+
+ grid->AddStringToken((int) (eTokenGridStr::seriestitle), seriesTitle.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::year), m_pParent->m_iParentYear);
+ }
+
+ // Banner, Seriesbanner
+ if (m_pParent && !m_pParent->m_sBanner.empty()) {
+ cached = false;
+ std::string banner = cPictureCache::GetInstance().GetPath(m_pServer->GetUri() + m_pParent->m_sBanner,
+ Config::GetInstance().BannerWidth(),
+ Config::GetInstance().BannerHeight(), cached,
+ OnCached, this);
+ if (cached) {
+ grid->AddIntToken((int) (eTokenGridInt::hasbanner), cached);
+ grid->AddStringToken((int) (eTokenGridStr::banner), banner.c_str());
+ }
+ }
+ }
-std::string Directory::ThumbUri()
-{
- if(!m_sThumb.empty()) {
- if(m_sThumb.find("http://") != std::string::npos) return m_sThumb;
- if(m_sThumb[0] == '/') return m_pServer->GetUri() + m_sThumb;
- return m_pServer->GetUri() + '/' + m_sThumb;
- }
- if(m_pParent) return m_pParent->ThumbUri();
- return "";
-}
+#endif
+
+ std::string Directory::ArtUri() {
+ if (!m_sArt.empty()) {
+ if (m_sArt.find("http://") != std::string::npos) return m_sArt;
+ if (m_sArt[0] == '/') return m_pServer->GetUri() + m_sArt;
+ return m_pServer->GetUri() + '/' + m_sArt;
+ }
+ if (m_pParent) return m_pParent->ArtUri();
+ return "";
+ }
+
+ std::string Directory::ThumbUri() {
+ if (!m_sThumb.empty()) {
+ if (m_sThumb.find("http://") != std::string::npos) return m_sThumb;
+ if (m_sThumb[0] == '/') return m_pServer->GetUri() + m_sThumb;
+ return m_pServer->GetUri() + '/' + m_sThumb;
+ }
+ if (m_pParent) return m_pParent->ThumbUri();
+ return "";
+ }
}
diff --git a/Directory.h b/Directory.h
index 97d7c85..f3a959f 100644
--- a/Directory.h
+++ b/Directory.h
@@ -12,10 +12,13 @@
#include <Poco/String.h>
#include <memory>
+
#ifdef SKINDESIGNER
- #include <libskindesignerapi/osdelements.h>
- #include "pictureCache.h"
- #include "viewGridNavigator.h"
+
+#include <libskindesignerapi/osdelements.h>
+#include "pictureCache.h"
+#include "viewGridNavigator.h"
+
#endif
#include "XmlObject.h"
@@ -30,58 +33,62 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
-class MediaContainer;
+namespace plexclient {
+ class MediaContainer;
-class Directory: private XmlObject
+ class Directory : private XmlObject
#ifdef SKINDESIGNER
-, public cGridElement
+ , public cGridElement
#endif
-{
-public:
- Directory(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent);
-
-public:
- bool m_bAllowSync;
- int m_iIndex; // Season, Episode number
- int m_iYear;
- int m_iLeafCount; // Total number of Episodes
- int m_iViewedLeafCount; // Watched Episodes
- int m_iChildCount; // Number of Seasons
- double m_fRating;
- std::string m_sSummary;
- std::string m_sParentSummary;
- std::string m_sTitle;
- std::string m_sTitle1;
- std::string m_sTitle2;
- std::string m_sParentTitle;
- std::string m_sComposite;
- std::string m_sLanguage;
- std::string m_sUuid;
- std::string m_sArt;
- std::string m_sThumb;
- std::string m_sStudio;
- Poco::Timestamp m_tUpdatedAt;
- Poco::Timestamp m_tCreatedAt;
- std::string m_sKey;
-
- std::vector<std::string> m_vGenre;
- std::vector<std::string> m_vRole;
-
- MediaType m_eType;
- PlexServer* m_pServer;
- MediaContainer* m_pParent;
-
- virtual std::string GetTitle();
- std::string ArtUri();
- std::string ThumbUri();
-
+ {
+ public:
+ Directory(Poco::XML::Node *pNode, PlexServer *Server, MediaContainer *parent);
+
+ public:
+ bool m_bAllowSync;
+ int m_iIndex; // Season, Episode number
+ int m_iYear;
+ int m_iLeafCount; // Total number of Episodes
+ int m_iViewedLeafCount; // Watched Episodes
+ int m_iChildCount; // Number of Seasons
+ double m_fRating;
+ std::string m_sSummary;
+ std::string m_sParentSummary;
+ std::string m_sTitle;
+ std::string m_sTitle1;
+ std::string m_sTitle2;
+ std::string m_sParentTitle;
+ std::string m_sComposite;
+ std::string m_sLanguage;
+ std::string m_sUuid;
+ std::string m_sArt;
+ std::string m_sThumb;
+ std::string m_sStudio;
+ Poco::Timestamp m_tUpdatedAt;
+ Poco::Timestamp m_tCreatedAt;
+ std::string m_sKey;
+
+ std::vector<std::string> m_vGenre;
+ std::vector<std::string> m_vRole;
+
+ MediaType m_eType;
+ PlexServer *m_pServer;
+ MediaContainer *m_pParent;
+
+ virtual std::string GetTitle();
+
+ std::string ArtUri();
+
+ std::string ThumbUri();
+
#ifdef SKINDESIGNER
- // gridElement
- virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL);
+
+ // gridElement
+ virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true,
+ std::function<void(cGridElement *)> OnCached = NULL);
+
#endif
-};
+ };
}
diff --git a/Media.cpp b/Media.cpp
index 35eef23..b17aa6f 100644
--- a/Media.cpp
+++ b/Media.cpp
@@ -1,67 +1,66 @@
#include "Media.h"
#include "tokendefinitions.h"
-namespace plexclient
-{
+namespace plexclient {
-Media::Media(Poco::XML::Node* pNode)
-{
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
+ Media::Media(Poco::XML::Node *pNode) {
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Media") == 0) {
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Media") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_sVideoResolution = GetNodeValue(pAttribs->getNamedItem("videoResolution"));
- m_iId = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
- m_lDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
- m_iBitrate = GetNodeValueAsInt(pAttribs->getNamedItem("bitrate"));
- m_iWidth = GetNodeValueAsInt(pAttribs->getNamedItem("width"));
- m_iHeight = GetNodeValueAsInt(pAttribs->getNamedItem("height"));
- m_sAspectRatio = GetNodeValue(pAttribs->getNamedItem("aspectRatio"));
- m_iAudioChannels = GetNodeValueAsInt(pAttribs->getNamedItem("audioChannels"));
- m_sAudioCodec = GetNodeValue(pAttribs->getNamedItem("audioCodec"));
- m_sVideoCodec = GetNodeValue(pAttribs->getNamedItem("videoCodec"));
- m_sContainer = GetNodeValue(pAttribs->getNamedItem("container"));
- m_VideoFrameRate = GetNodeValue(pAttribs->getNamedItem("videoFrameRate"));
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_sVideoResolution = GetNodeValue(pAttribs->getNamedItem("videoResolution"));
+ m_iId = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
+ m_lDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
+ m_iBitrate = GetNodeValueAsInt(pAttribs->getNamedItem("bitrate"));
+ m_iWidth = GetNodeValueAsInt(pAttribs->getNamedItem("width"));
+ m_iHeight = GetNodeValueAsInt(pAttribs->getNamedItem("height"));
+ m_sAspectRatio = GetNodeValue(pAttribs->getNamedItem("aspectRatio"));
+ m_iAudioChannels = GetNodeValueAsInt(pAttribs->getNamedItem("audioChannels"));
+ m_sAudioCodec = GetNodeValue(pAttribs->getNamedItem("audioCodec"));
+ m_sVideoCodec = GetNodeValue(pAttribs->getNamedItem("videoCodec"));
+ m_sContainer = GetNodeValue(pAttribs->getNamedItem("container"));
+ m_VideoFrameRate = GetNodeValue(pAttribs->getNamedItem("videoFrameRate"));
- pAttribs->release();
+ pAttribs->release();
- }
- if(Poco::icompare(pChildNode->nodeName(), "Part") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_sPartKey = GetNodeValue(pAttribs->getNamedItem("key"));
- m_iPartId = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
- m_lPartDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
- m_sPartFile = GetNodeValue(pAttribs->getNamedItem("file"));
- m_lPartSize = GetNodeValueAsLong(pAttribs->getNamedItem("size"));
- m_sPartContainer = GetNodeValue(pAttribs->getNamedItem("container"));
+ }
+ if (Poco::icompare(pChildNode->nodeName(), "Part") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_sPartKey = GetNodeValue(pAttribs->getNamedItem("key"));
+ m_iPartId = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
+ m_lPartDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
+ m_sPartFile = GetNodeValue(pAttribs->getNamedItem("file"));
+ m_lPartSize = GetNodeValueAsLong(pAttribs->getNamedItem("size"));
+ m_sPartContainer = GetNodeValue(pAttribs->getNamedItem("container"));
- pAttribs->release();
- }
- if(Poco::icompare(pChildNode->nodeName(), "Stream") == 0) {
- m_vStreams.push_back(Stream(pChildNode));
- }
- pChildNode = it.nextNode();
- }
-}
+ pAttribs->release();
+ }
+ if (Poco::icompare(pChildNode->nodeName(), "Stream") == 0) {
+ m_vStreams.push_back(Stream(pChildNode));
+ }
+ pChildNode = it.nextNode();
+ }
+ }
#ifdef SKINDESIGNER
-void Media::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid)
-{
- grid->AddStringToken((int)(eTokenGridStr::videoResolution), m_sVideoResolution.c_str());
- grid->AddIntToken((int)(eTokenGridInt::bitrate), m_iBitrate);
- grid->AddIntToken((int)(eTokenGridInt::width), m_iWidth);
- grid->AddIntToken((int)(eTokenGridInt::height), m_iHeight);
- grid->AddIntToken((int)(eTokenGridInt::audioChannels), m_iAudioChannels);
- grid->AddStringToken((int)(eTokenGridStr::aspectRatio), m_sAspectRatio.c_str());
- grid->AddStringToken((int)(eTokenGridStr::audioCodec), m_sAudioCodec.c_str());
- grid->AddStringToken((int)(eTokenGridStr::videoCodec), m_sVideoCodec.c_str());
- grid->AddStringToken((int)(eTokenGridStr::container), m_sContainer.c_str());
- grid->AddStringToken((int)(eTokenGridStr::videoFrameRate), m_VideoFrameRate.c_str());
-}
+
+ void Media::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid) {
+ grid->AddStringToken((int) (eTokenGridStr::videoResolution), m_sVideoResolution.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::bitrate), m_iBitrate);
+ grid->AddIntToken((int) (eTokenGridInt::width), m_iWidth);
+ grid->AddIntToken((int) (eTokenGridInt::height), m_iHeight);
+ grid->AddIntToken((int) (eTokenGridInt::audioChannels), m_iAudioChannels);
+ grid->AddStringToken((int) (eTokenGridStr::aspectRatio), m_sAspectRatio.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::audioCodec), m_sAudioCodec.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::videoCodec), m_sVideoCodec.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::container), m_sContainer.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::videoFrameRate), m_VideoFrameRate.c_str());
+ }
+
#endif
}
diff --git a/Media.h b/Media.h
index ac9f6e9..fde49d3 100644
--- a/Media.h
+++ b/Media.h
@@ -14,16 +14,19 @@
#include <vector>
#include <iostream>
+
#ifdef SKINDESIGNER
- #include <libskindesignerapi/osdelements.h>
+
+#include <libskindesignerapi/osdelements.h>
+
#endif
+
#include <memory>
#include "XmlObject.h" // Base class: model::XmlObject
#include "Stream.h"
-
using Poco::XML::DOMParser;
using Poco::XML::Document;
using Poco::XML::NodeIterator;
@@ -32,42 +35,43 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
-
-class Media: XmlObject
-{
- public:
- Media() {};
- Media(Poco::XML::Node* pNode);
-
-public:
- std::string m_sVideoResolution;
- int m_iId;
- long m_lDuration;
- int m_iBitrate;
- int m_iWidth;
- int m_iHeight;
- std::string m_sAspectRatio;
- int m_iAudioChannels;
- std::string m_sAudioCodec;
- std::string m_sVideoCodec;
- std::string m_sContainer;
- std::string m_VideoFrameRate;
-
- std::string m_sPartKey;
- int m_iPartId;
- long m_lPartDuration;
- std::string m_sPartFile;
- long m_lPartSize;
- std::string m_sPartContainer;
-
- std::vector<Stream> m_vStreams;
-
-#ifdef SKINDESIGNER
- void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid);
+namespace plexclient {
+
+ class Media : XmlObject {
+ public:
+ Media() { };
+
+ Media(Poco::XML::Node *pNode);
+
+ public:
+ std::string m_sVideoResolution;
+ int m_iId;
+ long m_lDuration;
+ int m_iBitrate;
+ int m_iWidth;
+ int m_iHeight;
+ std::string m_sAspectRatio;
+ int m_iAudioChannels;
+ std::string m_sAudioCodec;
+ std::string m_sVideoCodec;
+ std::string m_sContainer;
+ std::string m_VideoFrameRate;
+
+ std::string m_sPartKey;
+ int m_iPartId;
+ long m_lPartDuration;
+ std::string m_sPartFile;
+ long m_lPartSize;
+ std::string m_sPartContainer;
+
+ std::vector<Stream> m_vStreams;
+
+#ifdef SKINDESIGNER
+
+ void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid);
+
#endif
-};
+ };
}
diff --git a/MediaContainer.cpp b/MediaContainer.cpp
index 264d33b..0fe2137 100644
--- a/MediaContainer.cpp
+++ b/MediaContainer.cpp
@@ -1,92 +1,91 @@
#include "MediaContainer.h"
#ifdef SKINDESIGNER
- #include "pictureCache.h"
+
+#include "pictureCache.h"
+
#endif
-namespace plexclient
-{
-MediaContainer::MediaContainer(std::istream* response) : MediaContainer(response, NULL) {}
-
-MediaContainer::MediaContainer(std::istream* response, PlexServer* Server)
-{
- m_pServer = Server;
- m_eViewGroup = MediaType::UNDEF;
- try {
- InputSource src(*response);
- DOMParser parser;
- Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
-
- NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pNode = it.nextNode();
- while(pNode) {
- if(Poco::icompare(pNode->nodeName(), "MediaContainer") == 0) {
- Poco::XML::NamedNodeMap* pAttribs = pNode->attributes();
-
- m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
- m_sTitle1 = GetNodeValue(pAttribs->getNamedItem("title1"));
- m_sTitle2 = GetNodeValue(pAttribs->getNamedItem("title2"));
- m_sGrandparentTitle = GetNodeValue(pAttribs->getNamedItem("grandparentTitle"));
- m_sParentTitle = GetNodeValue(pAttribs->getNamedItem("parentTitle"));
- m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
- m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
- m_sBanner = GetNodeValue(pAttribs->getNamedItem("banner"));
- m_eViewGroup = GetNodeValueAsMediaType(pAttribs->getNamedItem("viewGroup"));
- m_sLibrarySectionTitle = GetNodeValue(pAttribs->getNamedItem("librarySectionTitle"));
- m_sLibrarySectionUUID = GetNodeValue(pAttribs->getNamedItem("librarySectionUUID"));
- m_iLibrarySectionID = GetNodeValueAsInt(pAttribs->getNamedItem("librarySectionID"));
- m_sMediaTagPrefix = GetNodeValue(pAttribs->getNamedItem("mediaTagPrefix"));
- m_iSize = GetNodeValueAsInt(pAttribs->getNamedItem("size"));
- m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
- m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
- m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
- m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
- m_iParentYear = GetNodeValueAsInt(pAttribs->getNamedItem("parentYear"));
-
- pAttribs->release();
- } else if(Poco::icompare(pNode->nodeName(), "Directory") == 0) {
- m_vDirectories.push_back(Directory(pNode, m_pServer, this));
- } else if(Poco::icompare(pNode->nodeName(), "Video") == 0) {
- m_vVideos.push_back(cVideo(pNode, m_pServer, this));
- } else if(Poco::icompare(pNode->nodeName(), "Device") == 0) {
- m_vDevices.push_back(Device(pNode, this));
- } else if(Poco::icompare(pNode->nodeName(), "Playlist") == 0) {
- m_vPlaylists.push_back(Playlist(pNode, this));
- }
-
- pNode = it.nextNode();
- }
-
- } catch(Exception &exc) {
- std::cerr << exc.displayText() << std::endl;
- }
-}
+namespace plexclient {
+ MediaContainer::MediaContainer(std::istream *response) : MediaContainer(response, NULL) { }
-std::string MediaContainer::ArtUri()
-{
- if(m_sArt.find("http://") != std::string::npos) return m_sArt;
- return m_pServer->GetUri() + m_sArt;
-}
+ MediaContainer::MediaContainer(std::istream *response, PlexServer *Server) {
+ m_pServer = Server;
+ m_eViewGroup = MediaType::UNDEF;
+ try {
+ InputSource src(*response);
+ DOMParser parser;
+ Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
-std::string MediaContainer::ThumbUri()
-{
- if(m_sThumb.find("http://") != std::string::npos) return m_sThumb;
- return m_pServer->GetUri() + m_sThumb;
-}
+ NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pNode = it.nextNode();
+ while (pNode) {
+ if (Poco::icompare(pNode->nodeName(), "MediaContainer") == 0) {
+ Poco::XML::NamedNodeMap *pAttribs = pNode->attributes();
+
+ m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
+ m_sTitle1 = GetNodeValue(pAttribs->getNamedItem("title1"));
+ m_sTitle2 = GetNodeValue(pAttribs->getNamedItem("title2"));
+ m_sGrandparentTitle = GetNodeValue(pAttribs->getNamedItem("grandparentTitle"));
+ m_sParentTitle = GetNodeValue(pAttribs->getNamedItem("parentTitle"));
+ m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
+ m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
+ m_sBanner = GetNodeValue(pAttribs->getNamedItem("banner"));
+ m_eViewGroup = GetNodeValueAsMediaType(pAttribs->getNamedItem("viewGroup"));
+ m_sLibrarySectionTitle = GetNodeValue(pAttribs->getNamedItem("librarySectionTitle"));
+ m_sLibrarySectionUUID = GetNodeValue(pAttribs->getNamedItem("librarySectionUUID"));
+ m_iLibrarySectionID = GetNodeValueAsInt(pAttribs->getNamedItem("librarySectionID"));
+ m_sMediaTagPrefix = GetNodeValue(pAttribs->getNamedItem("mediaTagPrefix"));
+ m_iSize = GetNodeValueAsInt(pAttribs->getNamedItem("size"));
+ m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
+ m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
+ m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
+ m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
+ m_iParentYear = GetNodeValueAsInt(pAttribs->getNamedItem("parentYear"));
+
+ pAttribs->release();
+ } else if (Poco::icompare(pNode->nodeName(), "Directory") == 0) {
+ m_vDirectories.push_back(Directory(pNode, m_pServer, this));
+ } else if (Poco::icompare(pNode->nodeName(), "Video") == 0) {
+ m_vVideos.push_back(cVideo(pNode, m_pServer, this));
+ } else if (Poco::icompare(pNode->nodeName(), "Device") == 0) {
+ m_vDevices.push_back(Device(pNode, this));
+ } else if (Poco::icompare(pNode->nodeName(), "Playlist") == 0) {
+ m_vPlaylists.push_back(Playlist(pNode, this));
+ }
+
+ pNode = it.nextNode();
+ }
+
+ } catch (Exception &exc) {
+ std::cerr << exc.displayText() << std::endl;
+ }
+ }
+
+ std::string MediaContainer::ArtUri() {
+ if (m_sArt.find("http://") != std::string::npos) return m_sArt;
+ return m_pServer->GetUri() + m_sArt;
+ }
+
+ std::string MediaContainer::ThumbUri() {
+ if (m_sThumb.find("http://") != std::string::npos) return m_sThumb;
+ return m_pServer->GetUri() + m_sThumb;
+ }
#ifdef SKINDESIGNER
-void MediaContainer::PreCache()
-{
- bool foo;
- for(std::vector<plexclient::cVideo>::iterator it = m_vVideos.begin(); it != m_vVideos.end(); ++it) {
- if(!it->m_sThumb.empty()) cPictureCache::GetInstance().GetPath(it->ThumbUri(), 1280, 720, foo);
- if(!it->m_sArt.empty()) cPictureCache::GetInstance().GetPath(it->ArtUri(), 1920, 1080, foo);
- }
+
+ void MediaContainer::PreCache() {
+ bool foo;
+ for (std::vector<plexclient::cVideo>::iterator it = m_vVideos.begin(); it != m_vVideos.end(); ++it) {
+ if (!it->m_sThumb.empty()) cPictureCache::GetInstance().GetPath(it->ThumbUri(), 1280, 720, foo);
+ if (!it->m_sArt.empty()) cPictureCache::GetInstance().GetPath(it->ArtUri(), 1920, 1080, foo);
+ }
/* for(std::vector<plexclient::Directory>::iterator it = m_vDirectories.begin(); it != m_vDirectories.end(); ++it) {
if(!it->m_sThumb.empty()) cPictureCache::GetInstance().GetPath(it->ThumbUri(), 1280, 720, foo);
if(!it->m_sArt.empty()) cPictureCache::GetInstance().GetPath(it->ArtUri(), 1920, 1080, foo);
}*/
-}
+ }
+
#endif
}
diff --git a/MediaContainer.h b/MediaContainer.h
index c6cb14e..61e102d 100644
--- a/MediaContainer.h
+++ b/MediaContainer.h
@@ -31,56 +31,61 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
-class cVideo;
-class Directory;
-class Device;
-class Playlist;
-
-class MediaContainer: XmlObject
-{
-public:
- MediaContainer(std::istream *response, PlexServer* Server);
- MediaContainer(std::istream *response);
-
-protected:
-
-
-public:
- std::vector<Directory> m_vDirectories;
- std::vector<cVideo> m_vVideos;
- std::vector<Device> m_vDevices;
- std::vector<Playlist> m_vPlaylists;
-
- bool m_bAllowSync;
- std::string m_sArt;
- std::string m_sThumb;
- std::string m_sBanner;
- std::string m_sTitle;
- std::string m_sTitle1;
- std::string m_sTitle2;
- std::string m_sGrandparentTitle;
- MediaType m_eViewGroup;
- int m_iLibrarySectionID;
- std::string m_sLibrarySectionTitle;
- std::string m_sLibrarySectionUUID;
- std::string m_sMediaTagPrefix;
- int m_iSize;
- std::string m_sSummary;
- int m_iParentIndex;
- std::string m_sParentTitle;
- int m_iParentYear;
-
- PlexServer* m_pServer;
-
- std::string ThumbUri();
- std::string ArtUri();
+namespace plexclient {
+ class cVideo;
+
+ class Directory;
+
+ class Device;
+
+ class Playlist;
+
+ class MediaContainer : XmlObject {
+ public:
+ MediaContainer(std::istream *response, PlexServer *Server);
+
+ MediaContainer(std::istream *response);
+
+ protected:
+
+
+ public:
+ std::vector<Directory> m_vDirectories;
+ std::vector<cVideo> m_vVideos;
+ std::vector<Device> m_vDevices;
+ std::vector<Playlist> m_vPlaylists;
+
+ bool m_bAllowSync;
+ std::string m_sArt;
+ std::string m_sThumb;
+ std::string m_sBanner;
+ std::string m_sTitle;
+ std::string m_sTitle1;
+ std::string m_sTitle2;
+ std::string m_sGrandparentTitle;
+ MediaType m_eViewGroup;
+ int m_iLibrarySectionID;
+ std::string m_sLibrarySectionTitle;
+ std::string m_sLibrarySectionUUID;
+ std::string m_sMediaTagPrefix;
+ int m_iSize;
+ std::string m_sSummary;
+ int m_iParentIndex;
+ std::string m_sParentTitle;
+ int m_iParentYear;
+
+ PlexServer *m_pServer;
+
+ std::string ThumbUri();
+
+ std::string ArtUri();
#ifdef SKINDESIGNER
- void PreCache();
+
+ void PreCache();
+
#endif
-};
+ };
}
diff --git a/PVideo.cpp b/PVideo.cpp
index 0cac25f..4a6196b 100644
--- a/PVideo.cpp
+++ b/PVideo.cpp
@@ -8,366 +8,367 @@
#include "PlexHelper.h"
#include "tokendefinitions.h"
-namespace plexclient
-{
-
-cVideo::cVideo(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent)
-{
- m_iMyPlayOffset = 0;
- m_lViewoffset = 0;
- m_dRating = 0;
- m_pServer = Server;
- Parse(pNode);
-
- m_pParent = parent;
- if (m_iParentIndex < 0 && m_pParent) {
- m_iParentIndex = parent->m_iParentIndex;
- }
-}
-
-bool cVideo::UpdateFromServer()
-{
- try {
- Poco::URI fileuri(Poco::format("%s/library/metadata/%d?includeExtras=1", m_pServer->GetUri(), m_iRatingKey));
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
- PlexHelper::AddHttpHeader(request);
-
- Poco::Net::HTTPClientSession session(fileuri.getHost(), fileuri.getPort());
-
- session.sendRequest(request);
- Poco::Net::HTTPResponse response;
- std::istream &rs = session.receiveResponse(response);
-
- if(response.getStatus() == 200) {
- // clear vectors
- m_vCountry.clear();
- m_vDirector.clear();
- m_vGenre.clear();
- m_vRole.clear();
- m_vWriter.clear();
- m_vExtras.clear();
-
- InputSource src(rs);
- DOMParser parser;
- Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
-
- NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pNode = it.nextNode();
- while(pNode) {
- if(Poco::icompare(pNode->nodeName(), "Video") == 0) {
- Parse(pNode);
- break;
- }
-
- pNode = it.nextNode();
- }
- return true;
- }
- } catch (Poco::Exception &exc) {
- esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
- }
- return false;
-}
-
-void cVideo::Parse(Poco::XML::Node* pNode)
-{
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
-
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Video") == 0) {
-
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
-
- m_iRatingKey = GetNodeValueAsInt(pAttribs->getNamedItem("ratingKey"));
- m_iViewCount = GetNodeValueAsInt(pAttribs->getNamedItem("viewCount"));
- m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
- m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
- m_sKey = GetNodeValue(pAttribs->getNamedItem("key"));
- m_sStudio = GetNodeValue(pAttribs->getNamedItem("studio"));
- m_tType = GetNodeValueAsMediaType(pAttribs->getNamedItem("type"));
- m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
- m_sOriginalTitle = GetNodeValue(pAttribs->getNamedItem("originalTitle"));
- m_sGrandparentTitle = GetNodeValue(pAttribs->getNamedItem("grandparentTitle"));
- m_sContentRating = GetNodeValue(pAttribs->getNamedItem("contentRating"));
- m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
- m_sTagline = GetNodeValue(pAttribs->getNamedItem("tagline"));
- m_lViewoffset = GetNodeValueAsLong(pAttribs->getNamedItem("viewOffset"));
- m_tLastViewedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("lastViewedAt"));
- m_iYear = GetNodeValueAsInt(pAttribs->getNamedItem("year"));
- m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
- m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
- m_sGrandparentThumb = GetNodeValue(pAttribs->getNamedItem("grandparentThumb"));
- m_sGrandparentArt = GetNodeValue(pAttribs->getNamedItem("grandparentArt"));
- m_iDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
- m_dRating = GetNodeValueAsDouble(pAttribs->getNamedItem("rating"));
- m_tAddedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("addedAt"));
- m_tUpdatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("updatedAt"));
- m_tOriginallyAvailableAt = GetNodeValueAsDateTime(pAttribs->getNamedItem("originallyAvailableAt"));
- m_eExtraType = GetNodeValueAsExtraType(pAttribs->getNamedItem("extraType"));
-
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Media") == 0) {
- m_Media = Media(pChildNode);
- } else if(Poco::icompare(pChildNode->nodeName(), "Genre") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vGenre.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Writer") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vWriter.push_back(GetNodeValue(pChildNode));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Director") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vDirector.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Country") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vCountry.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Role") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_vRole.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
- pAttribs->release();
-
- } else if(Poco::icompare(pChildNode->nodeName(), "Collection") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
- m_sCollection = GetNodeValue(pAttribs->getNamedItem("tag"));
- pAttribs->release();
- } else if(Poco::icompare(pChildNode->nodeName(), "Extras") == 0) {
- ParseExtras(pChildNode);
- }
- pChildNode = it.nextNode();
- }
-}
-
-void cVideo::ParseExtras(Poco::XML::Node* pNode)
-{
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
-
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Video") == 0) {
- m_vExtras.push_back(cVideo(pChildNode, m_pServer, NULL));
- }
- pChildNode = it.nextNode();
- }
-}
-
-std::string cVideo::GetTitle()
-{
- std::string res = m_sTitle;
-
- std::string seriesTitle = m_sGrandparentTitle;
- if(seriesTitle.empty() && m_pParent)
- seriesTitle = m_pParent->m_sGrandparentTitle;
-
- switch(m_tType) {
- case MediaType::MOVIE:
- if(m_iYear > 0) {
- res = Poco::format("%s (%d)", m_sTitle, m_iYear);
- } else {
- res = m_sTitle;
- }
- break;
- case MediaType::EPISODE:
- res = Poco::format("%s - %02dx%02d - %s", seriesTitle, m_iParentIndex, m_iIndex, m_sTitle);
- break;
- default:
- break;
- }
- return res;
-}
-
-bool cVideo::SetStream(Stream* stream)
-{
- try {
- Poco::Net::HTTPClientSession session(m_pServer->GetHost(), m_pServer->GetPort());
-
- std::string uri = Poco::format("/library/parts/%d?%s&X-Plex-Token=%s", m_Media.m_iPartId, stream->GetSetStreamQuery(), m_pServer->GetAuthToken());
- Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri);
- session.sendRequest(req);
-
- Poco::Net::HTTPResponse resp;
- session.receiveResponse(resp);
-
- if(resp.getStatus() == 200) {
- dsyslog("[plex]: Set Stream: %s", uri.c_str());
- return true;
- }
- return false;
- } catch (Poco::Exception &exc) {
- esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
- return false;
- }
-}
-
-bool cVideo::SetUnwatched()
-{
- try {
- std::string uri = Poco::format("/:/unscrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey);
-
- bool ok;
- auto cSession = m_pServer->MakeRequest(ok, uri);
- Poco::Net::HTTPResponse resp;
- cSession->receiveResponse(resp);
-
- if(resp.getStatus() == 200) {
- dsyslog("[plex]: Set Unwatched: %s", uri.c_str());
- return true;
- }
- return false;
- } catch (Poco::Exception &exc) {
- esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
- return false;
- }
-}
-
-bool cVideo::SetWatched()
-{
- try {
- std::string uri = Poco::format("/:/scrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey);
-
- bool ok;
- auto cSession = m_pServer->MakeRequest(ok, uri);
-
- if(ok) {
- dsyslog("[plex]: Set Watched: %s", uri.c_str());
- return true;
- }
- return false;
- } catch (Poco::Exception &exc) {
- esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
- return false;
- }
-}
+namespace plexclient {
+
+ cVideo::cVideo(Poco::XML::Node *pNode, PlexServer *Server, MediaContainer *parent) {
+ m_iMyPlayOffset = 0;
+ m_lViewoffset = 0;
+ m_dRating = 0;
+ m_pServer = Server;
+ Parse(pNode);
+
+ m_pParent = parent;
+ if (m_iParentIndex < 0 && m_pParent) {
+ m_iParentIndex = parent->m_iParentIndex;
+ }
+ }
+
+ bool cVideo::UpdateFromServer() {
+ try {
+ Poco::URI fileuri(
+ Poco::format("%s/library/metadata/%d?includeExtras=1", m_pServer->GetUri(), m_iRatingKey));
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(),
+ Poco::Net::HTTPMessage::HTTP_1_1);
+ PlexHelper::AddHttpHeader(request);
+
+ Poco::Net::HTTPClientSession session(fileuri.getHost(), fileuri.getPort());
+
+ session.sendRequest(request);
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = session.receiveResponse(response);
+
+ if (response.getStatus() == 200) {
+ // clear vectors
+ m_vCountry.clear();
+ m_vDirector.clear();
+ m_vGenre.clear();
+ m_vRole.clear();
+ m_vWriter.clear();
+ m_vExtras.clear();
+
+ InputSource src(rs);
+ DOMParser parser;
+ Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
+
+ NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pNode = it.nextNode();
+ while (pNode) {
+ if (Poco::icompare(pNode->nodeName(), "Video") == 0) {
+ Parse(pNode);
+ break;
+ }
+
+ pNode = it.nextNode();
+ }
+ return true;
+ }
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
+ }
+ return false;
+ }
+
+ void cVideo::Parse(Poco::XML::Node *pNode) {
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
+
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Video") == 0) {
+
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
+
+ m_iRatingKey = GetNodeValueAsInt(pAttribs->getNamedItem("ratingKey"));
+ m_iViewCount = GetNodeValueAsInt(pAttribs->getNamedItem("viewCount"));
+ m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
+ m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
+ m_sKey = GetNodeValue(pAttribs->getNamedItem("key"));
+ m_sStudio = GetNodeValue(pAttribs->getNamedItem("studio"));
+ m_tType = GetNodeValueAsMediaType(pAttribs->getNamedItem("type"));
+ m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
+ m_sOriginalTitle = GetNodeValue(pAttribs->getNamedItem("originalTitle"));
+ m_sGrandparentTitle = GetNodeValue(pAttribs->getNamedItem("grandparentTitle"));
+ m_sContentRating = GetNodeValue(pAttribs->getNamedItem("contentRating"));
+ m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
+ m_sTagline = GetNodeValue(pAttribs->getNamedItem("tagline"));
+ m_lViewoffset = GetNodeValueAsLong(pAttribs->getNamedItem("viewOffset"));
+ m_tLastViewedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("lastViewedAt"));
+ m_iYear = GetNodeValueAsInt(pAttribs->getNamedItem("year"));
+ m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
+ m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
+ m_sGrandparentThumb = GetNodeValue(pAttribs->getNamedItem("grandparentThumb"));
+ m_sGrandparentArt = GetNodeValue(pAttribs->getNamedItem("grandparentArt"));
+ m_iDuration = GetNodeValueAsLong(pAttribs->getNamedItem("duration"));
+ m_dRating = GetNodeValueAsDouble(pAttribs->getNamedItem("rating"));
+ m_tAddedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("addedAt"));
+ m_tUpdatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("updatedAt"));
+ m_tOriginallyAvailableAt = GetNodeValueAsDateTime(pAttribs->getNamedItem("originallyAvailableAt"));
+ m_eExtraType = GetNodeValueAsExtraType(pAttribs->getNamedItem("extraType"));
+
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Media") == 0) {
+ m_Media = Media(pChildNode);
+ } else if (Poco::icompare(pChildNode->nodeName(), "Genre") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vGenre.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Writer") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vWriter.push_back(GetNodeValue(pChildNode));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Director") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vDirector.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Country") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vCountry.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Role") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_vRole.push_back(GetNodeValue(pAttribs->getNamedItem("tag")));
+ pAttribs->release();
+
+ } else if (Poco::icompare(pChildNode->nodeName(), "Collection") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+ m_sCollection = GetNodeValue(pAttribs->getNamedItem("tag"));
+ pAttribs->release();
+ } else if (Poco::icompare(pChildNode->nodeName(), "Extras") == 0) {
+ ParseExtras(pChildNode);
+ }
+ pChildNode = it.nextNode();
+ }
+ }
+
+ void cVideo::ParseExtras(Poco::XML::Node *pNode) {
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
+
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Video") == 0) {
+ m_vExtras.push_back(cVideo(pChildNode, m_pServer, NULL));
+ }
+ pChildNode = it.nextNode();
+ }
+ }
+
+ std::string cVideo::GetTitle() {
+ std::string res = m_sTitle;
+
+ std::string seriesTitle = m_sGrandparentTitle;
+ if (seriesTitle.empty() && m_pParent)
+ seriesTitle = m_pParent->m_sGrandparentTitle;
+
+ switch (m_tType) {
+ case MediaType::MOVIE:
+ if (m_iYear > 0) {
+ res = Poco::format("%s (%d)", m_sTitle, m_iYear);
+ } else {
+ res = m_sTitle;
+ }
+ break;
+ case MediaType::EPISODE:
+ res = Poco::format("%s - %02dx%02d - %s", seriesTitle, m_iParentIndex, m_iIndex, m_sTitle);
+ break;
+ default:
+ break;
+ }
+ return res;
+ }
+
+ bool cVideo::SetStream(Stream *stream) {
+ try {
+ Poco::Net::HTTPClientSession session(m_pServer->GetHost(), m_pServer->GetPort());
+
+ std::string uri = Poco::format("/library/parts/%d?%s&X-Plex-Token=%s", m_Media.m_iPartId,
+ stream->GetSetStreamQuery(), m_pServer->GetAuthToken());
+ Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri);
+ session.sendRequest(req);
+
+ Poco::Net::HTTPResponse resp;
+ session.receiveResponse(resp);
+
+ if (resp.getStatus() == 200) {
+ dsyslog("[plex]: Set Stream: %s", uri.c_str());
+ return true;
+ }
+ return false;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
+ return false;
+ }
+ }
+
+ bool cVideo::SetUnwatched() {
+ try {
+ std::string uri = Poco::format("/:/unscrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey);
+
+ bool ok;
+ auto cSession = m_pServer->MakeRequest(ok, uri);
+ Poco::Net::HTTPResponse resp;
+ cSession->receiveResponse(resp);
+
+ if (resp.getStatus() == 200) {
+ dsyslog("[plex]: Set Unwatched: %s", uri.c_str());
+ return true;
+ }
+ return false;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
+ return false;
+ }
+ }
+
+ bool cVideo::SetWatched() {
+ try {
+ std::string uri = Poco::format("/:/scrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey);
+
+ bool ok;
+ auto cSession = m_pServer->MakeRequest(ok, uri);
+
+ if (ok) {
+ dsyslog("[plex]: Set Watched: %s", uri.c_str());
+ return true;
+ }
+ return false;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]: %s: %s", __FUNCTION__, exc.displayText().c_str());
+ return false;
+ }
+ }
#ifdef SKINDESIGNER
-void cVideo::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached)
-{
- if(clear) grid->ClearTokens();
- grid->AddIntToken((int)(eTokenGridInt::viewmode), Config::GetInstance().DefaultViewMode);
- grid->AddStringToken((int)(eTokenGridStr::title), m_sTitle.c_str());
- grid->AddStringToken((int)(eTokenGridStr::orginaltitle), m_sOriginalTitle.c_str());
- grid->AddStringToken((int)(eTokenGridStr::summary), m_sSummary.c_str());
- grid->AddStringToken((int)(eTokenGridStr::tagline), m_sTagline.c_str());
- grid->AddStringToken((int)(eTokenGridStr::contentrating), m_sContentRating.c_str());
- grid->AddIntToken((int)(eTokenGridInt::rating), m_dRating*10);
- grid->AddStringToken((int)(eTokenGridStr::ratingstring), Poco::format("%.1f", m_dRating).c_str());
- grid->AddStringToken((int)(eTokenGridStr::studio), m_sStudio.c_str());
- grid->AddIntToken((int)(eTokenGridInt::viewCount), m_iViewCount);
- grid->AddIntToken((int)(eTokenGridInt::viewoffset), m_lViewoffset/1000/60);
- if(m_iDuration > 0) // avoid division by zero
- grid->AddIntToken((int)(eTokenGridInt::viewoffsetpercent), 100.0 / m_iDuration * m_lViewoffset);
- else
- grid->AddIntToken((int)(eTokenGridInt::viewoffsetpercent), 0);
- grid->AddIntToken((int)(eTokenGridInt::duration), m_iDuration/1000/60);
- grid->AddIntToken((int)(eTokenGridInt::year), m_iYear);
- if(m_pParent) grid->AddIntToken((int)(eTokenGridInt::viewgroup), (int)m_pParent->m_eViewGroup);
-
- // Thumb, Cover, Episodepicture
- bool cached = false;
- std::string thumb = cPictureCache::GetInstance().GetPath(ThumbUri(), Config::GetInstance().ThumbWidth(), Config::GetInstance().ThumbHeight(), cached, OnCached, this);
- grid->AddIntToken((int)(eTokenGridInt::hasthumb), cached);
- if (cached) grid->AddStringToken((int)(eTokenGridStr::thumb), thumb.c_str());
-
- // Fanart
- cached = false;
- std::string art = cPictureCache::GetInstance().GetPath(ArtUri(), Config::GetInstance().ArtWidth(), Config::GetInstance().ArtHeight(), cached);
- grid->AddIntToken((int)(eTokenGridInt::hasart), cached);
- if (cached) grid->AddStringToken((int)(eTokenGridStr::art), art.c_str());
-
- if(m_tType == MediaType::MOVIE) {
- grid->AddIntToken((int)(eTokenGridInt::ismovie), true);
- } else if (m_tType == MediaType::CLIP) {
- grid->AddIntToken((int)(eTokenGridInt::isclip), true);
- grid->AddIntToken((int)eTokenGridInt::extratype, (int)m_eExtraType);
- }
-
- vector<int> loopInfo;
- loopInfo.push_back(m_vRole.size());
- loopInfo.push_back(m_vGenre.size());
- grid->SetLoop(loopInfo);
-
- int actloopIndex = grid->GetLoopIndex("roles");
- int i = 0;
- for(auto it = m_vRole.begin(); it != m_vRole.end(); it++) {
- grid->AddLoopToken(actloopIndex, i, (int)(eTokenGridActorLst::roles), it->c_str());
- i++;
- }
-
- int genloopIndex = grid->GetLoopIndex("genres");
- i = 0;
- for(auto it = m_vGenre.begin(); it != m_vGenre.end(); it++) {
- grid->AddLoopToken(genloopIndex, i, (int)(eTokenGridGenresLst::genres), it->c_str());
- i++;
- }
-
- grid->AddIntToken((int)(eTokenGridInt::originallyAvailableYear), m_tOriginallyAvailableAt.year());
- grid->AddIntToken((int)(eTokenGridInt::originallyAvailableMonth), m_tOriginallyAvailableAt.month());
- grid->AddIntToken((int)(eTokenGridInt::originallyAvailableDay), m_tOriginallyAvailableAt.day());
-
- if(m_tType == MediaType::EPISODE) {
- grid->AddIntToken((int)(eTokenGridInt::isepisode), true);
- std::string seriesTitle = m_sGrandparentTitle;
- if(seriesTitle.empty() && m_pParent) seriesTitle = m_pParent->m_sGrandparentTitle;
- grid->AddStringToken((int)(eTokenGridStr::seriestitle), seriesTitle.c_str());
- grid->AddIntToken((int)(eTokenGridInt::season), m_iParentIndex);
- grid->AddIntToken((int)(eTokenGridInt::episode), m_iIndex);
-
- // Seriescover, Seasoncover
- cached = false;
- std::string grandparentthumbUri = m_sGrandparentThumb;
- if(grandparentthumbUri.empty() && m_pParent) {
- grandparentthumbUri = m_sThumb;
- }
- if(!grandparentthumbUri.empty()) {
- std::string grandparentThumb = cPictureCache::GetInstance().GetPath(m_pServer->GetUri() + grandparentthumbUri, Config::GetInstance().ThumbWidth(), Config::GetInstance().ThumbHeight(), cached, OnCached, this);
- if (cached) grid->AddStringToken((int)(eTokenGridStr::seriesthumb), grandparentThumb.c_str());
- }
- grid->AddIntToken((int)(eTokenGridInt::hasseriesthumb), cached);
-
- // Banner, Seriesbanner
- if(m_pParent && !m_pParent->m_sBanner.empty()) {
- cached = false;
- std::string banner = cPictureCache::GetInstance().GetPath(m_pServer->GetUri() + m_pParent->m_sBanner, Config::GetInstance().BannerWidth(), Config::GetInstance().BannerHeight(), cached, OnCached, this);
- if(cached) {
- grid->AddIntToken((int)(eTokenGridInt::hasbanner), cached);
- grid->AddStringToken((int)(eTokenGridStr::banner), banner.c_str());
- }
- }
- }
-
- m_Media.AddTokens(grid);
-}
+
+ void cVideo::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear,
+ std::function<void(cGridElement *)> OnCached) {
+ if (clear) grid->ClearTokens();
+ grid->AddIntToken((int) (eTokenGridInt::viewmode), Config::GetInstance().DefaultViewMode);
+ grid->AddStringToken((int) (eTokenGridStr::title), m_sTitle.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::orginaltitle), m_sOriginalTitle.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::summary), m_sSummary.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::tagline), m_sTagline.c_str());
+ grid->AddStringToken((int) (eTokenGridStr::contentrating), m_sContentRating.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::rating), m_dRating * 10);
+ grid->AddStringToken((int) (eTokenGridStr::ratingstring), Poco::format("%.1f", m_dRating).c_str());
+ grid->AddStringToken((int) (eTokenGridStr::studio), m_sStudio.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::viewCount), m_iViewCount);
+ grid->AddIntToken((int) (eTokenGridInt::viewoffset), m_lViewoffset / 1000 / 60);
+ if (m_iDuration > 0) // avoid division by zero
+ grid->AddIntToken((int) (eTokenGridInt::viewoffsetpercent), 100.0 / m_iDuration * m_lViewoffset);
+ else
+ grid->AddIntToken((int) (eTokenGridInt::viewoffsetpercent), 0);
+ grid->AddIntToken((int) (eTokenGridInt::duration), m_iDuration / 1000 / 60);
+ grid->AddIntToken((int) (eTokenGridInt::year), m_iYear);
+ if (m_pParent) grid->AddIntToken((int) (eTokenGridInt::viewgroup), (int) m_pParent->m_eViewGroup);
+
+ // Thumb, Cover, Episodepicture
+ bool cached = false;
+ std::string thumb = cPictureCache::GetInstance().GetPath(ThumbUri(), Config::GetInstance().ThumbWidth(),
+ Config::GetInstance().ThumbHeight(), cached, OnCached,
+ this);
+ grid->AddIntToken((int) (eTokenGridInt::hasthumb), cached);
+ if (cached) grid->AddStringToken((int) (eTokenGridStr::thumb), thumb.c_str());
+
+ // Fanart
+ cached = false;
+ std::string art = cPictureCache::GetInstance().GetPath(ArtUri(), Config::GetInstance().ArtWidth(),
+ Config::GetInstance().ArtHeight(), cached);
+ grid->AddIntToken((int) (eTokenGridInt::hasart), cached);
+ if (cached) grid->AddStringToken((int) (eTokenGridStr::art), art.c_str());
+
+ if (m_tType == MediaType::MOVIE) {
+ grid->AddIntToken((int) (eTokenGridInt::ismovie), true);
+ } else if (m_tType == MediaType::CLIP) {
+ grid->AddIntToken((int) (eTokenGridInt::isclip), true);
+ grid->AddIntToken((int) eTokenGridInt::extratype, (int) m_eExtraType);
+ }
+
+ vector<int> loopInfo;
+ loopInfo.push_back(m_vRole.size());
+ loopInfo.push_back(m_vGenre.size());
+ grid->SetLoop(loopInfo);
+
+ int actloopIndex = grid->GetLoopIndex("roles");
+ int i = 0;
+ for (auto it = m_vRole.begin(); it != m_vRole.end(); it++) {
+ grid->AddLoopToken(actloopIndex, i, (int) (eTokenGridActorLst::roles), it->c_str());
+ i++;
+ }
+
+ int genloopIndex = grid->GetLoopIndex("genres");
+ i = 0;
+ for (auto it = m_vGenre.begin(); it != m_vGenre.end(); it++) {
+ grid->AddLoopToken(genloopIndex, i, (int) (eTokenGridGenresLst::genres), it->c_str());
+ i++;
+ }
+
+ grid->AddIntToken((int) (eTokenGridInt::originallyAvailableYear), m_tOriginallyAvailableAt.year());
+ grid->AddIntToken((int) (eTokenGridInt::originallyAvailableMonth), m_tOriginallyAvailableAt.month());
+ grid->AddIntToken((int) (eTokenGridInt::originallyAvailableDay), m_tOriginallyAvailableAt.day());
+
+ if (m_tType == MediaType::EPISODE) {
+ grid->AddIntToken((int) (eTokenGridInt::isepisode), true);
+ std::string seriesTitle = m_sGrandparentTitle;
+ if (seriesTitle.empty() && m_pParent) seriesTitle = m_pParent->m_sGrandparentTitle;
+ grid->AddStringToken((int) (eTokenGridStr::seriestitle), seriesTitle.c_str());
+ grid->AddIntToken((int) (eTokenGridInt::season), m_iParentIndex);
+ grid->AddIntToken((int) (eTokenGridInt::episode), m_iIndex);
+
+ // Seriescover, Seasoncover
+ cached = false;
+ std::string grandparentthumbUri = m_sGrandparentThumb;
+ if (grandparentthumbUri.empty() && m_pParent) {
+ grandparentthumbUri = m_sThumb;
+ }
+ if (!grandparentthumbUri.empty()) {
+ std::string grandparentThumb = cPictureCache::GetInstance().GetPath(
+ m_pServer->GetUri() + grandparentthumbUri, Config::GetInstance().ThumbWidth(),
+ Config::GetInstance().ThumbHeight(), cached, OnCached, this);
+ if (cached) grid->AddStringToken((int) (eTokenGridStr::seriesthumb), grandparentThumb.c_str());
+ }
+ grid->AddIntToken((int) (eTokenGridInt::hasseriesthumb), cached);
+
+ // Banner, Seriesbanner
+ if (m_pParent && !m_pParent->m_sBanner.empty()) {
+ cached = false;
+ std::string banner = cPictureCache::GetInstance().GetPath(m_pServer->GetUri() + m_pParent->m_sBanner,
+ Config::GetInstance().BannerWidth(),
+ Config::GetInstance().BannerHeight(), cached,
+ OnCached, this);
+ if (cached) {
+ grid->AddIntToken((int) (eTokenGridInt::hasbanner), cached);
+ grid->AddStringToken((int) (eTokenGridStr::banner), banner.c_str());
+ }
+ }
+ }
+
+ m_Media.AddTokens(grid);
+ }
+
#endif
-std::string cVideo::ArtUri()
-{
- if(m_sArt.find("http://") != std::string::npos) return m_sArt;
- if(m_sArt[0] == '/') return m_pServer->GetUri() + m_sArt;
- return m_pServer->GetUri() + '/' + m_sArt;
-}
-
-std::string cVideo::ThumbUri()
-{
- if(m_sThumb.find("http://") != std::string::npos) return m_sThumb;
- if(m_sThumb[0] == '/') return m_pServer->GetUri() + m_sThumb;
- return m_pServer->GetUri() + '/' + m_sThumb;
-}
-
-std::string cVideo::GetSubtitleUrl()
-{
- // /video/:/transcode/universal/subtitles
- // Argument? m_sKey?
- //std::string subtitleUrl = m_pServer.GetUri() + "/video/:/transcode/universal/subtitles?" + Config::GetInstance().GetUUID();
- return "";
- // Format is "Mpeg4 Timed Text"
-}
+ std::string cVideo::ArtUri() {
+ if (m_sArt.find("http://") != std::string::npos) return m_sArt;
+ if (m_sArt[0] == '/') return m_pServer->GetUri() + m_sArt;
+ return m_pServer->GetUri() + '/' + m_sArt;
+ }
+
+ std::string cVideo::ThumbUri() {
+ if (m_sThumb.find("http://") != std::string::npos) return m_sThumb;
+ if (m_sThumb[0] == '/') return m_pServer->GetUri() + m_sThumb;
+ return m_pServer->GetUri() + '/' + m_sThumb;
+ }
+
+ std::string cVideo::GetSubtitleUrl() {
+ // /video/:/transcode/universal/subtitles
+ // Argument? m_sKey?
+ //std::string subtitleUrl = m_pServer.GetUri() + "/video/:/transcode/universal/subtitles?" + Config::GetInstance().GetUUID();
+ return "";
+ // Format is "Mpeg4 Timed Text"
+ }
} // Namespace
diff --git a/PVideo.h b/PVideo.h
index e806143..855cf26 100644
--- a/PVideo.h
+++ b/PVideo.h
@@ -17,9 +17,11 @@
#include <memory>
#ifdef SKINDESIGNER
- #include <libskindesignerapi/osdelements.h>
- #include "viewGridNavigator.h"
- #include "pictureCache.h"
+
+#include <libskindesignerapi/osdelements.h>
+#include "viewGridNavigator.h"
+#include "pictureCache.h"
+
#endif
#include "XmlObject.h"
@@ -35,79 +37,89 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
-class MediaContainer;
+namespace plexclient {
+ class MediaContainer;
-class cVideo: private XmlObject
+ class cVideo : private XmlObject
#ifdef SKINDESIGNER
-,public cGridElement
+ , public cGridElement
#endif
-{
-private:
- MediaContainer* m_pParent;
- void Parse(Poco::XML::Node* pNode);
- void ParseExtras(Poco::XML::Node* pNode);
-
-public:
- cVideo(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent);
- cVideo() {};
-
-public:
- int m_iRatingKey;
- std::string m_sKey;
- std::string m_sStudio;
- MediaType m_tType;
- std::string m_sTitle;
- std::string m_sOriginalTitle;
- std::string m_sGrandparentTitle;
- std::string m_sContentRating;
- std::string m_sSummary;
- std::string m_sTagline;
- long m_lViewoffset;
- Poco::Timestamp m_tLastViewedAt;
- int m_iYear;
- std::string m_sThumb;
- std::string m_sGrandparentThumb;
- std::string m_sArt;
- std::string m_sGrandparentArt;
- long m_iDuration;
- int m_iViewCount;
- double m_dRating;
- Poco::Timestamp m_tAddedAt;
- Poco::Timestamp m_tUpdatedAt;
- Poco::DateTime m_tOriginallyAvailableAt;
-
- std::vector<std::string> m_vGenre;
- std::vector<std::string> m_vWriter;
- std::vector<std::string> m_vDirector;
- std::vector<std::string> m_vCountry;
- std::vector<std::string> m_vRole;
- std::string m_sCollection;
- Media m_Media;
- PlexServer* m_pServer;
- int m_iMyPlayOffset;
- int m_iIndex;
- int m_iParentIndex;
- std::vector<cVideo> m_vExtras;
- ExtraType m_eExtraType;
-
- virtual std::string GetTitle();
- bool SetStream(Stream* stream);
- bool UpdateFromServer();
- bool SetWatched();
- bool SetUnwatched();
- std::string ThumbUri();
- std::string ArtUri();
-
- std::string GetSubtitleUrl();
-
+ {
+ private:
+ MediaContainer *m_pParent;
+
+ void Parse(Poco::XML::Node *pNode);
+
+ void ParseExtras(Poco::XML::Node *pNode);
+
+ public:
+ cVideo(Poco::XML::Node *pNode, PlexServer *Server, MediaContainer *parent);
+
+ cVideo() { };
+
+ public:
+ int m_iRatingKey;
+ std::string m_sKey;
+ std::string m_sStudio;
+ MediaType m_tType;
+ std::string m_sTitle;
+ std::string m_sOriginalTitle;
+ std::string m_sGrandparentTitle;
+ std::string m_sContentRating;
+ std::string m_sSummary;
+ std::string m_sTagline;
+ long m_lViewoffset;
+ Poco::Timestamp m_tLastViewedAt;
+ int m_iYear;
+ std::string m_sThumb;
+ std::string m_sGrandparentThumb;
+ std::string m_sArt;
+ std::string m_sGrandparentArt;
+ long m_iDuration;
+ int m_iViewCount;
+ double m_dRating;
+ Poco::Timestamp m_tAddedAt;
+ Poco::Timestamp m_tUpdatedAt;
+ Poco::DateTime m_tOriginallyAvailableAt;
+
+ std::vector<std::string> m_vGenre;
+ std::vector<std::string> m_vWriter;
+ std::vector<std::string> m_vDirector;
+ std::vector<std::string> m_vCountry;
+ std::vector<std::string> m_vRole;
+ std::string m_sCollection;
+ Media m_Media;
+ PlexServer *m_pServer;
+ int m_iMyPlayOffset;
+ int m_iIndex;
+ int m_iParentIndex;
+ std::vector<cVideo> m_vExtras;
+ ExtraType m_eExtraType;
+
+ virtual std::string GetTitle();
+
+ bool SetStream(Stream *stream);
+
+ bool UpdateFromServer();
+
+ bool SetWatched();
+
+ bool SetUnwatched();
+
+ std::string ThumbUri();
+
+ std::string ArtUri();
+
+ std::string GetSubtitleUrl();
+
#ifdef SKINDESIGNER
- // gridElement
- virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL);
-
+
+ // gridElement
+ virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true,
+ std::function<void(cGridElement *)> OnCached = NULL);
+
#endif
-};
+ };
}
diff --git a/PlexHTTPRequestHandler.cpp b/PlexHTTPRequestHandler.cpp
index 81f0628..a157087 100644
--- a/PlexHTTPRequestHandler.cpp
+++ b/PlexHTTPRequestHandler.cpp
@@ -8,294 +8,285 @@
#include "hlsPlayerControl.h"
#include "services.h"
-namespace plexclient
-{
-
-void PlexHTTPRequestHandler::AddHeaders(Poco::Net::HTTPServerResponse& response, Poco::Net::HTTPServerRequest& request)
-{
- if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
- response.setContentType("text/plain");
-
- response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- response.add("Connection", "Close");
- response.add("Access-Control-Max-Age", "1209600");
- response.add("Access-Control-Allow-Origin", "*");
- response.add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
- response.add("Access-Control-Allow-Headers",
- "x-plex-version, x-plex-platform-version, "
- "x-plex-username, x-plex-client-identifier, "
- "x-plex-target-client-identifier, x-plex-device-name, "
- "x-plex-platform, x-plex-product, accept, x-plex-device");
- } else {
- response.setContentType("application/x-www-form-urlencoded");
-
- response.add("Access-Control-Allow-Origin", "*");
- response.add("X-Plex-Version", VERSION);
- response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- response.add("X-Plex-Product", DESCRIPTION);
- response.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
- response.add("X-Plex-Platform", "VDR");
- response.add("X-Plex-Model", "Linux");
- response.add("X-Plex-Device", "PC");
- response.add("X-Plex-Username", Config::GetInstance().GetUsername());
- }
- // header.MessageHeader(header);
-}
-
-std::map<std::string, std::string> PlexHTTPRequestHandler::ParseQuery(std::string query)
-{
- std::map<std::string, std::string> querymap;
- Poco::StringTokenizer queryTokens(query, "&");
- for(Poco::StringTokenizer::Iterator token = queryTokens.begin(); token != queryTokens.end(); token++) {
- int pos = token->find("=");
- querymap[token->substr(0, pos)] = token->substr(pos+1, std::string::npos);
- }
- return querymap;
-}
-
-std::string PlexHTTPRequestHandler::GetOKMsg()
-{
- return "<?xml version=\"1.0\" encoding=\"utf-8\"?> <Response code=\"200\" status=\"OK\" />";
-}
-
-void PlexHTTPRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request,
- Poco::Net::HTTPServerResponse& response)
-{
- response.send() << " "; // Stream must not be empty!
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_NOT_FOUND);
-}
-
-void PlexHTTPRequestHandler::UpdateCommandId(Poco::Net::HTTPServerRequest& request)
-{
- Poco::URI uri(request.getURI());
- std::map<std::string, std::string> query = ParseQuery(uri.getQuery()); // port=32400&commandID=0&protocol=http
-
- std::string uuid = request.get("X-Plex-Client-Identifier", "");
- if(uuid.length() != 0) {
- std::string command = query["commandID"];
- SubscriptionManager::GetInstance().UpdateSubscriber(uuid, command);
- }
-}
-
-void SubscribeRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request,
- Poco::Net::HTTPServerResponse& response)
-{
- UpdateCommandId(request);
- Poco::URI uri(request.getURI());
- std::map<std::string, std::string> query = ParseQuery(uri.getQuery());
-
- if(query.find("wait") != query.end() && atoi(query["wait"].c_str()) == 1) {
- usleep(900 * 1000);
- }
-
- if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
- AddHeaders(response, request);
- response.send() << " "; // Stream must not be empty!
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
- return;
- }
-
- // parse query
- if(request.getURI().find("/subscribe") != std::string::npos) {
- Subscribe(request);
- AddHeaders(response, request);
- response.send() << GetOKMsg();
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
- } else if(request.getURI().find("/unsubscribe") != std::string::npos) {
- Unsubscribe(request);
- AddHeaders(response, request);
- response.send() << GetOKMsg();
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
- } else if(request.getURI().find("/poll") != std::string::npos) {
- response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- response.add("Access-Control-Expose-Headers", "X-Plex-Client-Identifier");
- response.add("Access-Control-Allow-Origin", "*");
- response.setContentType("text/xml");
- response.send() << SubscriptionManager::GetInstance().GetMsg(query["commandID"]);
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
- }
-}
-
-void SubscribeRequestHandler::Subscribe(Poco::Net::HTTPServerRequest& request)
-{
- Poco::URI uri(request.getURI());
- std::map<std::string, std::string> query = ParseQuery(uri.getQuery()); // port=32400&commandID=0&protocol=http
-
- std::string uuid = request.get("X-Plex-Client-Identifier", "");
- if(uuid.length() != 0) {
- int port = atoi(query["port"].c_str());
- std::string command = query["commandID"];
-
- SubscriptionManager::GetInstance().AddSubscriber(
- Subscriber(query["protocol"], request.clientAddress().host().toString(), port, uuid, command));
- }
-}
-
-void SubscribeRequestHandler::Unsubscribe(Poco::Net::HTTPServerRequest& request)
-{
- std::string uuid = request.get("X-Plex-Client-Identifier", "");
- if(uuid.length() != 0) {
- SubscriptionManager::GetInstance().RemoveSubscriber(uuid);
- }
-}
-
-void ResourceRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request,
- Poco::Net::HTTPServerResponse& response)
-{
- UpdateCommandId(request);
- AddHeaders(response, request);
-
- std::ostream& ostr = response.send();
- ostr << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- "<MediaContainer>"
- "<Player title=\"" << Config::GetInstance().GetHostname() << "\""
- " protocol=\"plex\""
- " protocolVersion=\"1\""
- " protocolCapabilities=\"navigation,playback,timeline\""
- " machineIdentifier=\"" << Config::GetInstance().GetUUID() << "\""
- " product=\"" << DESCRIPTION << "\""
- " platform=\"Linux\""
- " platformVersion=\"" << VERSION << "\""
- " deviceClass=\"HTPC\""
- "/> </MediaContainer>";
-
- response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
-
- // dsyslog("[plex]Resources Response sent...");
-}
-
-void PlayerRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
-{
- try {
- UpdateCommandId(request);
-
- Poco::URI uri(request.getURI());
- std::map<std::string, std::string> query = ParseQuery(uri.getQuery());
-
- if(query.find("wait") != query.end() && atoi(query["wait"].c_str()) == 1) {
- usleep(900 * 1000);
- }
-
- if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
- AddHeaders(response, request);
- response.send() << " "; // Stream must not be empty!
- return;
- }
-
- if(request.getURI().find("/poll") != std::string::npos) {
- response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- response.add("Access-Control-Expose-Headers", "X-Plex-Client-Identifier");
- response.add("Access-Control-Allow-Origin", "*");
- response.setContentType("text/xml");
- std::ostream& ostr = response.send();
- ostr << SubscriptionManager::GetInstance().GetMsg(query["commandID"]);
-
- } else if(request.getURI().find("/navigation") != std::string::npos) {
- if(request.getURI().find("/moveUp") != std::string::npos) {
- cRemote::Put(kUp);
- } else if(request.getURI().find("/moveDown") != std::string::npos) {
- cRemote::Put(kDown);
- } else if(request.getURI().find("/moveLeft") != std::string::npos) {
- cRemote::Put(kLeft);
- } else if(request.getURI().find("/moveRight") != std::string::npos) {
- cRemote::Put(kRight);
- } else if(request.getURI().find("/select") != std::string::npos) {
- cRemote::Put(kOk);
- } else if(request.getURI().find("/home") != std::string::npos) {
- cRemote::Put(kMenu);
- } else if(request.getURI().find("/back") != std::string::npos) {
- cRemote::Put(kBack);
- }
- response.send() << GetOKMsg();
-
- } else if(request.getURI().find("/playback") != std::string::npos) {
- if(request.getURI().find("/playback/seekTo") != std::string::npos) {
- cHlsPlayerControl* control = dynamic_cast<cHlsPlayerControl*>(cControl::Control(true));
- if(query.find("offset") != query.end()) {
- int offset = atoi(query["offset"].c_str()) / 1000;
- if(control) {
- isyslog("[plex] Seeking to %d", offset);
- control->SeekTo(offset);
- } else if(cMyPlugin::PlayingFile) {
- cPlugin* mpvPlugin = cPluginManager::GetPlugin("mpv");
- if(mpvPlugin) {
- Mpv_Seek seekData;
- seekData.SeekAbsolute = offset;
- seekData.SeekRelative = 0;
- mpvPlugin->Service(MPV_SEEK, &seekData);
- }
- }
- }
- } else if(request.getURI().find("/playback/playMedia") != std::string::npos) {
- AddHeaders(response, request);
- std::string protocol = query["protocol"];
- std::string address = query["address"];
- std::string port = query["port"];
- std::string key = query["key"];
-
- std::string fullUrl = protocol + "://" + address + ":" + port + key; // Metainfo
- auto Cont = Plexservice::GetMediaContainer(fullUrl);
-
- // Check for video
- if(Cont && Cont->m_vVideos.size() > 0) {
- // MUSS im Maintread des Plugins/VDR gestartet werden
- if(query.find("offset") != query.end()) {
- Cont->m_vVideos[0].m_iMyPlayOffset = atoi(query["offset"].c_str()) / 1000;
- if(Cont->m_vVideos[0].m_iMyPlayOffset == 0) {
- Cont->m_vVideos[0].m_iMyPlayOffset = -1;
- }
-
- }
-
- ActionManager::GetInstance().AddAction(Cont->m_vVideos[0]);
- }
- } else if(request.getURI().find("/playback/play") != std::string::npos) {
- cRemote::Put(kPlay);
- } else if(request.getURI().find("/playback/pause") != std::string::npos) {
- cRemote::Put(kPause);
- } else if(request.getURI().find("/playback/stop") != std::string::npos) {
- cRemote::Put(kStop);
- } else if(request.getURI().find("/playback/stepForward") != std::string::npos) {
- cHlsPlayerControl* control = dynamic_cast<cHlsPlayerControl*>(cControl::Control(true));
- if(control) {
- control->JumpRelative(30);
- } else if(cMyPlugin::PlayingFile) {
- cPlugin* mpvPlugin = cPluginManager::GetPlugin("mpv");
- if(mpvPlugin) {
- Mpv_Seek seekData;
- seekData.SeekAbsolute = 0;
- seekData.SeekRelative = 30;
- mpvPlugin->Service(MPV_SEEK, &seekData);
- }
- } else
- cRemote::Put(kFastFwd);
- } else if(request.getURI().find("/playback/stepBack") != std::string::npos) {
- cHlsPlayerControl* control = dynamic_cast<cHlsPlayerControl*>(cControl::Control(true));
- if(control) {
- control->JumpRelative(-15);
- }else if(cMyPlugin::PlayingFile) {
- cPlugin* mpvPlugin = cPluginManager::GetPlugin("mpv");
- if(mpvPlugin) {
- Mpv_Seek seekData;
- seekData.SeekAbsolute = 0;
- seekData.SeekRelative = -15;
- mpvPlugin->Service(MPV_SEEK, &seekData);
- }
- } else
- cRemote::Put(kFastRew);
- } else if(request.getURI().find("/playback/skipNext") != std::string::npos) {
- cRemote::Put(kFastFwd);
- } else if(request.getURI().find("/playback/skipPrevious") != std::string::npos) {
- cRemote::Put(kFastRew);
- }
-
- SubscriptionManager::GetInstance().Notify();
- response.send() << GetOKMsg();
- }
-
- } catch(Poco::Exception& e) {
- std::cerr << e.displayText() << std::endl;
- }
-}
+namespace plexclient {
+
+ void PlexHTTPRequestHandler::AddHeaders(Poco::Net::HTTPServerResponse &response,
+ Poco::Net::HTTPServerRequest &request) {
+ if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
+ response.setContentType("text/plain");
+
+ response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ response.add("Connection", "Close");
+ response.add("Access-Control-Max-Age", "1209600");
+ response.add("Access-Control-Allow-Origin", "*");
+ response.add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
+ response.add("Access-Control-Allow-Headers",
+ "x-plex-version, x-plex-platform-version, "
+ "x-plex-username, x-plex-client-identifier, "
+ "x-plex-target-client-identifier, x-plex-device-name, "
+ "x-plex-platform, x-plex-product, accept, x-plex-device");
+ } else {
+ response.setContentType("application/x-www-form-urlencoded");
+
+ response.add("Access-Control-Allow-Origin", "*");
+ response.add("X-Plex-Version", VERSION);
+ response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ response.add("X-Plex-Product", DESCRIPTION);
+ response.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
+ response.add("X-Plex-Platform", "VDR");
+ response.add("X-Plex-Model", "Linux");
+ response.add("X-Plex-Device", "PC");
+ response.add("X-Plex-Username", Config::GetInstance().GetUsername());
+ }
+ // header.MessageHeader(header);
+ }
+
+ std::map<std::string, std::string> PlexHTTPRequestHandler::ParseQuery(std::string query) {
+ std::map<std::string, std::string> querymap;
+ Poco::StringTokenizer queryTokens(query, "&");
+ for (Poco::StringTokenizer::Iterator token = queryTokens.begin(); token != queryTokens.end(); token++) {
+ int pos = token->find("=");
+ querymap[token->substr(0, pos)] = token->substr(pos + 1, std::string::npos);
+ }
+ return querymap;
+ }
+
+ std::string PlexHTTPRequestHandler::GetOKMsg() {
+ return "<?xml version=\"1.0\" encoding=\"utf-8\"?> <Response code=\"200\" status=\"OK\" />";
+ }
+
+ void PlexHTTPRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
+ Poco::Net::HTTPServerResponse &response) {
+ response.send() << " "; // Stream must not be empty!
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_NOT_FOUND);
+ }
+
+ void PlexHTTPRequestHandler::UpdateCommandId(Poco::Net::HTTPServerRequest &request) {
+ Poco::URI uri(request.getURI());
+ std::map<std::string, std::string> query = ParseQuery(uri.getQuery()); // port=32400&commandID=0&protocol=http
+
+ std::string uuid = request.get("X-Plex-Client-Identifier", "");
+ if (uuid.length() != 0) {
+ std::string command = query["commandID"];
+ SubscriptionManager::GetInstance().UpdateSubscriber(uuid, command);
+ }
+ }
+
+ void SubscribeRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
+ Poco::Net::HTTPServerResponse &response) {
+ UpdateCommandId(request);
+ Poco::URI uri(request.getURI());
+ std::map<std::string, std::string> query = ParseQuery(uri.getQuery());
+
+ if (query.find("wait") != query.end() && atoi(query["wait"].c_str()) == 1) {
+ usleep(900 * 1000);
+ }
+
+ if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
+ AddHeaders(response, request);
+ response.send() << " "; // Stream must not be empty!
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
+ return;
+ }
+
+ // parse query
+ if (request.getURI().find("/subscribe") != std::string::npos) {
+ Subscribe(request);
+ AddHeaders(response, request);
+ response.send() << GetOKMsg();
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
+ } else if (request.getURI().find("/unsubscribe") != std::string::npos) {
+ Unsubscribe(request);
+ AddHeaders(response, request);
+ response.send() << GetOKMsg();
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
+ } else if (request.getURI().find("/poll") != std::string::npos) {
+ response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ response.add("Access-Control-Expose-Headers", "X-Plex-Client-Identifier");
+ response.add("Access-Control-Allow-Origin", "*");
+ response.setContentType("text/xml");
+ response.send() << SubscriptionManager::GetInstance().GetMsg(query["commandID"]);
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
+ }
+ }
+
+ void SubscribeRequestHandler::Subscribe(Poco::Net::HTTPServerRequest &request) {
+ Poco::URI uri(request.getURI());
+ std::map<std::string, std::string> query = ParseQuery(uri.getQuery()); // port=32400&commandID=0&protocol=http
+
+ std::string uuid = request.get("X-Plex-Client-Identifier", "");
+ if (uuid.length() != 0) {
+ int port = atoi(query["port"].c_str());
+ std::string command = query["commandID"];
+
+ SubscriptionManager::GetInstance().AddSubscriber(
+ Subscriber(query["protocol"], request.clientAddress().host().toString(), port, uuid, command));
+ }
+ }
+
+ void SubscribeRequestHandler::Unsubscribe(Poco::Net::HTTPServerRequest &request) {
+ std::string uuid = request.get("X-Plex-Client-Identifier", "");
+ if (uuid.length() != 0) {
+ SubscriptionManager::GetInstance().RemoveSubscriber(uuid);
+ }
+ }
+
+ void ResourceRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
+ Poco::Net::HTTPServerResponse &response) {
+ UpdateCommandId(request);
+ AddHeaders(response, request);
+
+ std::ostream &ostr = response.send();
+ ostr << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<MediaContainer>"
+ "<Player title=\"" << Config::GetInstance().GetHostname() << "\""
+ " protocol=\"plex\""
+ " protocolVersion=\"1\""
+ " protocolCapabilities=\"navigation,playback,timeline\""
+ " machineIdentifier=\"" << Config::GetInstance().GetUUID() << "\""
+ " product=\"" << DESCRIPTION << "\""
+ " platform=\"Linux\""
+ " platformVersion=\"" << VERSION << "\""
+ " deviceClass=\"HTPC\""
+ "/> </MediaContainer>";
+
+ response.setStatus(Poco::Net::HTTPResponse::HTTP_REASON_OK);
+
+ // dsyslog("[plex]Resources Response sent...");
+ }
+
+ void PlayerRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
+ Poco::Net::HTTPServerResponse &response) {
+ try {
+ UpdateCommandId(request);
+
+ Poco::URI uri(request.getURI());
+ std::map<std::string, std::string> query = ParseQuery(uri.getQuery());
+
+ if (query.find("wait") != query.end() && atoi(query["wait"].c_str()) == 1) {
+ usleep(900 * 1000);
+ }
+
+ if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
+ AddHeaders(response, request);
+ response.send() << " "; // Stream must not be empty!
+ return;
+ }
+
+ if (request.getURI().find("/poll") != std::string::npos) {
+ response.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ response.add("Access-Control-Expose-Headers", "X-Plex-Client-Identifier");
+ response.add("Access-Control-Allow-Origin", "*");
+ response.setContentType("text/xml");
+ std::ostream &ostr = response.send();
+ ostr << SubscriptionManager::GetInstance().GetMsg(query["commandID"]);
+
+ } else if (request.getURI().find("/navigation") != std::string::npos) {
+ if (request.getURI().find("/moveUp") != std::string::npos) {
+ cRemote::Put(kUp);
+ } else if (request.getURI().find("/moveDown") != std::string::npos) {
+ cRemote::Put(kDown);
+ } else if (request.getURI().find("/moveLeft") != std::string::npos) {
+ cRemote::Put(kLeft);
+ } else if (request.getURI().find("/moveRight") != std::string::npos) {
+ cRemote::Put(kRight);
+ } else if (request.getURI().find("/select") != std::string::npos) {
+ cRemote::Put(kOk);
+ } else if (request.getURI().find("/home") != std::string::npos) {
+ cRemote::Put(kMenu);
+ } else if (request.getURI().find("/back") != std::string::npos) {
+ cRemote::Put(kBack);
+ }
+ response.send() << GetOKMsg();
+
+ } else if (request.getURI().find("/playback") != std::string::npos) {
+ if (request.getURI().find("/playback/seekTo") != std::string::npos) {
+ cHlsPlayerControl *control = dynamic_cast<cHlsPlayerControl *>(cControl::Control(true));
+ if (query.find("offset") != query.end()) {
+ int offset = atoi(query["offset"].c_str()) / 1000;
+ if (control) {
+ isyslog("[plex] Seeking to %d", offset);
+ control->SeekTo(offset);
+ } else if (cMyPlugin::PlayingFile) {
+ cPlugin *mpvPlugin = cPluginManager::GetPlugin("mpv");
+ if (mpvPlugin) {
+ Mpv_Seek seekData;
+ seekData.SeekAbsolute = offset;
+ seekData.SeekRelative = 0;
+ mpvPlugin->Service(MPV_SEEK, &seekData);
+ }
+ }
+ }
+ } else if (request.getURI().find("/playback/playMedia") != std::string::npos) {
+ AddHeaders(response, request);
+ std::string protocol = query["protocol"];
+ std::string address = query["address"];
+ std::string port = query["port"];
+ std::string key = query["key"];
+
+ std::string fullUrl = protocol + "://" + address + ":" + port + key; // Metainfo
+ auto Cont = Plexservice::GetMediaContainer(fullUrl);
+
+ // Check for video
+ if (Cont && Cont->m_vVideos.size() > 0) {
+ // MUSS im Maintread des Plugins/VDR gestartet werden
+ if (query.find("offset") != query.end()) {
+ Cont->m_vVideos[0].m_iMyPlayOffset = atoi(query["offset"].c_str()) / 1000;
+ if (Cont->m_vVideos[0].m_iMyPlayOffset == 0) {
+ Cont->m_vVideos[0].m_iMyPlayOffset = -1;
+ }
+
+ }
+
+ ActionManager::GetInstance().AddAction(Cont->m_vVideos[0]);
+ }
+ } else if (request.getURI().find("/playback/play") != std::string::npos) {
+ cRemote::Put(kPlay);
+ } else if (request.getURI().find("/playback/pause") != std::string::npos) {
+ cRemote::Put(kPause);
+ } else if (request.getURI().find("/playback/stop") != std::string::npos) {
+ cRemote::Put(kStop);
+ } else if (request.getURI().find("/playback/stepForward") != std::string::npos) {
+ cHlsPlayerControl *control = dynamic_cast<cHlsPlayerControl *>(cControl::Control(true));
+ if (control) {
+ control->JumpRelative(30);
+ } else if (cMyPlugin::PlayingFile) {
+ cPlugin *mpvPlugin = cPluginManager::GetPlugin("mpv");
+ if (mpvPlugin) {
+ Mpv_Seek seekData;
+ seekData.SeekAbsolute = 0;
+ seekData.SeekRelative = 30;
+ mpvPlugin->Service(MPV_SEEK, &seekData);
+ }
+ } else
+ cRemote::Put(kFastFwd);
+ } else if (request.getURI().find("/playback/stepBack") != std::string::npos) {
+ cHlsPlayerControl *control = dynamic_cast<cHlsPlayerControl *>(cControl::Control(true));
+ if (control) {
+ control->JumpRelative(-15);
+ } else if (cMyPlugin::PlayingFile) {
+ cPlugin *mpvPlugin = cPluginManager::GetPlugin("mpv");
+ if (mpvPlugin) {
+ Mpv_Seek seekData;
+ seekData.SeekAbsolute = 0;
+ seekData.SeekRelative = -15;
+ mpvPlugin->Service(MPV_SEEK, &seekData);
+ }
+ } else
+ cRemote::Put(kFastRew);
+ } else if (request.getURI().find("/playback/skipNext") != std::string::npos) {
+ cRemote::Put(kFastFwd);
+ } else if (request.getURI().find("/playback/skipPrevious") != std::string::npos) {
+ cRemote::Put(kFastRew);
+ }
+
+ SubscriptionManager::GetInstance().Notify();
+ response.send() << GetOKMsg();
+ }
+
+ } catch (Poco::Exception &e) {
+ std::cerr << e.displayText() << std::endl;
+ }
+ }
} // namespace
diff --git a/PlexHTTPRequestHandler.h b/PlexHTTPRequestHandler.h
index 2787e18..9f0d69f 100644
--- a/PlexHTTPRequestHandler.h
+++ b/PlexHTTPRequestHandler.h
@@ -23,41 +23,40 @@
#include "plexgdm.h"
+namespace plexclient {
-namespace plexclient
-{
-
-class PlexHTTPRequestHandler : public Poco::Net::HTTPRequestHandler
-{
-public:
- virtual void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
-
-protected:
- std::string GetOKMsg();
- void AddHeaders(Poco::Net::HTTPServerResponse& response, Poco::Net::HTTPServerRequest& request);
- std::map<std::string, std::string> ParseQuery(std::string query);
- void UpdateCommandId(Poco::Net::HTTPServerRequest& request);
-};
-
-class SubscribeRequestHandler : public PlexHTTPRequestHandler
-{
-public:
- virtual void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
- void Subscribe(Poco::Net::HTTPServerRequest& request);
- void Unsubscribe(Poco::Net::HTTPServerRequest& request);
-};
-
-class ResourceRequestHandler : public PlexHTTPRequestHandler
-{
-public:
- virtual void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
-};
-
-class PlayerRequestHandler : public PlexHTTPRequestHandler
-{
-public:
- virtual void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
-};
+ class PlexHTTPRequestHandler : public Poco::Net::HTTPRequestHandler {
+ public:
+ virtual void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
+
+ protected:
+ std::string GetOKMsg();
+
+ void AddHeaders(Poco::Net::HTTPServerResponse &response, Poco::Net::HTTPServerRequest &request);
+
+ std::map<std::string, std::string> ParseQuery(std::string query);
+
+ void UpdateCommandId(Poco::Net::HTTPServerRequest &request);
+ };
+
+ class SubscribeRequestHandler : public PlexHTTPRequestHandler {
+ public:
+ virtual void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
+
+ void Subscribe(Poco::Net::HTTPServerRequest &request);
+
+ void Unsubscribe(Poco::Net::HTTPServerRequest &request);
+ };
+
+ class ResourceRequestHandler : public PlexHTTPRequestHandler {
+ public:
+ virtual void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
+ };
+
+ class PlayerRequestHandler : public PlexHTTPRequestHandler {
+ public:
+ virtual void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
+ };
}
diff --git a/PlexHelper.cpp b/PlexHelper.cpp
index 61643d7..97bb7fa 100644
--- a/PlexHelper.cpp
+++ b/PlexHelper.cpp
@@ -2,24 +2,23 @@
#include "Config.h"
#include "plex.h"
-namespace plexclient
-{
+namespace plexclient {
-void PlexHelper::AddHttpHeader(Poco::Net::HTTPRequest& request)
-{
- request.add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
+ void PlexHelper::AddHttpHeader(Poco::Net::HTTPRequest &request) {
+ request.add("User-Agent",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
- //request.add("X-Plex-Client-Capabilities", "protocols=shoutcast,http-video;videoDecoders=h264{profile:high&resolution:1080&level:51};audioDecoders=mp3,aac");
- request.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- request.add("X-Plex-Device", "PC");
- request.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
- request.add("X-Plex-Language", Config::GetInstance().GetLanguage());
- request.add("X-Plex-Model", "Linux");
- request.add("X-Plex-Platform", "VDR");
- request.add("X-Plex-Product", "plex for vdr");
- request.add("X-Plex-Provides", "player");
- request.add("X-Plex-Version", VERSION);
-}
+ //request.add("X-Plex-Client-Capabilities", "protocols=shoutcast,http-video;videoDecoders=h264{profile:high&resolution:1080&level:51};audioDecoders=mp3,aac");
+ request.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ request.add("X-Plex-Device", "PC");
+ request.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
+ request.add("X-Plex-Language", Config::GetInstance().GetLanguage());
+ request.add("X-Plex-Model", "Linux");
+ request.add("X-Plex-Platform", "VDR");
+ request.add("X-Plex-Product", "plex for vdr");
+ request.add("X-Plex-Provides", "player");
+ request.add("X-Plex-Version", VERSION);
+ }
} // namespace
diff --git a/PlexHelper.h b/PlexHelper.h
index 0df6eaf..3c77987 100644
--- a/PlexHelper.h
+++ b/PlexHelper.h
@@ -3,17 +3,16 @@
#include <Poco/Net/HTTPRequest.h>
-namespace plexclient
-{
+namespace plexclient {
-class PlexHelper
-{
-public:
- static void AddHttpHeader(Poco::Net::HTTPRequest& request);
-private:
- PlexHelper() {};
+ class PlexHelper {
+ public:
+ static void AddHttpHeader(Poco::Net::HTTPRequest &request);
-};
+ private:
+ PlexHelper() { };
+
+ };
}
diff --git a/PlexReqHandlerFactory.cpp b/PlexReqHandlerFactory.cpp
index dacdff7..c1d9401 100644
--- a/PlexReqHandlerFactory.cpp
+++ b/PlexReqHandlerFactory.cpp
@@ -1,18 +1,15 @@
#include "PlexReqHandlerFactory.h"
-namespace plexclient
-{
+namespace plexclient {
-PlexReqHandlerFactory::PlexReqHandlerFactory()
-{
-}
+ PlexReqHandlerFactory::PlexReqHandlerFactory() {
+ }
-PlexReqHandlerFactory::~PlexReqHandlerFactory()
-{
-}
+ PlexReqHandlerFactory::~PlexReqHandlerFactory() {
+ }
-Poco::Net::HTTPRequestHandler* PlexReqHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)
-{ /*
+ Poco::Net::HTTPRequestHandler *PlexReqHandlerFactory::createRequestHandler(
+ const Poco::Net::HTTPServerRequest &request) { /*
if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
std::cout << "GET Request: " << request.getURI() << " from: " << request.clientAddress().toString() << std::endl;
} else if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
@@ -24,11 +21,11 @@ Poco::Net::HTTPRequestHandler* PlexReqHandlerFactory::createRequestHandler(const
std::cout << "??? Request: " << request.getURI() << " from: " << request.clientAddress().toString() << std::endl;
}
*/
- if(request.getURI().find("/player/timeline")!= std::string::npos) return new SubscribeRequestHandler();
- else if(request.getURI().find("/resources")!= std::string::npos) return new ResourceRequestHandler();
- else if(request.getURI().find("/player")!= std::string::npos) return new PlayerRequestHandler();
+ if (request.getURI().find("/player/timeline") != std::string::npos) return new SubscribeRequestHandler();
+ else if (request.getURI().find("/resources") != std::string::npos) return new ResourceRequestHandler();
+ else if (request.getURI().find("/player") != std::string::npos) return new PlayerRequestHandler();
- return new PlexHTTPRequestHandler();
-}
+ return new PlexHTTPRequestHandler();
+ }
}
diff --git a/PlexReqHandlerFactory.h b/PlexReqHandlerFactory.h
index 82ceb8a..15c97ef 100644
--- a/PlexReqHandlerFactory.h
+++ b/PlexReqHandlerFactory.h
@@ -9,18 +9,17 @@
#include "Config.h"
-namespace plexclient
-{
-
-class PlexReqHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
-{
-public:
- PlexReqHandlerFactory();
- ~PlexReqHandlerFactory();
-
-public:
- virtual Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
-};
+namespace plexclient {
+
+ class PlexReqHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
+ public:
+ PlexReqHandlerFactory();
+
+ ~PlexReqHandlerFactory();
+
+ public:
+ virtual Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &request);
+ };
}
diff --git a/PlexServer.cpp b/PlexServer.cpp
index 42db999..8e49805 100644
--- a/PlexServer.cpp
+++ b/PlexServer.cpp
@@ -3,149 +3,142 @@
#include "Config.h"
#include "plex.h"
-namespace plexclient
-{
-
-PlexServer::PlexServer(std::string ip, int port)
-{
- Poco::URI uri;
- uri.setHost(ip);
- uri.setPort(port);
- uri.setScheme("http");
- m_uri = uri.toString();
- Offline = false;
-}
+namespace plexclient {
-PlexServer::PlexServer(std::string data, std::string ip)
-{
- ParseData(data, ip);
-}
+ PlexServer::PlexServer(std::string ip, int port) {
+ Poco::URI uri;
+ uri.setHost(ip);
+ uri.setPort(port);
+ uri.setScheme("http");
+ m_uri = uri.toString();
+ Offline = false;
+ }
-PlexServer::PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned, bool local)
-{
- m_sServerName = name;
- m_sUuid = uuid;
- m_nOwned = owned;
- m_bLocal = local;
- m_authToken = accessToken;
- Offline = false;
- m_uri = uri;
-}
+ PlexServer::PlexServer(std::string data, std::string ip) {
+ ParseData(data, ip);
+ }
-PlexServer::~PlexServer()
-{
-
-}
+ PlexServer::PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned,
+ bool local) {
+ m_sServerName = name;
+ m_sUuid = uuid;
+ m_nOwned = owned;
+ m_bLocal = local;
+ m_authToken = accessToken;
+ Offline = false;
+ m_uri = uri;
+ }
-void PlexServer::ParseData(std::string data, std::string ip)
-{
- int port = 0;
- std::istringstream f(data);
- std::string s;
- Offline = false;
- while(std::getline(f, s)) {
- int pos = s.find(':');
- if(pos > 0) {
- std::string name = Poco::trim(s.substr(0, pos));
- std::string val = Poco::trim(s.substr(pos+1));
- if(name == "Content-Type") {
- m_sContentType = val;
- } else if (name == "Resource-Identifier") {
- m_sUuid = val;
- } else if (name == "Name") {
- m_sServerName = val;
- } else if (name == "Port") {
- port = atoi(val.c_str());
- } else if (name == "Updated-At") {
- m_nUpdated = atol(val.c_str());
- } else if (name == "Version") {
- m_sVersion = val;
- }
- }
- }
-
- m_bLocal = true;
-
- Poco::URI uri;
-
- uri.setHost(ip);
- uri.setPort(port);
- uri.setScheme("http");
-
- m_uri = uri.toString();
-}
+ PlexServer::~PlexServer() {
-std::string PlexServer::GetHost()
-{
- Poco::URI uri(m_uri);
- return uri.getHost();
-}
+ }
-int PlexServer::GetPort()
-{
- Poco::URI uri(m_uri);
- return uri.getPort();
-}
+ void PlexServer::ParseData(std::string data, std::string ip) {
+ int port = 0;
+ std::istringstream f(data);
+ std::string s;
+ Offline = false;
+ while (std::getline(f, s)) {
+ int pos = s.find(':');
+ if (pos > 0) {
+ std::string name = Poco::trim(s.substr(0, pos));
+ std::string val = Poco::trim(s.substr(pos + 1));
+ if (name == "Content-Type") {
+ m_sContentType = val;
+ } else if (name == "Resource-Identifier") {
+ m_sUuid = val;
+ } else if (name == "Name") {
+ m_sServerName = val;
+ } else if (name == "Port") {
+ port = atoi(val.c_str());
+ } else if (name == "Updated-At") {
+ m_nUpdated = atol(val.c_str());
+ } else if (name == "Version") {
+ m_sVersion = val;
+ }
+ }
+ }
-std::shared_ptr<Poco::Net::HTTPClientSession> PlexServer::GetClientSession()
-{
- Poco::URI uri(m_uri);
- std::shared_ptr<Poco::Net::HTTPClientSession> pHttpSession = nullptr;
- if(uri.getScheme().find("https") != std::string::npos) {
- pHttpSession = std::make_shared<Poco::Net::HTTPSClientSession>(uri.getHost(), uri.getPort());
- }
- else {
- pHttpSession = std::make_shared<Poco::Net::HTTPClientSession>(uri.getHost(), uri.getPort());
- }
-
- //pHttpSession->setTimeout(Poco::Timespan(5, 0)); // set 5 seconds Timeout
- return pHttpSession;
-}
+ m_bLocal = true;
-std::shared_ptr<Poco::Net::HTTPClientSession> PlexServer::MakeRequest(bool& ok, std::string path, const std::map<std::string, std::string>& queryParameters)
-{
- Poco::URI uri(path);
- // Create a request with an optional query
- if(queryParameters.size()) {
- for (auto const& pair : queryParameters) {
- // addQueryParameter does the encode already
- uri.addQueryParameter(pair.first, pair.second);
- }
- }
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
-
- request.add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
- request.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- request.add("X-Plex-Device", "PC");
- request.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
- request.add("X-Plex-Language", Config::GetInstance().GetLanguage());
- request.add("X-Plex-Model", "Linux");
- request.add("X-Plex-Platform", "VDR");
- request.add("X-Plex-Product", "plex for vdr");
- request.add("X-Plex-Provides", "player");
- request.add("X-Plex-Version", VERSION);
-
- if(Config::GetInstance().UsePlexAccount && !GetAuthToken().empty()) {
- // Add PlexToken to Header
- request.add("X-Plex-Token", GetAuthToken());
- }
- auto cSession = GetClientSession();
- ok = true;
- try {
- cSession->sendRequest(request);
- } catch (Poco::TimeoutException &exc) {
- esyslog("[plex] Timeout: %s", path.c_str());
- ok = false;
- } catch (Poco::Exception &exc) {
- esyslog("[plex] Oops Exception: %s", exc.displayText().c_str());
- ok = false;
- }
- return cSession;
-}
+ Poco::URI uri;
-std::string PlexServer::GetUri()
-{
- return m_uri;
-}
+ uri.setHost(ip);
+ uri.setPort(port);
+ uri.setScheme("http");
+
+ m_uri = uri.toString();
+ }
+
+ std::string PlexServer::GetHost() {
+ Poco::URI uri(m_uri);
+ return uri.getHost();
+ }
+
+ int PlexServer::GetPort() {
+ Poco::URI uri(m_uri);
+ return uri.getPort();
+ }
+
+ std::shared_ptr<Poco::Net::HTTPClientSession> PlexServer::GetClientSession() {
+ Poco::URI uri(m_uri);
+ std::shared_ptr<Poco::Net::HTTPClientSession> pHttpSession = nullptr;
+ if (uri.getScheme().find("https") != std::string::npos) {
+ pHttpSession = std::make_shared<Poco::Net::HTTPSClientSession>(uri.getHost(), uri.getPort());
+ }
+ else {
+ pHttpSession = std::make_shared<Poco::Net::HTTPClientSession>(uri.getHost(), uri.getPort());
+ }
+
+ //pHttpSession->setTimeout(Poco::Timespan(5, 0)); // set 5 seconds Timeout
+ return pHttpSession;
+ }
+
+ std::shared_ptr<Poco::Net::HTTPClientSession> PlexServer::MakeRequest(bool &ok, std::string path,
+ const std::map<std::string, std::string> &queryParameters) {
+ Poco::URI uri(path);
+ // Create a request with an optional query
+ if (queryParameters.size()) {
+ for (auto const &pair : queryParameters) {
+ // addQueryParameter does the encode already
+ uri.addQueryParameter(pair.first, pair.second);
+ }
+ }
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(),
+ Poco::Net::HTTPMessage::HTTP_1_1);
+
+ request.add("User-Agent",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
+ request.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ request.add("X-Plex-Device", "PC");
+ request.add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
+ request.add("X-Plex-Language", Config::GetInstance().GetLanguage());
+ request.add("X-Plex-Model", "Linux");
+ request.add("X-Plex-Platform", "VDR");
+ request.add("X-Plex-Product", "plex for vdr");
+ request.add("X-Plex-Provides", "player");
+ request.add("X-Plex-Version", VERSION);
+
+ if (Config::GetInstance().UsePlexAccount && !GetAuthToken().empty()) {
+ // Add PlexToken to Header
+ request.add("X-Plex-Token", GetAuthToken());
+ }
+ auto cSession = GetClientSession();
+ ok = true;
+ try {
+ cSession->sendRequest(request);
+ } catch (Poco::TimeoutException &exc) {
+ esyslog("[plex] Timeout: %s", path.c_str());
+ ok = false;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex] Oops Exception: %s", exc.displayText().c_str());
+ ok = false;
+ }
+ return cSession;
+ }
+
+ std::string PlexServer::GetUri() {
+ return m_uri;
+ }
}
diff --git a/PlexServer.h b/PlexServer.h
index 273df28..7bacb1b 100644
--- a/PlexServer.h
+++ b/PlexServer.h
@@ -17,88 +17,102 @@
#include <Poco/Net/MessageHeader.h>
#include <Poco/URI.h>
-namespace plexclient
-{
-
-class PlexServer
-{
- friend class plexgdm;
-
- public:
- PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned, bool local);
- ~PlexServer();
-
- int GetMaster() const {
- return m_nMaster;
- }
-
- int IsOwned() const {
- return m_nOwned;
- }
- const std::string& GetContentType() const {
- return m_sContentType;
- }
- const std::string& GetDiscovery() const {
- return m_sDiscovery;
- }
- const std::string& GetRole() const {
- return m_sRole;
- }
- const std::string& GetServerName() const {
- return m_sServerName;
- }
- long GetUpdated() const {
- return m_nUpdated;
- }
- const std::string& GetUuid() const {
- return m_sUuid;
- }
- const std::string& GetVersion() const {
- return m_sVersion;
- }
- const std::string& GetAuthToken() const {
- return m_authToken;
- }
- const bool& IsLocal() const {
- return m_bLocal;
- }
- void SetAuthToken(std::string token) {
- m_authToken = token;
- }
-
- std::shared_ptr<Poco::Net::HTTPClientSession> MakeRequest(bool& ok, std::string path, const std::map<std::string, std::string>& queryParameters = std::map<std::string, std::string>());
-
- std::string GetHost();
- int GetPort();
-
- std::string GetUri();
-
- std::shared_ptr<Poco::Net::HTTPClientSession> GetClientSession();
-
- bool Offline;
-
-protected:
- PlexServer(std::string data, std::string ip);
- PlexServer(std::string ip, int port);
- PlexServer() {};
-
- void ParseData(std::string data, std::string ip);
-
-private:
- std::string m_sDiscovery;
-
- int m_nOwned;
- bool m_bLocal;
- int m_nMaster;
- std::string m_sRole;
- std::string m_sContentType;
- std::string m_sUuid;
- std::string m_sServerName;
- std::string m_uri;
- std::string m_authToken;
- long m_nUpdated;
- std::string m_sVersion;
-};
+namespace plexclient {
+
+ class PlexServer {
+ friend class plexgdm;
+
+ public:
+ PlexServer(std::string uri, std::string name, std::string uuid, std::string accessToken, bool owned,
+ bool local);
+
+ ~PlexServer();
+
+ int GetMaster() const {
+ return m_nMaster;
+ }
+
+ int IsOwned() const {
+ return m_nOwned;
+ }
+
+ const std::string &GetContentType() const {
+ return m_sContentType;
+ }
+
+ const std::string &GetDiscovery() const {
+ return m_sDiscovery;
+ }
+
+ const std::string &GetRole() const {
+ return m_sRole;
+ }
+
+ const std::string &GetServerName() const {
+ return m_sServerName;
+ }
+
+ long GetUpdated() const {
+ return m_nUpdated;
+ }
+
+ const std::string &GetUuid() const {
+ return m_sUuid;
+ }
+
+ const std::string &GetVersion() const {
+ return m_sVersion;
+ }
+
+ const std::string &GetAuthToken() const {
+ return m_authToken;
+ }
+
+ const bool &IsLocal() const {
+ return m_bLocal;
+ }
+
+ void SetAuthToken(std::string token) {
+ m_authToken = token;
+ }
+
+ std::shared_ptr<Poco::Net::HTTPClientSession> MakeRequest(bool &ok, std::string path,
+ const std::map<std::string, std::string> &queryParameters = std::map<std::string, std::string>());
+
+ std::string GetHost();
+
+ int GetPort();
+
+ std::string GetUri();
+
+ std::shared_ptr<Poco::Net::HTTPClientSession> GetClientSession();
+
+ bool Offline;
+
+ protected:
+ PlexServer(std::string data, std::string ip);
+
+ PlexServer(std::string ip, int port);
+
+ PlexServer() { };
+
+ void ParseData(std::string data, std::string ip);
+
+ private:
+ std::string m_sDiscovery;
+
+ int m_nOwned;
+ bool m_bLocal;
+ int m_nMaster;
+ std::string m_sRole;
+ std::string m_sContentType;
+ std::string m_sUuid;
+ std::string m_sServerName;
+ std::string m_uri;
+ std::string m_authToken;
+ long m_nUpdated;
+ std::string m_sVersion;
+ };
}
#endif // PLEXSERVER_H
diff --git a/Plexservice.cpp b/Plexservice.cpp
index 1e76bef..9ddc29d 100644
--- a/Plexservice.cpp
+++ b/Plexservice.cpp
@@ -5,305 +5,302 @@
#include <memory>
#include <Poco/Net/NetException.h>
-namespace plexclient
-{
-
-Plexservice::Plexservice(PlexServer *server)
-{
- pServer = server;
-}
-
-Plexservice::Plexservice(PlexServer *server, std::string startUri)
-{
- pServer = server;
- StartUri = startUri;
-}
-
-std::string Plexservice::GetMyPlexToken()
-{
- static bool done;
- static std::string myToken;
-
- //todo: cache token in file or db
- if(!done) {
- std::stringstream ss;
- Poco::Base64Encoder b64(ss);
-
- b64 << Config::GetInstance().GetUsername() << ":" << Config::GetInstance().GetPassword();
-
- b64.close();
- std::string tempToken = ss.str();
-
-
- try {
- Poco::Net::HTTPSClientSession plexSession("plex.tv", 443);
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/users/sign_in.xml", Poco::Net::HTTPMessage::HTTP_1_1);
-
- PlexHelper::AddHttpHeader(request);
- request.add("Authorization", Poco::format("Basic %s", tempToken));
-
- plexSession.sendRequest(request);
-
- Poco::Net::HTTPResponse response;
- std::istream &rs = plexSession.receiveResponse(response);
- if(response.getStatus() == 201) {
- // parse the XML Response
- user u(&rs);
- myToken = u.authenticationToken;
- isyslog("[plex] plex.tv login successfull.");
- } else {
- esyslog("[plex] plex.tv Login failed, check you creditials.");
- }
- done = true;
- plexSession.abort();
- } catch (Poco::Exception &exc) {
- esyslog("[plex]Exception in %s s%", __func__, exc.displayText().c_str() );
- done = true;
- }
-
- }
- return myToken;
-}
-
-void Plexservice::Authenticate()
-{
- if(!Config::GetInstance().UsePlexAccount) return;
- try {
- std::string token = GetMyPlexToken();
- auto pRequest = CreateRequest("/?X-Plex-Token=" + token);
-
- Poco::Net::HTTPClientSession session(pServer->GetHost(), pServer->GetPort());
- session.sendRequest(*pRequest);
- Poco::Net::HTTPResponse response;
- /*std::istream &rs = */
- session.receiveResponse(response);
- session.abort();
- // TODO: process response
- //Poco::StreamCopier::copyStream(rs, std::cout);
- } catch (Poco::Exception &exc) {
- esyslog("[plex]Exception in %s s%", __func__, exc.displayText().c_str() );
- }
-}
-
-void Plexservice::UpdateResources()
-{
- // We must be autenticated
- // https://plex.tv/api/resources?includeHttps=1
- if(!Config::GetInstance().UsePlexAccount) {
- isyslog("[plex] To access remote servers, please login with your plex.tv account.");
- return; // Plugin is used without plex.tv login
- }
- isyslog("[plex] Updating remote resources...");
-
-
- std::shared_ptr<MediaContainer> pContainer = nullptr;
- try {
- Poco::URI fileuri("https://plex.tv/api/resources?includeHttps=1");
-
- Poco::Net::HTTPSClientSession session(fileuri.getHost(), 443);
-
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
- PlexHelper::AddHttpHeader(request);
- request.add("X-Plex-Token", GetMyPlexToken() );
-
- session.sendRequest(request);
- Poco::Net::HTTPResponse response;
- std::istream &rs = session.receiveResponse(response);
-
- //Poco::StreamCopier::copyStream(rs, std::cout);
-
- pContainer = std::shared_ptr<MediaContainer>(new MediaContainer(&rs));
-
- } catch (Poco::Net::NetException &exc) {
- esyslog("[plex] UpdateResources, NetException: %s", exc.displayText().c_str());
- return;
- } catch (Poco::Exception &exc) {
- esyslog("[plex] UpdateResources, Exception: %s", exc.displayText().c_str());
- return;
- }
-
- for(std::vector<Device>::iterator d_it = pContainer->m_vDevices.begin(); d_it != pContainer->m_vDevices.end(); ++d_it) {
-
- // check device is a server
- if(d_it->m_sProvides.find("server") != std::string::npos) {
- // is it a remote server?
- if(d_it->m_bPublicAddressMatches == false) {
- // pick remote connection
- for(std::vector<Connection>::iterator c_it = d_it->m_vConnections.begin(); c_it != d_it->m_vConnections.end(); ++c_it) {
- if(c_it->m_bLocal == false) {
- dsyslog("[plex] Found server via plex.tv: %s", d_it->m_sName.c_str());
- // a remote Server
- plexgdm::GetInstance().AddServer(PlexServer(c_it->m_sUri, d_it->m_sName, d_it->m_sClientIdentifier, d_it->m_sAccessToken, d_it->m_bOwned, c_it->m_bLocal));
- }
- }
- }
- }
- }
-}
-
-PlexServer* Plexservice::GetServer()
-{
- return pServer;
-}
-
-std::shared_ptr<MediaContainer> Plexservice::GetSection(std::string section, bool putOnStack)
-{
- try {
- std::string uri;
- if(section[0]=='/') { // Full URI?
- uri = section;
- } else {
- uri = Poco::format("%s/%s", m_vUriStack.top(), section);
- }
-
- if(putOnStack) {
- m_vUriStack.push(uri);
- }
-
- dsyslog("[plex] URI: %s%s", pServer->GetUri().c_str(), uri.c_str());
-
- bool ok;
- auto cSession = pServer->MakeRequest(ok, uri);
- Poco::Net::HTTPResponse response;
- std::istream& rs = cSession->receiveResponse(response);
- if(ok && response.getStatus() == 200) {
- std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, pServer));
- return pAllsections;
- }
- else {
- dsyslog("[plex] URI: %s%s Response bad: s%", pServer->GetUri().c_str(), uri.c_str(), response.getReasonForStatus(response.getStatus()).c_str() );
- return 0;
- }
-
-
- } catch (Poco::Net::NetException &exc) {
- pServer->Offline = true;
- return 0;
- }
-}
-
-std::shared_ptr<MediaContainer> Plexservice::GetLastSection(bool current)
-{
- if(m_vUriStack.size() > 1) {
- if(!current) {
- // discard last one
- m_vUriStack.pop();
- }
- std::string uri = m_vUriStack.top();
- return GetSection(uri, false);
- }
- return NULL;
-}
-
-bool Plexservice::IsRoot()
-{
- return m_vUriStack.size() <= 1;
-}
-
-std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string path)
-{
- std::unique_ptr<Poco::Net::HTTPRequest> pRequest = std::unique_ptr<Poco::Net::HTTPRequest>(new Poco::Net::HTTPRequest(Poco::Net::HTTPRequest::HTTP_GET,
- path, Poco::Net::HTTPMessage::HTTP_1_1));
-
- PlexHelper::AddHttpHeader(*pRequest);
-
- if(Config::GetInstance().UsePlexAccount) {
- // Add PlexToken to Header
- std::string token = GetMyPlexToken();
- if(pServer && !pServer->GetAuthToken().empty()) {
- pRequest->add("X-Plex-Token", pServer->GetAuthToken());
- dsyslog("[plex] Using server access token");
- } else if(!token.empty()) {
- pRequest->add("X-Plex-Token", token);
- dsyslog("[plex] Using global access token");
- }
- }
-
- return pRequest;
-}
-
-std::shared_ptr<MediaContainer> Plexservice::GetMediaContainer(std::string fullUrl)
-{
- PlexServer* pServer = NULL;
- try {
- Poco::URI fileuri(fullUrl);
- dsyslog("[plex] GetMediaContainer: %s", fullUrl.c_str());
-
- pServer = plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort());
-
- bool ok;
- auto cSession = pServer->MakeRequest(ok, fileuri.getPathAndQuery());
- Poco::Net::HTTPResponse response;
- std::istream &rs = cSession->receiveResponse(response);
- if(ok && response.getStatus() == 200) {
- std::shared_ptr<MediaContainer> pAllsections = std::shared_ptr<MediaContainer>(new MediaContainer(&rs, pServer));
- return pAllsections;
- }
- return 0;
- //Poco::StreamCopier::copyStream(rs, std::cout);
- } catch (Poco::Net::NetException &exc) {
- esyslog("[plex] GetMediaContainer, NetException: %s", exc.displayText().c_str());
- return 0;
- }
-}
-
-std::string Plexservice::GetUniversalTranscodeUrl(cVideo* video, int offset, PlexServer* server, bool http)
-{
- PlexServer* pSrv = server ? server : video->m_pServer;
- Poco::URI transcodeUri(pSrv->GetUri());
- if(!http) {
- transcodeUri.setPath("/video/:/transcode/universal/start.m3u8");
- transcodeUri.addQueryParameter("protocol", "hls");
- transcodeUri.addQueryParameter("includeCodecs", "1");
- //transcodeUri.addQueryParameter("copyts", "1");
- transcodeUri.addQueryParameter("directPlay", "0");
- transcodeUri.addQueryParameter("directStream", "1");
- transcodeUri.addQueryParameter("subtitles", "burn");
- transcodeUri.addQueryParameter("audioBoost", "100");
- } else {
- transcodeUri.setScheme("http"); // mpv segfaults with https... :-(
- transcodeUri.setPath("/video/:/transcode/universal/start");
- transcodeUri.addQueryParameter("protocol", "http");
-
- transcodeUri.addQueryParameter("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- transcodeUri.addQueryParameter("X-Plex-Product", "Chromecast");
- transcodeUri.addQueryParameter("X-Plex-Platform", "Chromecast");
- transcodeUri.addQueryParameter("X-Plex-Token", pSrv->GetAuthToken());
- }
-
-
- // Force set localhost and http
- Poco::URI pathUri(pSrv->GetUri()+video->m_sKey);
- pathUri.setHost("127.0.0.1");
- pathUri.setScheme("http");
-
- transcodeUri.addQueryParameter("path", pathUri.toString());
- transcodeUri.addQueryParameter("mediaIndex", "0");
- transcodeUri.addQueryParameter("partIndex", "0");
- transcodeUri.addQueryParameter("offset", std::to_string(offset) );
- transcodeUri.addQueryParameter("fastSeek", "1");
-
-
- if(pSrv->IsLocal()) {
- transcodeUri.addQueryParameter("videoResolution", "1920x1080");
- transcodeUri.addQueryParameter("maxVideoBitrate", "20000");
- transcodeUri.addQueryParameter("videoQuality", "100");
- } else {
- transcodeUri.addQueryParameter("videoResolution", "1280x720");
- transcodeUri.addQueryParameter("maxVideoBitrate", "8000");
- transcodeUri.addQueryParameter("videoQuality", "100");
- }
- transcodeUri.addQueryParameter("session", Config::GetInstance().GetUUID()); // TODO: generate Random SessionID
-
-
- if(Config::GetInstance().UseAc3 && !http) {
- transcodeUri.addQueryParameter("X-Plex-Client-Profile-Extra", "add-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3)");
- //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.height&value=1080)");
- //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.frameRate&value=25)");
- //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=upperBound&name=video.frameRate&value=25)");
- }
-
- return transcodeUri.toString();
-}
+namespace plexclient {
+
+ Plexservice::Plexservice(PlexServer *server) {
+ pServer = server;
+ }
+
+ Plexservice::Plexservice(PlexServer *server, std::string startUri) {
+ pServer = server;
+ StartUri = startUri;
+ }
+
+ std::string Plexservice::GetMyPlexToken() {
+ static bool done;
+ static std::string myToken;
+
+ //todo: cache token in file or db
+ if (!done) {
+ std::stringstream ss;
+ Poco::Base64Encoder b64(ss);
+
+ b64 << Config::GetInstance().GetUsername() << ":" << Config::GetInstance().GetPassword();
+
+ b64.close();
+ std::string tempToken = ss.str();
+
+
+ try {
+ Poco::Net::HTTPSClientSession plexSession("plex.tv", 443);
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/users/sign_in.xml",
+ Poco::Net::HTTPMessage::HTTP_1_1);
+
+ PlexHelper::AddHttpHeader(request);
+ request.add("Authorization", Poco::format("Basic %s", tempToken));
+
+ plexSession.sendRequest(request);
+
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = plexSession.receiveResponse(response);
+ if (response.getStatus() == 201) {
+ // parse the XML Response
+ user u(&rs);
+ myToken = u.authenticationToken;
+ isyslog("[plex] plex.tv login successfull.");
+ } else {
+ esyslog("[plex] plex.tv Login failed, check you creditials.");
+ }
+ done = true;
+ plexSession.abort();
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]Exception in %s s%", __func__, exc.displayText().c_str());
+ done = true;
+ }
+
+ }
+ return myToken;
+ }
+
+ void Plexservice::Authenticate() {
+ if (!Config::GetInstance().UsePlexAccount) return;
+ try {
+ std::string token = GetMyPlexToken();
+ auto pRequest = CreateRequest("/?X-Plex-Token=" + token);
+
+ Poco::Net::HTTPClientSession session(pServer->GetHost(), pServer->GetPort());
+ session.sendRequest(*pRequest);
+ Poco::Net::HTTPResponse response;
+ /*std::istream &rs = */
+ session.receiveResponse(response);
+ session.abort();
+ // TODO: process response
+ //Poco::StreamCopier::copyStream(rs, std::cout);
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]Exception in %s s%", __func__, exc.displayText().c_str());
+ }
+ }
+
+ void Plexservice::UpdateResources() {
+ // We must be autenticated
+ // https://plex.tv/api/resources?includeHttps=1
+ if (!Config::GetInstance().UsePlexAccount) {
+ isyslog("[plex] To access remote servers, please login with your plex.tv account.");
+ return; // Plugin is used without plex.tv login
+ }
+ isyslog("[plex] Updating remote resources...");
+
+
+ std::shared_ptr<MediaContainer> pContainer = nullptr;
+ try {
+ Poco::URI fileuri("https://plex.tv/api/resources?includeHttps=1");
+
+ Poco::Net::HTTPSClientSession session(fileuri.getHost(), 443);
+
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(),
+ Poco::Net::HTTPMessage::HTTP_1_1);
+ PlexHelper::AddHttpHeader(request);
+ request.add("X-Plex-Token", GetMyPlexToken());
+
+ session.sendRequest(request);
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = session.receiveResponse(response);
+
+ //Poco::StreamCopier::copyStream(rs, std::cout);
+
+ pContainer = std::shared_ptr<MediaContainer>(new MediaContainer(&rs));
+
+ } catch (Poco::Net::NetException &exc) {
+ esyslog("[plex] UpdateResources, NetException: %s", exc.displayText().c_str());
+ return;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex] UpdateResources, Exception: %s", exc.displayText().c_str());
+ return;
+ }
+
+ for (std::vector<Device>::iterator d_it = pContainer->m_vDevices.begin();
+ d_it != pContainer->m_vDevices.end(); ++d_it) {
+
+ // check device is a server
+ if (d_it->m_sProvides.find("server") != std::string::npos) {
+ // is it a remote server?
+ if (d_it->m_bPublicAddressMatches == false) {
+ // pick remote connection
+ for (std::vector<Connection>::iterator c_it = d_it->m_vConnections.begin();
+ c_it != d_it->m_vConnections.end(); ++c_it) {
+ if (c_it->m_bLocal == false) {
+ dsyslog("[plex] Found server via plex.tv: %s", d_it->m_sName.c_str());
+ // a remote Server
+ plexgdm::GetInstance().AddServer(
+ PlexServer(c_it->m_sUri, d_it->m_sName, d_it->m_sClientIdentifier,
+ d_it->m_sAccessToken, d_it->m_bOwned, c_it->m_bLocal));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ PlexServer *Plexservice::GetServer() {
+ return pServer;
+ }
+
+ std::shared_ptr<MediaContainer> Plexservice::GetSection(std::string section, bool putOnStack) {
+ try {
+ std::string uri;
+ if (section[0] == '/') { // Full URI?
+ uri = section;
+ } else {
+ uri = Poco::format("%s/%s", m_vUriStack.top(), section);
+ }
+
+ if (putOnStack) {
+ m_vUriStack.push(uri);
+ }
+
+ dsyslog("[plex] URI: %s%s", pServer->GetUri().c_str(), uri.c_str());
+
+ bool ok;
+ auto cSession = pServer->MakeRequest(ok, uri);
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = cSession->receiveResponse(response);
+ if (ok && response.getStatus() == 200) {
+ std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, pServer));
+ return pAllsections;
+ }
+ else {
+ dsyslog("[plex] URI: %s%s Response bad: s%", pServer->GetUri().c_str(), uri.c_str(),
+ response.getReasonForStatus(response.getStatus()).c_str());
+ return 0;
+ }
+
+
+ } catch (Poco::Net::NetException &exc) {
+ pServer->Offline = true;
+ return 0;
+ }
+ }
+
+ std::shared_ptr<MediaContainer> Plexservice::GetLastSection(bool current) {
+ if (m_vUriStack.size() > 1) {
+ if (!current) {
+ // discard last one
+ m_vUriStack.pop();
+ }
+ std::string uri = m_vUriStack.top();
+ return GetSection(uri, false);
+ }
+ return NULL;
+ }
+
+ bool Plexservice::IsRoot() {
+ return m_vUriStack.size() <= 1;
+ }
+
+ std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string path) {
+ std::unique_ptr<Poco::Net::HTTPRequest> pRequest = std::unique_ptr<Poco::Net::HTTPRequest>(
+ new Poco::Net::HTTPRequest(Poco::Net::HTTPRequest::HTTP_GET,
+ path, Poco::Net::HTTPMessage::HTTP_1_1));
+
+ PlexHelper::AddHttpHeader(*pRequest);
+
+ if (Config::GetInstance().UsePlexAccount) {
+ // Add PlexToken to Header
+ std::string token = GetMyPlexToken();
+ if (pServer && !pServer->GetAuthToken().empty()) {
+ pRequest->add("X-Plex-Token", pServer->GetAuthToken());
+ dsyslog("[plex] Using server access token");
+ } else if (!token.empty()) {
+ pRequest->add("X-Plex-Token", token);
+ dsyslog("[plex] Using global access token");
+ }
+ }
+
+ return pRequest;
+ }
+
+ std::shared_ptr<MediaContainer> Plexservice::GetMediaContainer(std::string fullUrl) {
+ PlexServer *pServer = NULL;
+ try {
+ Poco::URI fileuri(fullUrl);
+ dsyslog("[plex] GetMediaContainer: %s", fullUrl.c_str());
+
+ pServer = plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort());
+
+ bool ok;
+ auto cSession = pServer->MakeRequest(ok, fileuri.getPathAndQuery());
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = cSession->receiveResponse(response);
+ if (ok && response.getStatus() == 200) {
+ std::shared_ptr<MediaContainer> pAllsections = std::shared_ptr<MediaContainer>(
+ new MediaContainer(&rs, pServer));
+ return pAllsections;
+ }
+ return 0;
+ //Poco::StreamCopier::copyStream(rs, std::cout);
+ } catch (Poco::Net::NetException &exc) {
+ esyslog("[plex] GetMediaContainer, NetException: %s", exc.displayText().c_str());
+ return 0;
+ }
+ }
+
+ std::string Plexservice::GetUniversalTranscodeUrl(cVideo *video, int offset, PlexServer *server, bool http) {
+ PlexServer *pSrv = server ? server : video->m_pServer;
+ Poco::URI transcodeUri(pSrv->GetUri());
+ if (!http) {
+ transcodeUri.setPath("/video/:/transcode/universal/start.m3u8");
+ transcodeUri.addQueryParameter("protocol", "hls");
+ transcodeUri.addQueryParameter("includeCodecs", "1");
+ //transcodeUri.addQueryParameter("copyts", "1");
+ transcodeUri.addQueryParameter("directPlay", "0");
+ transcodeUri.addQueryParameter("directStream", "1");
+ transcodeUri.addQueryParameter("subtitles", "burn");
+ transcodeUri.addQueryParameter("audioBoost", "100");
+ } else {
+ transcodeUri.setScheme("http"); // mpv segfaults with https... :-(
+ transcodeUri.setPath("/video/:/transcode/universal/start");
+ transcodeUri.addQueryParameter("protocol", "http");
+
+ transcodeUri.addQueryParameter("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+ transcodeUri.addQueryParameter("X-Plex-Product", "Chromecast");
+ transcodeUri.addQueryParameter("X-Plex-Platform", "Chromecast");
+ transcodeUri.addQueryParameter("X-Plex-Token", pSrv->GetAuthToken());
+ }
+
+
+ // Force set localhost and http
+ Poco::URI pathUri(pSrv->GetUri() + video->m_sKey);
+ pathUri.setHost("127.0.0.1");
+ pathUri.setScheme("http");
+
+ transcodeUri.addQueryParameter("path", pathUri.toString());
+ transcodeUri.addQueryParameter("mediaIndex", "0");
+ transcodeUri.addQueryParameter("partIndex", "0");
+ transcodeUri.addQueryParameter("offset", std::to_string(offset));
+ transcodeUri.addQueryParameter("fastSeek", "1");
+
+
+ if (pSrv->IsLocal()) {
+ transcodeUri.addQueryParameter("videoResolution", "1920x1080");
+ transcodeUri.addQueryParameter("maxVideoBitrate", "20000");
+ transcodeUri.addQueryParameter("videoQuality", "100");
+ } else {
+ transcodeUri.addQueryParameter("videoResolution", "1280x720");
+ transcodeUri.addQueryParameter("maxVideoBitrate", "8000");
+ transcodeUri.addQueryParameter("videoQuality", "100");
+ }
+ transcodeUri.addQueryParameter("session", Config::GetInstance().GetUUID()); // TODO: generate Random SessionID
+
+
+ if (Config::GetInstance().UseAc3 && !http) {
+ transcodeUri.addQueryParameter("X-Plex-Client-Profile-Extra",
+ "add-transcode-target-audio-codec(type=videoProfile&context=streaming&protocol=hls&audioCodec=ac3)");
+ //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.height&value=1080)");
+ //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=lowerBound&name=video.frameRate&value=25)");
+ //params << encode("+add-limitation(scope=videoCodec&scopeName=h264&type=upperBound&name=video.frameRate&value=25)");
+ }
+
+ return transcodeUri.toString();
+ }
}
diff --git a/Plexservice.h b/Plexservice.h
index a40525c..97bf8a2 100644
--- a/Plexservice.h
+++ b/Plexservice.h
@@ -33,37 +33,45 @@
#include "user.h"
#include "MediaContainer.h"
-namespace plexclient
-{
-
-class Plexservice
-{
-public:
- Plexservice(PlexServer *server);
- Plexservice(PlexServer *server, std::string startUri);
-
- std::shared_ptr<MediaContainer> GetSection(std::string section, bool putOnStack = true);
- std::shared_ptr<MediaContainer> GetLastSection(bool current = false);
- bool IsRoot();
- PlexServer* GetServer();
- void Authenticate();
-
- static std::string GetUniversalTranscodeUrl(cVideo* video, int offset = 0, PlexServer* server = 0, bool http = false);
- static std::string GetMyPlexToken();
- static std::shared_ptr<MediaContainer> GetMediaContainer(std::string fullUrl);
- //static std::string encode(std::string message);
- static void UpdateResources();
-
- std::string StartUri;
-
-private:
- Poco::Mutex m_mutex;
- PlexServer *pServer;
-
- std::stack<std::string> m_vUriStack;
- std::unique_ptr<Poco::Net::HTTPRequest> CreateRequest(std::string path);
-
-};
+namespace plexclient {
+
+ class Plexservice {
+ public:
+ Plexservice(PlexServer *server);
+
+ Plexservice(PlexServer *server, std::string startUri);
+
+ std::shared_ptr<MediaContainer> GetSection(std::string section, bool putOnStack = true);
+
+ std::shared_ptr<MediaContainer> GetLastSection(bool current = false);
+
+ bool IsRoot();
+
+ PlexServer *GetServer();
+
+ void Authenticate();
+
+ static std::string GetUniversalTranscodeUrl(cVideo *video, int offset = 0, PlexServer *server = 0,
+ bool http = false);
+
+ static std::string GetMyPlexToken();
+
+ static std::shared_ptr<MediaContainer> GetMediaContainer(std::string fullUrl);
+
+ //static std::string encode(std::string message);
+ static void UpdateResources();
+
+ std::string StartUri;
+
+ private:
+ Poco::Mutex m_mutex;
+ PlexServer *pServer;
+
+ std::stack<std::string> m_vUriStack;
+
+ std::unique_ptr<Poco::Net::HTTPRequest> CreateRequest(std::string path);
+
+ };
}
diff --git a/Stream.cpp b/Stream.cpp
index 3f466f4..da3df33 100644
--- a/Stream.cpp
+++ b/Stream.cpp
@@ -1,36 +1,34 @@
#include "Stream.h"
#include <Poco/Format.h>
-namespace plexclient
-{
+namespace plexclient {
-Stream::Stream(Poco::XML::Node* pNode)
-{
- if(Poco::icompare(pNode->nodeName(), "Stream") == 0) {
+ Stream::Stream(Poco::XML::Node *pNode) {
+ if (Poco::icompare(pNode->nodeName(), "Stream") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
-
- m_bSelected = GetNodeValueAsBool(pAttribs->getNamedItem("selected"));
- m_iID = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
- m_iStreamType = GetNodeValueAsInt(pAttribs->getNamedItem("streamType"));
- m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
- m_iChannels = GetNodeValueAsInt(pAttribs->getNamedItem("channels"));
- m_sCodec = GetNodeValue(pAttribs->getNamedItem("codec"));
- m_sCodecId = GetNodeValue(pAttribs->getNamedItem("codecID"));
- m_sLanguage = GetNodeValue(pAttribs->getNamedItem("language"));
- m_sLanguageCode = GetNodeValue(pAttribs->getNamedItem("languageCode"));
- m_eStreamType = GetNodeValueAsStreamType(pAttribs->getNamedItem("streamType"));
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
- pAttribs->release();
- }
-}
+ m_bSelected = GetNodeValueAsBool(pAttribs->getNamedItem("selected"));
+ m_iID = GetNodeValueAsInt(pAttribs->getNamedItem("id"));
+ m_iStreamType = GetNodeValueAsInt(pAttribs->getNamedItem("streamType"));
+ m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
+ m_iChannels = GetNodeValueAsInt(pAttribs->getNamedItem("channels"));
+ m_sCodec = GetNodeValue(pAttribs->getNamedItem("codec"));
+ m_sCodecId = GetNodeValue(pAttribs->getNamedItem("codecID"));
+ m_sLanguage = GetNodeValue(pAttribs->getNamedItem("language"));
+ m_sLanguageCode = GetNodeValue(pAttribs->getNamedItem("languageCode"));
+ m_eStreamType = GetNodeValueAsStreamType(pAttribs->getNamedItem("streamType"));
-std::string Stream::GetSetStreamQuery()
-{
- if(m_eStreamType == StreamType::sAUDIO) return Poco::format("audioStreamID=%d", m_iID);
- else if(m_eStreamType == StreamType::sSUBTITLE && m_iID >= 0) return Poco::format("subtitleStreamID=%d", m_iID);
- else if(m_eStreamType == StreamType::sSUBTITLE && m_iID < 0) return "subtitleStreamID=";
- else return "";
-}
+ pAttribs->release();
+ }
+ }
+
+ std::string Stream::GetSetStreamQuery() {
+ if (m_eStreamType == StreamType::sAUDIO) return Poco::format("audioStreamID=%d", m_iID);
+ else if (m_eStreamType == StreamType::sSUBTITLE && m_iID >= 0)
+ return Poco::format("subtitleStreamID=%d", m_iID);
+ else if (m_eStreamType == StreamType::sSUBTITLE && m_iID < 0) return "subtitleStreamID=";
+ else return "";
+ }
} // namespace
diff --git a/Stream.h b/Stream.h
index 5d9b94a..64a6fc2 100644
--- a/Stream.h
+++ b/Stream.h
@@ -26,29 +26,28 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
-
-class Stream: XmlObject
-{
-public:
- Stream(Poco::XML::Node* pNode);
- Stream() {};
-
-public:
- bool m_bSelected;
- int m_iID;
- int m_iStreamType;
- int m_iIndex;
- int m_iChannels;
- std::string m_sCodec;
- std::string m_sCodecId;
- std::string m_sLanguage;
- std::string m_sLanguageCode;
- StreamType m_eStreamType;
-
- std::string GetSetStreamQuery();
-};
+namespace plexclient {
+
+ class Stream : XmlObject {
+ public:
+ Stream(Poco::XML::Node *pNode);
+
+ Stream() { };
+
+ public:
+ bool m_bSelected;
+ int m_iID;
+ int m_iStreamType;
+ int m_iIndex;
+ int m_iChannels;
+ std::string m_sCodec;
+ std::string m_sCodecId;
+ std::string m_sLanguage;
+ std::string m_sLanguageCode;
+ StreamType m_eStreamType;
+
+ std::string GetSetStreamQuery();
+ };
}
diff --git a/SubscriptionManager.cpp b/SubscriptionManager.cpp
index 4d90a58..4d4311d 100644
--- a/SubscriptionManager.cpp
+++ b/SubscriptionManager.cpp
@@ -14,286 +14,269 @@
#include "PlexHelper.h"
#include "plex.h"
-namespace plexclient
-{
-
-SubscriptionManager::SubscriptionManager()
-{
- m_pStatus = new cSubscriberStatus();
- m_bStoppedSent = true;
-}
-
-void SubscriptionManager::Notify()
-{
- //dsyslog("[plex]: '%s'", __FUNCTION__);
- Cleanup();
- m_myLock.Lock(&m_myMutex);
- for(std::map<std::string, Subscriber>::iterator it = m_mSubcribers.begin() ; it != m_mSubcribers.end(); ++it) {
- Subscriber subs = it->second;
- subs.SendUpdate(GetMsg(subs.m_iCommandId), false);
- }
- NotifyServer();
- ReportProgress();
-}
-
-void SubscriptionManager::ReportProgress()
-{
- if(!m_pStatus->pVideo) {
- return;
- }
-
- try {
- int current, total, speed;
- bool play, forward;
- if(!m_pStatus->PlayerStopped && m_pStatus->pControl) {
- m_pStatus->pControl->GetIndex(current, total);
- current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
- total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
- m_pStatus->pControl->GetReplayMode(play, forward, speed);
- } else {
- return;
- }
-
- m_pStatus->pControl->GetReplayMode(play, forward, speed);
-
- std::string state = "playing";
- if (m_pStatus->PlayerStopped) state = "stopped";
- else if(!play) state = "paused";
-
- std::map<std::string, std::string> queryMap;
- queryMap["key"] = std::to_string(m_pStatus->pVideo->m_iRatingKey);
- queryMap["identifier"] = "com.plexapp.plugins.library";
- queryMap["time"] = std::to_string(current);
- queryMap["state"] = state;
-
- bool ok;
- auto cSession = m_pStatus->pVideo->m_pServer->MakeRequest(ok, "/:/progress", queryMap);
-
- } catch (Poco::Exception&) {}
-}
-
-void SubscriptionManager::NotifyServer()
-{
- if(m_bStoppedSent && m_pStatus->PlayerStopped) return;
- try {
- int current, total, speed;
- bool play, forward;
- cVideo *pVid = NULL;
- if(!m_pStatus->PlayerStopped && m_pStatus->pControl) {
- m_pStatus->pControl->GetIndex(current, total);
- current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
- total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
- m_pStatus->pControl->GetReplayMode(play, forward, speed);
- pVid = m_pStatus->pVideo;
- } else {
- return;
- }
-
- PlexServer* pServer;
- if(pVid) {
- pServer = pVid->m_pServer;
- } else if ( plexgdm::GetInstance().GetPlexservers().size() > 0) {
- pServer = &plexgdm::GetInstance().GetPlexservers().at(0);
- } else {
- // no plexservers in network
- return;
- }
-
- std::map<std::string, std::string> queryMap;
-
- queryMap["containerKey"] = pVid ? pVid->m_sKey : "/library/metadata/900000";
- queryMap["key"] = pVid ? pVid->m_sKey : "/library/metadata/900000";
- queryMap["ratingKey"] = pVid ? std::to_string(pVid->m_iRatingKey) : "900000";
-
- if (m_pStatus->PlayerStopped) queryMap["state"] = "stopped";
- else if(!play) queryMap["state"] = "paused";
- else queryMap["state"] = "playing";
-
- queryMap["time"] = std::to_string(current);
- queryMap["duration"] = std::to_string(total);
-
-
- Poco::Net::HTTPResponse response;
- bool ok;
- auto cSession = pServer->MakeRequest(ok, "/:/timeline", queryMap);
-
-
- m_bStoppedSent = m_pStatus->PlayerStopped ? true : false;
- } catch (Poco::Exception& e) {}
-
-}
-
-void SubscriptionManager::AddSubscriber(Subscriber subs)
-{
- m_myLock.Lock(&m_myMutex);
- m_mSubcribers[subs.GetUuid()] = subs;
-}
-
-void SubscriptionManager::RemoveSubscriber(std::string uuid)
-{
- m_myLock.Lock(&m_myMutex);
- if(m_mSubcribers.find(uuid) != m_mSubcribers.end()) {
- m_mSubcribers.erase(uuid);
- }
-}
-
-void SubscriptionManager::UpdateSubscriber(std::string uuid, std::string commandId)
-{
- m_myLock.Lock(&m_myMutex);
- if(m_mSubcribers.find(uuid) != m_mSubcribers.end()) {
- m_mSubcribers[uuid].m_iCommandId = commandId;
- //dsyslog("[plex]: '%s'", __FUNCTION__);
- }
-}
-
-std::string SubscriptionManager::GetMsg(std::string commandId)
-{
- //dsyslog("[plex]: '%s'", __FUNCTION__);
- std::stringstream msg;
- msg << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- "<MediaContainer commandID=\"" << commandId << "\" location=\"navigation\">";
-
- msg << "<Timeline location=\"navigation\" state=\"stopped\" time=\"0\" type=\"photo\" />";
- msg << "<Timeline location=\"navigation\" state=\"stopped\" time=\"0\" type=\"music\" />";
-
- msg << GetTimelineXml();
-
- msg << "</MediaContainer>";
- return msg.str();
-}
-
-std::string SubscriptionManager::GetTimelineXml()
-{
- int current = 0, total = 0, speed;
- bool play = false, forward;
- cVideo *pVid = NULL;
- if(!m_pStatus->PlayerStopped && m_pStatus->pControl) {
- m_pStatus->pControl->GetIndex(current, total);
- current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
- total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
- m_pStatus->pControl->GetReplayMode(play, forward, speed);
- pVid = m_pStatus->pVideo;
- }
-
- std::stringstream msg;
-
- msg << "<Timeline location=\"navigation\" state=\"";
- if (m_pStatus->PlayerStopped) msg << "stopped";
- else if(!play) msg << "paused";
- else msg << "playing";
-
- msg << "\" time=\"" << current << "\" type=\"video\"";
- if (!m_pStatus->PlayerStopped) {
- msg << " duration=\"" << total << "\"";
- msg << " seekRange=\"0-" << total << "\"";
- msg << " controllable=\"true\"";
- msg << " machineIdentifier=\"" << (pVid ? pVid->m_pServer->GetUuid() : "") << "\"";
- msg << " protocol=\"http\"";
- msg << " address=\"" << (pVid ? pVid->m_pServer->GetHost() : "") << "\"";
- msg << " port=\"" << (pVid ? pVid->m_pServer->GetPort() : 0) << "\"";
- msg << " guid=\"" << Config::GetInstance().GetUUID() << "\"";
- msg << " containerKey=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\"";
- msg << " key=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\"";
- msg << " ratingKey=\"" << (pVid ? pVid->m_iRatingKey : 900000) << "\"";
- msg << " volume=\"" << m_pStatus->Volume << "\"";
- msg << " shuffle=\"false\"";
- }
- msg << "/>";
- return msg.str();
-}
-
-void SubscriptionManager::Cleanup()
-{
- m_myLock.Lock(&m_myMutex);
- for(std::map<std::string, Subscriber>::iterator it = m_mSubcribers.begin() ; it != m_mSubcribers.end(); ++it) {
- Subscriber subs = it->second;
- if(subs.m_iAge > 30) {
- m_mSubcribers.erase(it);
- }
- }
-}
-
-Subscriber::Subscriber(std::string protocol, std::string host, int port, std::string uuid, std::string commandId)
-{
- m_sProtocol = protocol;
- int pos = host.find(":");
- m_sHost = host.substr(0,pos-1);
- m_iPort = port;
- m_sUuid = uuid;
- m_iCommandId = commandId;
- m_iAge = 0;
-}
-
-void Subscriber::SendUpdate(std::string msg, bool isNav)
-{
- //dsyslog("[plex]: '%s'", __FUNCTION__);
- ++m_iAge;
- try {
- Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
- "/:/timeline", Poco::Net::HTTPMessage::HTTP_1_1);
-
- PlexHelper::AddHttpHeader(Request);
-
- Poco::Net::HTTPClientSession session(m_sHost, m_iPort);
-
- Request.setContentLength(msg.length());
- session.sendRequest(Request) << msg;
-
- Poco::Net::HTTPResponse response;
- session.receiveResponse(response);
-
- } catch (Poco::Exception& e) {}
-}
-
-ActionManager::ActionManager() {}
-
-void ActionManager::AddAction(cVideo video)
-{
- m_myLock.Lock(&m_myMutex);
- m_Action = video;
- m_isAction = true;
-}
-
-cVideo ActionManager::GetAction()
-{
- m_myLock.Lock(&m_myMutex);
- m_isAction = false;
- return m_Action;
-}
-
-bool ActionManager::IsAction()
-{
- //m_myLock.Lock(&m_myMutex);
- return m_isAction;
-}
-
-cSubscriberStatus::cSubscriberStatus()
-{
- PlayerStopped = true;
- pControl = NULL;
-}
-
-void cSubscriberStatus::Replaying(const cControl* DvbPlayerControl, const char* Name, const char* FileName, bool On)
-{
- //dsyslog("[plex]: '%s'", __FUNCTION__);
- PlayerStopped = !On;
-
- if(PlayerStopped) {
- cMyPlugin::PlayingFile = false;
- }
-
- pControl = const_cast<cControl*>(DvbPlayerControl);
- cHlsPlayerControl* hlsControl = dynamic_cast<cHlsPlayerControl*>(pControl);
- if(hlsControl) {
- pVideo = &hlsControl->m_Video;
- } else if(cMyPlugin::PlayingFile) {
- pVideo = &cMyPlugin::CurrentVideo;
- } else {
- pVideo = NULL;
- pControl = NULL;
- }
-
- SubscriptionManager::GetInstance().Notify();
-}
+namespace plexclient {
+
+ SubscriptionManager::SubscriptionManager() {
+ m_pStatus = new cSubscriberStatus();
+ m_bStoppedSent = true;
+ }
+
+ void SubscriptionManager::Notify() {
+ //dsyslog("[plex]: '%s'", __FUNCTION__);
+ Cleanup();
+ m_myLock.Lock(&m_myMutex);
+ for (std::map<std::string, Subscriber>::iterator it = m_mSubcribers.begin(); it != m_mSubcribers.end(); ++it) {
+ Subscriber subs = it->second;
+ subs.SendUpdate(GetMsg(subs.m_iCommandId), false);
+ }
+ NotifyServer();
+ ReportProgress();
+ }
+
+ void SubscriptionManager::ReportProgress() {
+ if (!m_pStatus->pVideo) {
+ return;
+ }
+
+ try {
+ int current, total, speed;
+ bool play, forward;
+ if (!m_pStatus->PlayerStopped && m_pStatus->pControl) {
+ m_pStatus->pControl->GetIndex(current, total);
+ current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
+ total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
+ m_pStatus->pControl->GetReplayMode(play, forward, speed);
+ } else {
+ return;
+ }
+
+ m_pStatus->pControl->GetReplayMode(play, forward, speed);
+
+ std::string state = "playing";
+ if (m_pStatus->PlayerStopped) state = "stopped";
+ else if (!play) state = "paused";
+
+ std::map<std::string, std::string> queryMap;
+ queryMap["key"] = std::to_string(m_pStatus->pVideo->m_iRatingKey);
+ queryMap["identifier"] = "com.plexapp.plugins.library";
+ queryMap["time"] = std::to_string(current);
+ queryMap["state"] = state;
+
+ bool ok;
+ auto cSession = m_pStatus->pVideo->m_pServer->MakeRequest(ok, "/:/progress", queryMap);
+
+ } catch (Poco::Exception &) { }
+ }
+
+ void SubscriptionManager::NotifyServer() {
+ if (m_bStoppedSent && m_pStatus->PlayerStopped) return;
+ try {
+ int current, total, speed;
+ bool play, forward;
+ cVideo *pVid = NULL;
+ if (!m_pStatus->PlayerStopped && m_pStatus->pControl) {
+ m_pStatus->pControl->GetIndex(current, total);
+ current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
+ total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
+ m_pStatus->pControl->GetReplayMode(play, forward, speed);
+ pVid = m_pStatus->pVideo;
+ } else {
+ return;
+ }
+
+ PlexServer *pServer;
+ if (pVid) {
+ pServer = pVid->m_pServer;
+ } else if (plexgdm::GetInstance().GetPlexservers().size() > 0) {
+ pServer = &plexgdm::GetInstance().GetPlexservers().at(0);
+ } else {
+ // no plexservers in network
+ return;
+ }
+
+ std::map<std::string, std::string> queryMap;
+
+ queryMap["containerKey"] = pVid ? pVid->m_sKey : "/library/metadata/900000";
+ queryMap["key"] = pVid ? pVid->m_sKey : "/library/metadata/900000";
+ queryMap["ratingKey"] = pVid ? std::to_string(pVid->m_iRatingKey) : "900000";
+
+ if (m_pStatus->PlayerStopped) queryMap["state"] = "stopped";
+ else if (!play) queryMap["state"] = "paused";
+ else queryMap["state"] = "playing";
+
+ queryMap["time"] = std::to_string(current);
+ queryMap["duration"] = std::to_string(total);
+
+
+ Poco::Net::HTTPResponse response;
+ bool ok;
+ auto cSession = pServer->MakeRequest(ok, "/:/timeline", queryMap);
+
+
+ m_bStoppedSent = m_pStatus->PlayerStopped ? true : false;
+ } catch (Poco::Exception &e) { }
+
+ }
+
+ void SubscriptionManager::AddSubscriber(Subscriber subs) {
+ m_myLock.Lock(&m_myMutex);
+ m_mSubcribers[subs.GetUuid()] = subs;
+ }
+
+ void SubscriptionManager::RemoveSubscriber(std::string uuid) {
+ m_myLock.Lock(&m_myMutex);
+ if (m_mSubcribers.find(uuid) != m_mSubcribers.end()) {
+ m_mSubcribers.erase(uuid);
+ }
+ }
+
+ void SubscriptionManager::UpdateSubscriber(std::string uuid, std::string commandId) {
+ m_myLock.Lock(&m_myMutex);
+ if (m_mSubcribers.find(uuid) != m_mSubcribers.end()) {
+ m_mSubcribers[uuid].m_iCommandId = commandId;
+ //dsyslog("[plex]: '%s'", __FUNCTION__);
+ }
+ }
+
+ std::string SubscriptionManager::GetMsg(std::string commandId) {
+ //dsyslog("[plex]: '%s'", __FUNCTION__);
+ std::stringstream msg;
+ msg << "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<MediaContainer commandID=\"" << commandId << "\" location=\"navigation\">";
+
+ msg << "<Timeline location=\"navigation\" state=\"stopped\" time=\"0\" type=\"photo\" />";
+ msg << "<Timeline location=\"navigation\" state=\"stopped\" time=\"0\" type=\"music\" />";
+
+ msg << GetTimelineXml();
+
+ msg << "</MediaContainer>";
+ return msg.str();
+ }
+
+ std::string SubscriptionManager::GetTimelineXml() {
+ int current = 0, total = 0, speed;
+ bool play = false, forward;
+ cVideo *pVid = NULL;
+ if (!m_pStatus->PlayerStopped && m_pStatus->pControl) {
+ m_pStatus->pControl->GetIndex(current, total);
+ current = current / m_pStatus->pControl->FramesPerSecond() * 1000;
+ total = total / m_pStatus->pControl->FramesPerSecond() * 1000;
+ m_pStatus->pControl->GetReplayMode(play, forward, speed);
+ pVid = m_pStatus->pVideo;
+ }
+
+ std::stringstream msg;
+
+ msg << "<Timeline location=\"navigation\" state=\"";
+ if (m_pStatus->PlayerStopped) msg << "stopped";
+ else if (!play) msg << "paused";
+ else msg << "playing";
+
+ msg << "\" time=\"" << current << "\" type=\"video\"";
+ if (!m_pStatus->PlayerStopped) {
+ msg << " duration=\"" << total << "\"";
+ msg << " seekRange=\"0-" << total << "\"";
+ msg << " controllable=\"true\"";
+ msg << " machineIdentifier=\"" << (pVid ? pVid->m_pServer->GetUuid() : "") << "\"";
+ msg << " protocol=\"http\"";
+ msg << " address=\"" << (pVid ? pVid->m_pServer->GetHost() : "") << "\"";
+ msg << " port=\"" << (pVid ? pVid->m_pServer->GetPort() : 0) << "\"";
+ msg << " guid=\"" << Config::GetInstance().GetUUID() << "\"";
+ msg << " containerKey=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\"";
+ msg << " key=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\"";
+ msg << " ratingKey=\"" << (pVid ? pVid->m_iRatingKey : 900000) << "\"";
+ msg << " volume=\"" << m_pStatus->Volume << "\"";
+ msg << " shuffle=\"false\"";
+ }
+ msg << "/>";
+ return msg.str();
+ }
+
+ void SubscriptionManager::Cleanup() {
+ m_myLock.Lock(&m_myMutex);
+ for (std::map<std::string, Subscriber>::iterator it = m_mSubcribers.begin(); it != m_mSubcribers.end(); ++it) {
+ Subscriber subs = it->second;
+ if (subs.m_iAge > 30) {
+ m_mSubcribers.erase(it);
+ }
+ }
+ }
+
+ Subscriber::Subscriber(std::string protocol, std::string host, int port, std::string uuid, std::string commandId) {
+ m_sProtocol = protocol;
+ int pos = host.find(":");
+ m_sHost = host.substr(0, pos - 1);
+ m_iPort = port;
+ m_sUuid = uuid;
+ m_iCommandId = commandId;
+ m_iAge = 0;
+ }
+
+ void Subscriber::SendUpdate(std::string msg, bool isNav) {
+ //dsyslog("[plex]: '%s'", __FUNCTION__);
+ ++m_iAge;
+ try {
+ Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
+ "/:/timeline", Poco::Net::HTTPMessage::HTTP_1_1);
+
+ PlexHelper::AddHttpHeader(Request);
+
+ Poco::Net::HTTPClientSession session(m_sHost, m_iPort);
+
+ Request.setContentLength(msg.length());
+ session.sendRequest(Request) << msg;
+
+ Poco::Net::HTTPResponse response;
+ session.receiveResponse(response);
+
+ } catch (Poco::Exception &e) { }
+ }
+
+ ActionManager::ActionManager() { }
+
+ void ActionManager::AddAction(cVideo video) {
+ m_myLock.Lock(&m_myMutex);
+ m_Action = video;
+ m_isAction = true;
+ }
+
+ cVideo ActionManager::GetAction() {
+ m_myLock.Lock(&m_myMutex);
+ m_isAction = false;
+ return m_Action;
+ }
+
+ bool ActionManager::IsAction() {
+ //m_myLock.Lock(&m_myMutex);
+ return m_isAction;
+ }
+
+ cSubscriberStatus::cSubscriberStatus() {
+ PlayerStopped = true;
+ pControl = NULL;
+ }
+
+ void cSubscriberStatus::Replaying(const cControl *DvbPlayerControl, const char *Name, const char *FileName,
+ bool On) {
+ //dsyslog("[plex]: '%s'", __FUNCTION__);
+ PlayerStopped = !On;
+
+ if (PlayerStopped) {
+ cMyPlugin::PlayingFile = false;
+ }
+
+ pControl = const_cast<cControl *>(DvbPlayerControl);
+ cHlsPlayerControl *hlsControl = dynamic_cast<cHlsPlayerControl *>(pControl);
+ if (hlsControl) {
+ pVideo = &hlsControl->m_Video;
+ } else if (cMyPlugin::PlayingFile) {
+ pVideo = &cMyPlugin::CurrentVideo;
+ } else {
+ pVideo = NULL;
+ pControl = NULL;
+ }
+
+ SubscriptionManager::GetInstance().Notify();
+ }
} // Namespace
diff --git a/SubscriptionManager.h b/SubscriptionManager.h
index 55facef..fb86e75 100644
--- a/SubscriptionManager.h
+++ b/SubscriptionManager.h
@@ -11,97 +11,111 @@
#include "hlsPlayerControl.h"
#include "PVideo.h"
-namespace plexclient
-{
-
-class cSubscriberStatus : public cStatus
-{
-protected:
- virtual void Replaying(const cControl *DvbPlayerControl, const char *Name, const char *FileName, bool On);
-
-public:
- cSubscriberStatus();
- bool PlayerPaused;
- bool PlayerStopped;
- cControl* pControl;
- cVideo* pVideo;
- int Volume;
-
-};
-
-class Subscriber
-{
- friend class SubscriptionManager;
-public:
- std::string m_iCommandId;
- Subscriber() {};
- Subscriber(std::string protocol, std::string host, int port, std::string uuid, std::string commandId);
-
- std::string GetUuid() {
- return m_sUuid;
- }
-
- void SendUpdate(std::string msg, bool isNav);
-
- virtual std::string to_string() {
- return "Subscriber-> Host: " + m_sHost + "; Port: " + std::string(itoa(m_iPort)) + "; Uuid:" + m_sUuid + "; CmdID:" + m_iCommandId;
- }
-
-private:
- std::string m_sProtocol;
- std::string m_sHost;
- int m_iPort;
- std::string m_sUuid;
-
- int m_iAge;
-};
-
-
-class SubscriptionManager
-{
-public:
- static SubscriptionManager& GetInstance() {
- static SubscriptionManager instance;
- return instance;
- }
- void AddSubscriber(Subscriber subs);
- void RemoveSubscriber(std::string uuid);
- void UpdateSubscriber(std::string uuid, std::string commandId);
- std::string GetMsg(std::string commandId);
- void Notify();
-
-private:
- SubscriptionManager();
- cMutexLock m_myLock;
- cMutex m_myMutex;
- std::map<std::string, Subscriber> m_mSubcribers;
- cSubscriberStatus* m_pStatus;
- bool m_bStoppedSent;
-
- void ReportProgress();
- void NotifyServer();
- void Cleanup();
- std::string GetTimelineXml();
-};
-
-class ActionManager
-{
-public:
- static ActionManager& GetInstance() {
- static ActionManager instance;
- return instance;
- }
- void AddAction(cVideo video);
- cVideo GetAction();
- bool IsAction();
-
-private:
- cMutexLock m_myLock;
- cMutex m_myMutex;
- ActionManager();
- cVideo m_Action;
- bool m_isAction;
-};
+namespace plexclient {
+
+ class cSubscriberStatus : public cStatus {
+ protected:
+ virtual void Replaying(const cControl *DvbPlayerControl, const char *Name, const char *FileName, bool On);
+
+ public:
+ cSubscriberStatus();
+
+ bool PlayerPaused;
+ bool PlayerStopped;
+ cControl *pControl;
+ cVideo *pVideo;
+ int Volume;
+
+ };
+
+ class Subscriber {
+ friend class SubscriptionManager;
+
+ public:
+ std::string m_iCommandId;
+
+ Subscriber() { };
+
+ Subscriber(std::string protocol, std::string host, int port, std::string uuid, std::string commandId);
+
+ std::string GetUuid() {
+ return m_sUuid;
+ }
+
+ void SendUpdate(std::string msg, bool isNav);
+
+ virtual std::string to_string() {
+ return "Subscriber-> Host: " + m_sHost + "; Port: " + std::string(itoa(m_iPort)) + "; Uuid:" + m_sUuid +
+ "; CmdID:" + m_iCommandId;
+ }
+
+ private:
+ std::string m_sProtocol;
+ std::string m_sHost;
+ int m_iPort;
+ std::string m_sUuid;
+
+ int m_iAge;
+ };
+
+
+ class SubscriptionManager {
+ public:
+ static SubscriptionManager &GetInstance() {
+ static SubscriptionManager instance;
+ return instance;
+ }
+
+ void AddSubscriber(Subscriber subs);
+
+ void RemoveSubscriber(std::string uuid);
+
+ void UpdateSubscriber(std::string uuid, std::string commandId);
+
+ std::string GetMsg(std::string commandId);
+
+ void Notify();
+
+ private:
+ SubscriptionManager();
+
+ cMutexLock m_myLock;
+ cMutex m_myMutex;
+ std::map<std::string, Subscriber> m_mSubcribers;
+ cSubscriberStatus *m_pStatus;
+ bool m_bStoppedSent;
+
+ void ReportProgress();
+
+ void NotifyServer();
+
+ void Cleanup();
+
+ std::string GetTimelineXml();
+ };
+
+ class ActionManager {
+ public:
+ static ActionManager &GetInstance() {
+ static ActionManager instance;
+ return instance;
+ }
+
+ void AddAction(cVideo video);
+
+ cVideo GetAction();
+
+ bool IsAction();
+
+ private:
+ cMutexLock m_myLock;
+ cMutex m_myMutex;
+
+ ActionManager();
+
+ cVideo m_Action;
+ bool m_isAction;
+ };
}
diff --git a/XmlObject.cpp b/XmlObject.cpp
index 8c01dd7..c13cbed 100644
--- a/XmlObject.cpp
+++ b/XmlObject.cpp
@@ -1,170 +1,158 @@
#include "XmlObject.h"
#include <vdr/tools.h>
-namespace plexclient
-{
-std::string XmlObject::GetNodeValue(Poco::XML::Node* pNode)
-{
- std::string value;
- if(pNode != 0) {
- value = pNode->getNodeValue();
- }
- return value;
-}
-
-int XmlObject::GetNodeValueAsInt(Poco::XML::Node* pNode)
-{
- int value = -1;
- if(pNode != 0) {
- try {
- value = atoi(pNode->getNodeValue().c_str());
- } catch(Poco::Exception) {}
- }
- return value;
-}
-
-long XmlObject::GetNodeValueAsLong(Poco::XML::Node* pNode)
-{
- long value = -1;
- if(pNode != 0) {
- try {
- value = atol(pNode->getNodeValue().c_str());
- } catch(Poco::Exception) {}
- }
- return value;
-}
-
-double XmlObject::GetNodeValueAsDouble(Poco::XML::Node* pNode)
-{
- double value = -1;
- if(pNode != 0) {
- try {
- value = atod(pNode->getNodeValue().c_str());
- } catch(Poco::Exception) {}
- }
- return value;
-}
-
-bool XmlObject::GetNodeValueAsBool(Poco::XML::Node* pNode)
-{
- bool value = false;
- if(pNode != 0) {
- value = pNode->getNodeValue() == "1";
- }
- return value;
-}
-
-Poco::Timestamp XmlObject::GetNodeValueAsTimeStamp(Poco::XML::Node* pNode)
-{
- Poco::Timestamp value;
- if(pNode != 0) {
- try {
- long lValue = atol(pNode->nodeValue().c_str());
- value = Poco::Timestamp(lValue);
- } catch (Poco::Exception) {}
- }
- return value;
-}
-
-Poco::DateTime XmlObject::GetNodeValueAsDateTime(Poco::XML::Node* pNode)
-{
- Poco::DateTime value;
- if(pNode != 0) {
- try {
- std::string format = "%Y-%m-%d";
- std::string val = pNode->nodeValue();
- int diff;
- value = Poco::DateTimeParser::parse(format, val, diff);
- } catch (Poco::Exception) {}
- }
- return value;
-}
-
-MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node* pNode)
-{
- MediaType type = MediaType::UNDEF;
-
- if(pNode != 0) {
- std::string sType = pNode->nodeValue();
- if (Poco::icompare(sType, "photo") == 0) {
- type = MediaType::PHOTO;
- } else if (Poco::icompare(sType, "movie") == 0) {
- type = MediaType::MOVIE;
- } else if (Poco::icompare(sType, "music") == 0) {
- type = MediaType::MUSIC;
- } else if (Poco::icompare(sType, "show") == 0) {
- type = MediaType::SHOW;
- } else if (Poco::icompare(sType, "season") == 0) {
- type = MediaType::SEASON;
- } else if (Poco::icompare(sType, "episode") == 0) {
- type = MediaType::EPISODE;
- } else if (Poco::icompare(sType, "clip") == 0) {
- type = MediaType::CLIP;
- }
- }
- return type;
-}
-
-StreamType XmlObject::GetNodeValueAsStreamType(Poco::XML::Node* pNode)
-{
- StreamType type = StreamType::sUNDEF;
-
- if(pNode != 0) {
- int iType = GetNodeValueAsInt(pNode);
- switch(iType) {
- case 1:
- type = StreamType::sVIDEO;
- break;
- case 2:
- type = StreamType::sAUDIO;
- break;
- case 3:
- type = StreamType::sSUBTITLE;
- break;
- default:
- type = StreamType::sUNDEF;
- break;
- }
- }
- return type;
-}
-
-PlaylistType XmlObject::GetNodeValueAsPlaylistType(Poco::XML::Node* pNode)
-{
- PlaylistType type = PlaylistType::Undef;
-
- if(pNode != 0) {
- std::string sType = pNode->nodeValue();
- if (Poco::icompare(sType, "photo") == 0) {
- type = PlaylistType::Photo;
- } else if (Poco::icompare(sType, "video") == 0) {
- type = PlaylistType::Video;
- } else if (Poco::icompare(sType, "audio") == 0) {
- type = PlaylistType::Audio;
- }
- }
- return type;
-}
-
-ExtraType XmlObject::GetNodeValueAsExtraType(Poco::XML::Node* pNode)
-{
- ExtraType type = ExtraType::Unkown;
-
- if(pNode != 0) {
- int iType = GetNodeValueAsInt(pNode);
- switch(iType) {
- case 1:
- type = ExtraType::Trailer;
- break;
- case 5:
- type = ExtraType::BehindTheScenes;
- break;
- default:
- type = ExtraType::Unkown;
- break;
- }
- }
- return type;
-}
+namespace plexclient {
+ std::string XmlObject::GetNodeValue(Poco::XML::Node *pNode) {
+ std::string value;
+ if (pNode != 0) {
+ value = pNode->getNodeValue();
+ }
+ return value;
+ }
+
+ int XmlObject::GetNodeValueAsInt(Poco::XML::Node *pNode) {
+ int value = -1;
+ if (pNode != 0) {
+ try {
+ value = atoi(pNode->getNodeValue().c_str());
+ } catch (Poco::Exception) { }
+ }
+ return value;
+ }
+
+ long XmlObject::GetNodeValueAsLong(Poco::XML::Node *pNode) {
+ long value = -1;
+ if (pNode != 0) {
+ try {
+ value = atol(pNode->getNodeValue().c_str());
+ } catch (Poco::Exception) { }
+ }
+ return value;
+ }
+
+ double XmlObject::GetNodeValueAsDouble(Poco::XML::Node *pNode) {
+ double value = -1;
+ if (pNode != 0) {
+ try {
+ value = atod(pNode->getNodeValue().c_str());
+ } catch (Poco::Exception) { }
+ }
+ return value;
+ }
+
+ bool XmlObject::GetNodeValueAsBool(Poco::XML::Node *pNode) {
+ bool value = false;
+ if (pNode != 0) {
+ value = pNode->getNodeValue() == "1";
+ }
+ return value;
+ }
+
+ Poco::Timestamp XmlObject::GetNodeValueAsTimeStamp(Poco::XML::Node *pNode) {
+ Poco::Timestamp value;
+ if (pNode != 0) {
+ try {
+ long lValue = atol(pNode->nodeValue().c_str());
+ value = Poco::Timestamp(lValue);
+ } catch (Poco::Exception) { }
+ }
+ return value;
+ }
+
+ Poco::DateTime XmlObject::GetNodeValueAsDateTime(Poco::XML::Node *pNode) {
+ Poco::DateTime value;
+ if (pNode != 0) {
+ try {
+ std::string format = "%Y-%m-%d";
+ std::string val = pNode->nodeValue();
+ int diff;
+ value = Poco::DateTimeParser::parse(format, val, diff);
+ } catch (Poco::Exception) { }
+ }
+ return value;
+ }
+
+ MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node *pNode) {
+ MediaType type = MediaType::UNDEF;
+
+ if (pNode != 0) {
+ std::string sType = pNode->nodeValue();
+ if (Poco::icompare(sType, "photo") == 0) {
+ type = MediaType::PHOTO;
+ } else if (Poco::icompare(sType, "movie") == 0) {
+ type = MediaType::MOVIE;
+ } else if (Poco::icompare(sType, "music") == 0) {
+ type = MediaType::MUSIC;
+ } else if (Poco::icompare(sType, "show") == 0) {
+ type = MediaType::SHOW;
+ } else if (Poco::icompare(sType, "season") == 0) {
+ type = MediaType::SEASON;
+ } else if (Poco::icompare(sType, "episode") == 0) {
+ type = MediaType::EPISODE;
+ } else if (Poco::icompare(sType, "clip") == 0) {
+ type = MediaType::CLIP;
+ }
+ }
+ return type;
+ }
+
+ StreamType XmlObject::GetNodeValueAsStreamType(Poco::XML::Node *pNode) {
+ StreamType type = StreamType::sUNDEF;
+
+ if (pNode != 0) {
+ int iType = GetNodeValueAsInt(pNode);
+ switch (iType) {
+ case 1:
+ type = StreamType::sVIDEO;
+ break;
+ case 2:
+ type = StreamType::sAUDIO;
+ break;
+ case 3:
+ type = StreamType::sSUBTITLE;
+ break;
+ default:
+ type = StreamType::sUNDEF;
+ break;
+ }
+ }
+ return type;
+ }
+
+ PlaylistType XmlObject::GetNodeValueAsPlaylistType(Poco::XML::Node *pNode) {
+ PlaylistType type = PlaylistType::Undef;
+
+ if (pNode != 0) {
+ std::string sType = pNode->nodeValue();
+ if (Poco::icompare(sType, "photo") == 0) {
+ type = PlaylistType::Photo;
+ } else if (Poco::icompare(sType, "video") == 0) {
+ type = PlaylistType::Video;
+ } else if (Poco::icompare(sType, "audio") == 0) {
+ type = PlaylistType::Audio;
+ }
+ }
+ return type;
+ }
+
+ ExtraType XmlObject::GetNodeValueAsExtraType(Poco::XML::Node *pNode) {
+ ExtraType type = ExtraType::Unkown;
+
+ if (pNode != 0) {
+ int iType = GetNodeValueAsInt(pNode);
+ switch (iType) {
+ case 1:
+ type = ExtraType::Trailer;
+ break;
+ case 5:
+ type = ExtraType::BehindTheScenes;
+ break;
+ default:
+ type = ExtraType::Unkown;
+ break;
+ }
+ }
+ return type;
+ }
}
diff --git a/XmlObject.h b/XmlObject.h
index 4c64a6c..942e061 100644
--- a/XmlObject.h
+++ b/XmlObject.h
@@ -10,31 +10,47 @@
#include <Poco/String.h>
#include <Poco/Exception.h>
-namespace plexclient
-{
-
-enum class MediaType {UNDEF = 0, MOVIE, SHOW, SEASON, EPISODE, MUSIC, PHOTO, CLIP, PLAYLIST};
-enum class PlaylistType { Undef, Video, Audio, Photo };
-enum class StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3};
-enum class ExtraType { Unkown = 0, Trailer = 1, BehindTheScenes = 5 };
-
-class XmlObject
-{
-protected:
- static std::string GetNodeValue(Poco::XML::Node* pNode);
- static int GetNodeValueAsInt(Poco::XML::Node* pNode);
- static long GetNodeValueAsLong(Poco::XML::Node* pNode);
- static double GetNodeValueAsDouble(Poco::XML::Node* pNode);
- static bool GetNodeValueAsBool(Poco::XML::Node* pNode);
- static Poco::Timestamp GetNodeValueAsTimeStamp(Poco::XML::Node* pNode);
- static Poco::DateTime GetNodeValueAsDateTime(Poco::XML::Node* pNode);
- static MediaType GetNodeValueAsMediaType(Poco::XML::Node* pNode);
- static StreamType GetNodeValueAsStreamType(Poco::XML::Node* pNode);
- static PlaylistType GetNodeValueAsPlaylistType(Poco::XML::Node* pNode);
- static ExtraType GetNodeValueAsExtraType(Poco::XML::Node* pNode);
-
-private:
-};
+namespace plexclient {
+
+ enum class MediaType {
+ UNDEF = 0, MOVIE, SHOW, SEASON, EPISODE, MUSIC, PHOTO, CLIP, PLAYLIST
+ };
+ enum class PlaylistType {
+ Undef, Video, Audio, Photo
+ };
+ enum class StreamType {
+ sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3
+ };
+ enum class ExtraType {
+ Unkown = 0, Trailer = 1, BehindTheScenes = 5
+ };
+
+ class XmlObject {
+ protected:
+ static std::string GetNodeValue(Poco::XML::Node *pNode);
+
+ static int GetNodeValueAsInt(Poco::XML::Node *pNode);
+
+ static long GetNodeValueAsLong(Poco::XML::Node *pNode);
+
+ static double GetNodeValueAsDouble(Poco::XML::Node *pNode);
+
+ static bool GetNodeValueAsBool(Poco::XML::Node *pNode);
+
+ static Poco::Timestamp GetNodeValueAsTimeStamp(Poco::XML::Node *pNode);
+
+ static Poco::DateTime GetNodeValueAsDateTime(Poco::XML::Node *pNode);
+
+ static MediaType GetNodeValueAsMediaType(Poco::XML::Node *pNode);
+
+ static StreamType GetNodeValueAsStreamType(Poco::XML::Node *pNode);
+
+ static PlaylistType GetNodeValueAsPlaylistType(Poco::XML::Node *pNode);
+
+ static ExtraType GetNodeValueAsExtraType(Poco::XML::Node *pNode);
+
+ private:
+ };
}
diff --git a/browserGrid.cpp b/browserGrid.cpp
index 4fcbb2f..8cebb83 100644
--- a/browserGrid.cpp
+++ b/browserGrid.cpp
@@ -7,320 +7,315 @@
#include "pictureCache.h"
#include "tokendefinitions.h"
-cBrowserGrid::cBrowserGrid(std::shared_ptr<skindesignerapi::cOsdView> rootView) : cViewGridNavigator(rootView)
-{
- m_pBackground = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::background));
- m_pHeader = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::header));
- m_pfooter = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::footer));
- m_pInfopane = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::infopane));
- m_pWatch = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::watch));
- m_pScrollbar = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int)eViewElementsRoot::scrollbar));
- m_lastsecond = 0;
-
- m_pService = NULL;
- m_pContainer = NULL;
- m_viewEntryIndex = 0;
- m_redrawBackground = true;
-
- Config *conf = &Config::GetInstance();
- if(conf->DefaultViewMode == ViewMode::Cover) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int)eViewGrids::cover) ));
- SetGridDimensions(conf->CoverGridRows, conf->CoverGridColumns);
- } else if(conf->DefaultViewMode == ViewMode::Detail) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int)eViewGrids::detail) ));
- SetGridDimensions(conf->DetailGridRows, conf->DetailGridColumns);
- } else if(conf->DefaultViewMode == ViewMode::List) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int)eViewGrids::list) ));
- SetGridDimensions(conf->ListGridRows, conf->ListGridColumns);
- }
-
- SwitchGrid(m_viewEntryIndex);
- SwitchView();
+cBrowserGrid::cBrowserGrid(std::shared_ptr<skindesignerapi::cOsdView> rootView) : cViewGridNavigator(rootView) {
+ m_pBackground = std::shared_ptr<skindesignerapi::cViewElement>(
+ rootView->GetViewElement((int) eViewElementsRoot::background));
+ m_pHeader = std::shared_ptr<skindesignerapi::cViewElement>(
+ rootView->GetViewElement((int) eViewElementsRoot::header));
+ m_pfooter = std::shared_ptr<skindesignerapi::cViewElement>(
+ rootView->GetViewElement((int) eViewElementsRoot::footer));
+ m_pInfopane = std::shared_ptr<skindesignerapi::cViewElement>(
+ rootView->GetViewElement((int) eViewElementsRoot::infopane));
+ m_pWatch = std::shared_ptr<skindesignerapi::cViewElement>(rootView->GetViewElement((int) eViewElementsRoot::watch));
+ m_pScrollbar = std::shared_ptr<skindesignerapi::cViewElement>(
+ rootView->GetViewElement((int) eViewElementsRoot::scrollbar));
+ m_lastsecond = 0;
+
+ m_pService = NULL;
+ m_pContainer = NULL;
+ m_viewEntryIndex = 0;
+ m_redrawBackground = true;
+
+ Config *conf = &Config::GetInstance();
+ if (conf->DefaultViewMode == ViewMode::Cover) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int) eViewGrids::cover)));
+ SetGridDimensions(conf->CoverGridRows, conf->CoverGridColumns);
+ } else if (conf->DefaultViewMode == ViewMode::Detail) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int) eViewGrids::detail)));
+ SetGridDimensions(conf->DetailGridRows, conf->DetailGridColumns);
+ } else if (conf->DefaultViewMode == ViewMode::List) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(rootView->GetViewGrid((int) eViewGrids::list)));
+ SetGridDimensions(conf->ListGridRows, conf->ListGridColumns);
+ }
+
+ SwitchGrid(m_viewEntryIndex);
+ SwitchView();
}
-cBrowserGrid::~cBrowserGrid()
-{
- m_vServerElements.clear();
- m_vElements.clear();
+cBrowserGrid::~cBrowserGrid() {
+ m_vServerElements.clear();
+ m_vElements.clear();
}
-void cBrowserGrid::Clear()
-{
- m_pBackground->Clear();
- m_pfooter->Clear();
- m_pInfopane->Clear();
- m_pWatch->Clear();
- m_pGrid->Clear();
+void cBrowserGrid::Clear() {
+ m_pBackground->Clear();
+ m_pfooter->Clear();
+ m_pInfopane->Clear();
+ m_pWatch->Clear();
+ m_pGrid->Clear();
}
-void cBrowserGrid::Flush()
-{
- if(m_redrawBackground){
- m_pBackground->Display();
- m_redrawBackground = false;
- }
-
- cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
- m_pGrid->Display();
- m_pScrollbar->Display();
-
- m_pRootView->Display();
+void cBrowserGrid::Flush() {
+ if (m_redrawBackground) {
+ m_pBackground->Display();
+ m_redrawBackground = false;
+ }
+
+ cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
+ m_pGrid->Display();
+ m_pScrollbar->Display();
+
+ m_pRootView->Display();
}
-void cBrowserGrid::SwitchView(ViewMode mode)
-{
- auto selObj = SelectedObject();
- if(!selObj) return;
-
- Config *conf = &Config::GetInstance();
- conf->DefaultViewMode = mode;
- if(conf->DefaultViewMode == ViewMode::Cover) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int)eViewGrids::cover) ));
- SetGridDimensions(conf->CoverGridRows, conf->CoverGridColumns);
- } else if(conf->DefaultViewMode == ViewMode::Detail) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int)eViewGrids::detail) ));
- SetGridDimensions(conf->DetailGridRows, conf->DetailGridColumns);
- } else if(conf->DefaultViewMode == ViewMode::List) {
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int)eViewGrids::list) ));
- SetGridDimensions(conf->ListGridRows, conf->ListGridColumns);
- }
-
- int activePos = selObj->AbsolutePosition;
- //ProcessData();
-
- for(std::vector<cGridElement*>::iterator it = m_vElements.begin(); it != m_vElements.end(); ++it) {
- cGridElement *elem = *it;
- elem->Position = -1;
- elem->Dirty();
- elem->SetPosition(-1,-1);
- }
-
- m_pGrid->Clear();
- m_startIndex = activePos;
- m_setIterator = true;
- FilterElements(0);
+void cBrowserGrid::SwitchView(ViewMode mode) {
+ auto selObj = SelectedObject();
+ if (!selObj) return;
+
+ Config *conf = &Config::GetInstance();
+ conf->DefaultViewMode = mode;
+ if (conf->DefaultViewMode == ViewMode::Cover) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int) eViewGrids::cover)));
+ SetGridDimensions(conf->CoverGridRows, conf->CoverGridColumns);
+ } else if (conf->DefaultViewMode == ViewMode::Detail) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int) eViewGrids::detail)));
+ SetGridDimensions(conf->DetailGridRows, conf->DetailGridColumns);
+ } else if (conf->DefaultViewMode == ViewMode::List) {
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(m_pRootView->GetViewGrid((int) eViewGrids::list)));
+ SetGridDimensions(conf->ListGridRows, conf->ListGridColumns);
+ }
+
+ int activePos = selObj->AbsolutePosition;
+ //ProcessData();
+
+ for (std::vector<cGridElement *>::iterator it = m_vElements.begin(); it != m_vElements.end(); ++it) {
+ cGridElement *elem = *it;
+ elem->Position = -1;
+ elem->Dirty();
+ elem->SetPosition(-1, -1);
+ }
+
+ m_pGrid->Clear();
+ m_startIndex = activePos;
+ m_setIterator = true;
+ FilterElements(0);
}
-void cBrowserGrid::NextViewMode()
-{
- ViewMode mode = Config::GetInstance().DefaultViewMode;
- if(mode == ViewMode::Cover) {
- mode = ViewMode::Detail;
- } else if(mode == ViewMode::Detail) {
- mode = ViewMode::List;
- } else if(mode == ViewMode::List) {
- mode = ViewMode::Cover;
- }
- SwitchView(mode);
+void cBrowserGrid::NextViewMode() {
+ ViewMode mode = Config::GetInstance().DefaultViewMode;
+ if (mode == ViewMode::Cover) {
+ mode = ViewMode::Detail;
+ } else if (mode == ViewMode::Detail) {
+ mode = ViewMode::List;
+ } else if (mode == ViewMode::List) {
+ mode = ViewMode::Cover;
+ }
+ SwitchView(mode);
}
-void cBrowserGrid::SwitchGrid(int index)
-{
- m_pHeader->Clear();
- m_pHeader->ClearTokens();
- m_pHeader->AddIntToken((int)eTokenGridInt::columns, m_columns);
- m_pHeader->AddIntToken((int)eTokenGridInt::rows, m_rows);
- m_pHeader->AddIntToken((int)eTokenGridInt::totalcount, m_vElements.size());
-
- if(plexclient::plexgdm::GetInstance().GetFirstServer()) {
- if(m_viewEntryIndex < (int)Config::GetInstance().m_viewentries.size()) {
- ViewEntry entry = Config::GetInstance().m_viewentries[index];
- m_pHeader->AddStringToken((int)eTokenGridStr::tabname, tr(entry.Name.c_str()));
- m_pService = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( plexclient::plexgdm::GetInstance().GetFirstServer(), entry.PlexPath ) );
- m_pContainer = m_pService->GetSection(m_pService->StartUri);
- m_bServersAreRoot = false;
- m_vServerElements.clear();
- } else {
- //Server View
- m_pHeader->AddStringToken((int)eTokenGridStr::tabname, tr("Library"));
- m_pService = NULL;
- m_pContainer = NULL;
- m_bServersAreRoot = true;
- SetServerElements();
- }
- } else {
- m_pHeader->AddStringToken((int)eTokenGridStr::tabname, tr("No Plex Media Server found."));
- m_pInfopane->AddStringToken((int)eTokenGridStr::title, tr("No Plex Media Server found."));
- m_pService = NULL;
- m_pContainer = NULL;
- }
- ProcessData();
- auto selObj = SelectedObject();
- if(selObj) {
- selObj->AddTokens(m_pHeader, false);
- m_pHeader->AddIntToken((int)eTokenGridInt::position, selObj->AbsolutePosition);
- }
-
- DrawBackground();
+void cBrowserGrid::SwitchGrid(int index) {
+ m_pHeader->Clear();
+ m_pHeader->ClearTokens();
+ m_pHeader->AddIntToken((int) eTokenGridInt::columns, m_columns);
+ m_pHeader->AddIntToken((int) eTokenGridInt::rows, m_rows);
+ m_pHeader->AddIntToken((int) eTokenGridInt::totalcount, m_vElements.size());
+
+ if (plexclient::plexgdm::GetInstance().GetFirstServer()) {
+ if (m_viewEntryIndex < (int) Config::GetInstance().m_viewentries.size()) {
+ ViewEntry entry = Config::GetInstance().m_viewentries[index];
+ m_pHeader->AddStringToken((int) eTokenGridStr::tabname, tr(entry.Name.c_str()));
+ m_pService = std::shared_ptr<plexclient::Plexservice>(
+ new plexclient::Plexservice(plexclient::plexgdm::GetInstance().GetFirstServer(), entry.PlexPath));
+ m_pContainer = m_pService->GetSection(m_pService->StartUri);
+ m_bServersAreRoot = false;
+ m_vServerElements.clear();
+ } else {
+ //Server View
+ m_pHeader->AddStringToken((int) eTokenGridStr::tabname, tr("Library"));
+ m_pService = NULL;
+ m_pContainer = NULL;
+ m_bServersAreRoot = true;
+ SetServerElements();
+ }
+ } else {
+ m_pHeader->AddStringToken((int) eTokenGridStr::tabname, tr("No Plex Media Server found."));
+ m_pInfopane->AddStringToken((int) eTokenGridStr::title, tr("No Plex Media Server found."));
+ m_pService = NULL;
+ m_pContainer = NULL;
+ }
+ ProcessData();
+ auto selObj = SelectedObject();
+ if (selObj) {
+ selObj->AddTokens(m_pHeader, false);
+ m_pHeader->AddIntToken((int) eTokenGridInt::position, selObj->AbsolutePosition);
+ }
+
+ DrawBackground();
}
-void cBrowserGrid::SetServerElements()
-{
- m_vServerElements.clear();
+void cBrowserGrid::SetServerElements() {
+ m_vServerElements.clear();
- for(std::vector<plexclient::PlexServer>::iterator it = plexclient::plexgdm::GetInstance().GetPlexservers().begin(); it != plexclient::plexgdm::GetInstance().GetPlexservers().end(); ++it) {
- for(std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_serverViewentries.begin(); vEntry != Config::GetInstance().m_serverViewentries.end(); ++vEntry) {
- m_vServerElements.push_back(cServerElement(&(*it), vEntry->PlexPath, vEntry->Name));
- }
- }
+ for (std::vector<plexclient::PlexServer>::iterator it = plexclient::plexgdm::GetInstance().GetPlexservers().begin();
+ it != plexclient::plexgdm::GetInstance().GetPlexservers().end(); ++it) {
+ for (std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_serverViewentries.begin();
+ vEntry != Config::GetInstance().m_serverViewentries.end(); ++vEntry) {
+ m_vServerElements.push_back(cServerElement(&(*it), vEntry->PlexPath, vEntry->Name));
+ }
+ }
}
-void cBrowserGrid::ProcessData()
-{
- m_vElements.clear();
-
- if(m_vServerElements.size() > 0) {
- for(auto it = m_vServerElements.begin(); it !=m_vServerElements.end(); ++it) {
- cServerElement *elem = &(*it);
- m_vElements.push_back(elem);
- }
- } else if (m_pContainer) {
- if (!m_pService->IsRoot()) {
- m_vElements.push_back(&m_Dummy);
- m_Dummy.Dirty();
- }
-
- if(m_pContainer->m_vVideos.size() > 0) {
- for(std::vector<plexclient::cVideo>::iterator it = m_pContainer->m_vVideos.begin(); it != m_pContainer->m_vVideos.end(); ++it) {
- plexclient::cVideo *elem = &(*it);
- m_vElements.push_back(elem);
- }
- }
- if(m_pContainer->m_vDirectories.size() > 0) {
- for(std::vector<plexclient::Directory>::iterator it = m_pContainer->m_vDirectories.begin(); it != m_pContainer->m_vDirectories.end(); ++it) {
- plexclient::Directory *elem = &(*it);
- m_vElements.push_back(elem);
- }
- }
- }
-
- int pos = 0;
- for(std::vector<cGridElement*>::iterator it = m_vElements.begin(); it != m_vElements.end(); ++it) {
- cGridElement *elem = *it;
- elem->AbsolutePosition = pos++;
- }
-
- m_startIndex = 0;
-
- m_pGrid->Clear();
- m_setIterator = true;
- FilterElements(0);
+void cBrowserGrid::ProcessData() {
+ m_vElements.clear();
+
+ if (m_vServerElements.size() > 0) {
+ for (auto it = m_vServerElements.begin(); it != m_vServerElements.end(); ++it) {
+ cServerElement *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ } else if (m_pContainer) {
+ if (!m_pService->IsRoot()) {
+ m_vElements.push_back(&m_Dummy);
+ m_Dummy.Dirty();
+ }
+
+ if (m_pContainer->m_vVideos.size() > 0) {
+ for (std::vector<plexclient::cVideo>::iterator it = m_pContainer->m_vVideos.begin();
+ it != m_pContainer->m_vVideos.end(); ++it) {
+ plexclient::cVideo *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ }
+ if (m_pContainer->m_vDirectories.size() > 0) {
+ for (std::vector<plexclient::Directory>::iterator it = m_pContainer->m_vDirectories.begin();
+ it != m_pContainer->m_vDirectories.end(); ++it) {
+ plexclient::Directory *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ }
+ }
+
+ int pos = 0;
+ for (std::vector<cGridElement *>::iterator it = m_vElements.begin(); it != m_vElements.end(); ++it) {
+ cGridElement *elem = *it;
+ elem->AbsolutePosition = pos++;
+ }
+
+ m_startIndex = 0;
+
+ m_pGrid->Clear();
+ m_setIterator = true;
+ FilterElements(0);
}
-eOSState cBrowserGrid::NavigateSelect()
-{
- if(m_setIterator) return eOSState::osContinue;;
- plexclient::Directory* dir = dynamic_cast<plexclient::Directory*>(SelectedObject());
- if(dir) {
- m_pContainer = m_pService->GetSection(dir->m_sKey);
- ProcessData();
- return eOSState::osContinue;
- } else if(dynamic_cast<cDummyElement*>(SelectedObject())) {
- return NavigateBack();
- } else if(cServerElement* srv = dynamic_cast<cServerElement*>(SelectedObject())) {
- m_pService = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( srv->Server() ) );
- m_pContainer = m_pService->GetSection(srv->StartPath());
- m_vServerElements.clear();
- ProcessData();
- return eOSState::osContinue;
- } else if(dynamic_cast<plexclient::cVideo*>(SelectedObject())) {
- return eOSState::osUser1;
- } else return eOSState::osEnd;
+eOSState cBrowserGrid::NavigateSelect() {
+ if (m_setIterator) return eOSState::osContinue;;
+ plexclient::Directory *dir = dynamic_cast<plexclient::Directory *>(SelectedObject());
+ if (dir) {
+ m_pContainer = m_pService->GetSection(dir->m_sKey);
+ ProcessData();
+ return eOSState::osContinue;
+ } else if (dynamic_cast<cDummyElement *>(SelectedObject())) {
+ return NavigateBack();
+ } else if (cServerElement *srv = dynamic_cast<cServerElement *>(SelectedObject())) {
+ m_pService = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice(srv->Server()));
+ m_pContainer = m_pService->GetSection(srv->StartPath());
+ m_vServerElements.clear();
+ ProcessData();
+ return eOSState::osContinue;
+ } else if (dynamic_cast<plexclient::cVideo *>(SelectedObject())) {
+ return eOSState::osUser1;
+ } else return eOSState::osEnd;
}
-eOSState cBrowserGrid::NavigateBack()
-{
- if(m_setIterator) return eOSState::osContinue;;
- std::shared_ptr<plexclient::MediaContainer> pCont = NULL;
- if(m_pService) {
- pCont = m_pService->GetLastSection();
- }
-
- if(pCont) {
- m_pContainer = pCont;
- ProcessData();
- return eOSState::osContinue;
-
- } else if(m_bServersAreRoot && m_pService) {
- m_pContainer = NULL;
- m_pService = NULL;
- SetServerElements();
- ProcessData();
- return eOSState::osContinue;
- }
- return eOSState::osEnd;
+eOSState cBrowserGrid::NavigateBack() {
+ if (m_setIterator) return eOSState::osContinue;;
+ std::shared_ptr<plexclient::MediaContainer> pCont = NULL;
+ if (m_pService) {
+ pCont = m_pService->GetLastSection();
+ }
+
+ if (pCont) {
+ m_pContainer = pCont;
+ ProcessData();
+ return eOSState::osContinue;
+
+ } else if (m_bServersAreRoot && m_pService) {
+ m_pContainer = NULL;
+ m_pService = NULL;
+ SetServerElements();
+ ProcessData();
+ return eOSState::osContinue;
+ }
+ return eOSState::osEnd;
}
-void cBrowserGrid::DrawGrid()
-{
- m_pHeader->Display();
- DrawInfopane();
- DrawFooter();
- DrawScrollbar();
+void cBrowserGrid::DrawGrid() {
+ m_pHeader->Display();
+ DrawInfopane();
+ DrawFooter();
+ DrawScrollbar();
}
-void cBrowserGrid::DrawBackground()
-{
- m_redrawBackground = true;
- m_pBackground->ClearTokens();
-
- /*auto video = dynamic_cast<plexclient::Video*>(SelectedObject());
- if(video) {
- bool cached = false;
- std::string path = cPictureCache::GetInstance().GetPath(video->ArtUri(), 1920, 1080, cached);
- m_pBackground->AddStringToken("selecteditembackground", path);
- }
- */
- m_pBackground->AddIntToken((int)eTokenBackgroundInt::isdirectory, 1);
- m_pBackground->AddStringToken((int)eTokenBackgroundStr::currentdirectorybackground, "/path");
- m_pBackground->AddIntToken((int)eTokenBackgroundInt::viewmode, Config::GetInstance().DefaultViewMode);
+void cBrowserGrid::DrawBackground() {
+ m_redrawBackground = true;
+ m_pBackground->ClearTokens();
+
+ /*auto video = dynamic_cast<plexclient::Video*>(SelectedObject());
+ if(video) {
+ bool cached = false;
+ std::string path = cPictureCache::GetInstance().GetPath(video->ArtUri(), 1920, 1080, cached);
+ m_pBackground->AddStringToken("selecteditembackground", path);
+ }
+ */
+ m_pBackground->AddIntToken((int) eTokenBackgroundInt::isdirectory, 1);
+ m_pBackground->AddStringToken((int) eTokenBackgroundStr::currentdirectorybackground, "/path");
+ m_pBackground->AddIntToken((int) eTokenBackgroundInt::viewmode, Config::GetInstance().DefaultViewMode);
}
-void cBrowserGrid::DrawInfopane()
-{
- m_pInfopane->Clear();
- if(SelectedObject()) {
- SelectedObject()->AddTokens(m_pInfopane, true);
- m_pInfopane->AddIntToken((int)eTokenGridInt::columns, m_columns);
- m_pInfopane->AddIntToken((int)eTokenGridInt::rows, m_rows);
- m_pInfopane->AddIntToken((int)eTokenGridInt::totalcount, m_vElements.size());
- m_pInfopane->AddIntToken((int)eTokenGridInt::position, SelectedObject()->AbsolutePosition);
- }
- m_pInfopane->Display();
+void cBrowserGrid::DrawInfopane() {
+ m_pInfopane->Clear();
+ if (SelectedObject()) {
+ SelectedObject()->AddTokens(m_pInfopane, true);
+ m_pInfopane->AddIntToken((int) eTokenGridInt::columns, m_columns);
+ m_pInfopane->AddIntToken((int) eTokenGridInt::rows, m_rows);
+ m_pInfopane->AddIntToken((int) eTokenGridInt::totalcount, m_vElements.size());
+ m_pInfopane->AddIntToken((int) eTokenGridInt::position, SelectedObject()->AbsolutePosition);
+ }
+ m_pInfopane->Display();
}
-void cBrowserGrid::DrawFooter()
-{
- //if (!active)
- // return;
- cString nextTab = "Library";
- if(m_viewEntryIndex + 1 < (int)Config::GetInstance().m_viewentries.size()) {
- nextTab = Config::GetInstance().m_viewentries[m_viewEntryIndex + 1].Name.c_str();
- } else if(m_viewEntryIndex + 1 == (int)Config::GetInstance().m_viewentries.size() + 1) {
- nextTab = Config::GetInstance().m_viewentries[0].Name.c_str();
- }
- cString details = "Details";
+void cBrowserGrid::DrawFooter() {
+ //if (!active)
+ // return;
+ cString nextTab = "Library";
+ if (m_viewEntryIndex + 1 < (int) Config::GetInstance().m_viewentries.size()) {
+ nextTab = Config::GetInstance().m_viewentries[m_viewEntryIndex + 1].Name.c_str();
+ } else if (m_viewEntryIndex + 1 == (int) Config::GetInstance().m_viewentries.size() + 1) {
+ nextTab = Config::GetInstance().m_viewentries[0].Name.c_str();
+ }
+ cString details = "Details";
- string textGreen = tr(details);
- string textYellow = tr(nextTab);
- string textRed = "";
- string textBlue = tr("Switch View");
+ string textGreen = tr(details);
+ string textYellow = tr(nextTab);
+ string textRed = "";
+ string textBlue = tr("Switch View");
- if(auto vid = dynamic_cast<plexclient::cVideo*>(SelectedObject()) ) {
- if(vid->m_iViewCount > 0) textRed = tr("Unscrobble");
- else textRed = tr("Scrobble");
- }
+ if (auto vid = dynamic_cast<plexclient::cVideo *>(SelectedObject())) {
+ if (vid->m_iViewCount > 0) textRed = tr("Unscrobble");
+ else textRed = tr("Scrobble");
+ }
- int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
+ int colorKeys[4] = {Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3};
- m_pfooter->Clear();
- m_pfooter->ClearTokens();
+ m_pfooter->Clear();
+ m_pfooter->ClearTokens();
- m_pfooter->AddStringToken((int)eTokenFooterStr::red, textRed.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::green, textGreen.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::yellow, textYellow.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::blue, textBlue.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::red, textRed.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::green, textGreen.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::yellow, textYellow.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::blue, textBlue.c_str());
for (int button = 0; button < 4; button++) {
bool isRed = false;
@@ -343,146 +338,137 @@ void cBrowserGrid::DrawFooter()
default:
break;
}
- m_pfooter->AddIntToken(0 + button, isRed);
- m_pfooter->AddIntToken(4 + button, isGreen);
- m_pfooter->AddIntToken(8 + button, isYellow);
+ m_pfooter->AddIntToken(0 + button, isRed);
+ m_pfooter->AddIntToken(4 + button, isGreen);
+ m_pfooter->AddIntToken(8 + button, isYellow);
m_pfooter->AddIntToken(12 + button, isBlue);
}
- m_pfooter->Display();
+ m_pfooter->Display();
}
-void cBrowserGrid::DrawScrollbar()
-{
- m_pScrollbar->Clear();
- m_pScrollbar->ClearTokens();
-
- if ((int)m_vElements.size() > (m_columns * m_rows)) {
- int currentRow = SelectedObject()->AbsolutePosition / m_columns;
- int totalRows = ceil((double) m_vElements.size() / m_columns);
-
- int scrollBarHeight = 100.0 / totalRows * m_rows;
-
- int offset = 100.0 / totalRows * currentRow;
- if(offset >= 100 - scrollBarHeight) {
- offset = 100.0 - scrollBarHeight;
- }
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::height, scrollBarHeight);
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::offset, offset);
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::hasscrollbar, true);
- } else {
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::hasscrollbar, false);
- }
-
- m_pScrollbar->Display();
+void cBrowserGrid::DrawScrollbar() {
+ m_pScrollbar->Clear();
+ m_pScrollbar->ClearTokens();
+
+ if ((int) m_vElements.size() > (m_columns * m_rows)) {
+ int currentRow = SelectedObject()->AbsolutePosition / m_columns;
+ int totalRows = ceil((double) m_vElements.size() / m_columns);
+
+ int scrollBarHeight = 100.0 / totalRows * m_rows;
+
+ int offset = 100.0 / totalRows * currentRow;
+ if (offset >= 100 - scrollBarHeight) {
+ offset = 100.0 - scrollBarHeight;
+ }
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::height, scrollBarHeight);
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::offset, offset);
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::hasscrollbar, true);
+ } else {
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::hasscrollbar, false);
+ }
+
+ m_pScrollbar->Display();
}
-void cBrowserGrid::NextTab()
-{
- m_viewEntryIndex++;
- if(m_viewEntryIndex > (int)Config::GetInstance().m_viewentries.size()) {
- m_viewEntryIndex = 0;
- }
- SwitchGrid(m_viewEntryIndex);
+void cBrowserGrid::NextTab() {
+ m_viewEntryIndex++;
+ if (m_viewEntryIndex > (int) Config::GetInstance().m_viewentries.size()) {
+ m_viewEntryIndex = 0;
+ }
+ SwitchGrid(m_viewEntryIndex);
}
-void cBrowserGrid::PrevTab()
-{
- m_viewEntryIndex--;
- if(m_viewEntryIndex < 0) {
- m_viewEntryIndex = Config::GetInstance().m_viewentries.size();
- }
- SwitchGrid(m_viewEntryIndex);
+void cBrowserGrid::PrevTab() {
+ m_viewEntryIndex--;
+ if (m_viewEntryIndex < 0) {
+ m_viewEntryIndex = Config::GetInstance().m_viewentries.size();
+ }
+ SwitchGrid(m_viewEntryIndex);
}
-bool cBrowserGrid::DrawTime()
-{
- time_t t = time(0); // get time now
- struct tm * now = localtime(&t);
- int sec = now->tm_sec;
- if (sec == m_lastsecond)
- return false;
-
- int min = now->tm_min;
- int hour = now->tm_hour;
- int hourMinutes = hour%12 * 5 + min / 12;
-
- char monthname[20];
- char monthshort[10];
- strftime(monthshort, sizeof(monthshort), "%b", now);
- strftime(monthname, sizeof(monthname), "%B", now);
-
- m_pWatch->Clear();
- m_pWatch->ClearTokens();
- m_pWatch->AddIntToken((int)eTokenTimeInt::sec, sec);
- m_pWatch->AddIntToken((int)eTokenTimeInt::min, min);
- m_pWatch->AddIntToken((int)eTokenTimeInt::hour, hour);
- m_pWatch->AddIntToken((int)eTokenTimeInt::hmins, hourMinutes);
- m_pWatch->AddIntToken((int)eTokenTimeInt::year, now->tm_year + 1900);
- m_pWatch->AddIntToken((int)eTokenTimeInt::day, now->tm_mday);
- m_pWatch->AddStringToken((int)eTokenTimeStr::time, *TimeString(t));
- m_pWatch->AddStringToken((int)eTokenTimeStr::monthname, monthname);
- m_pWatch->AddStringToken((int)eTokenTimeStr::monthnameshort, monthshort);
- m_pWatch->AddStringToken((int)eTokenTimeStr::month, *cString::sprintf("%02d", now->tm_mon + 1));
- m_pWatch->AddStringToken((int)eTokenTimeStr::dayleadingzero, *cString::sprintf("%02d", now->tm_mday));
- m_pWatch->AddStringToken((int)eTokenTimeStr::dayname, *WeekDayNameFull(now->tm_wday));
- m_pWatch->AddStringToken((int)eTokenTimeStr::daynameshort, *WeekDayName(now->tm_wday));
- m_pWatch->Display();
-
- m_lastsecond = sec;
- return true;
+bool cBrowserGrid::DrawTime() {
+ time_t t = time(0); // get time now
+ struct tm *now = localtime(&t);
+ int sec = now->tm_sec;
+ if (sec == m_lastsecond)
+ return false;
+
+ int min = now->tm_min;
+ int hour = now->tm_hour;
+ int hourMinutes = hour % 12 * 5 + min / 12;
+
+ char monthname[20];
+ char monthshort[10];
+ strftime(monthshort, sizeof(monthshort), "%b", now);
+ strftime(monthname, sizeof(monthname), "%B", now);
+
+ m_pWatch->Clear();
+ m_pWatch->ClearTokens();
+ m_pWatch->AddIntToken((int) eTokenTimeInt::sec, sec);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::min, min);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::hour, hour);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::hmins, hourMinutes);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::year, now->tm_year + 1900);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::day, now->tm_mday);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::time, *TimeString(t));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::monthname, monthname);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::monthnameshort, monthshort);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::month, *cString::sprintf("%02d", now->tm_mon + 1));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::dayleadingzero, *cString::sprintf("%02d", now->tm_mday));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::dayname, *WeekDayNameFull(now->tm_wday));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::daynameshort, *WeekDayName(now->tm_wday));
+ m_pWatch->Display();
+
+ m_lastsecond = sec;
+ return true;
}
/*
* cDummyElement
*/
-cDummyElement::cDummyElement()
-{
- m_title = "../";
+cDummyElement::cDummyElement() {
+ m_title = "../";
}
-cDummyElement::cDummyElement(std::string title)
-{
- m_title = title;
+cDummyElement::cDummyElement(std::string title) {
+ m_title = title;
}
-void cDummyElement::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached)
-{
- if(clear) grid->ClearTokens();
- grid->AddIntToken((int)eTokenGridInt::isdummy, 1);
- grid->AddStringToken((int)eTokenGridStr::title, m_title.c_str());
+void cDummyElement::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear,
+ std::function<void(cGridElement *)> OnCached) {
+ if (clear) grid->ClearTokens();
+ grid->AddIntToken((int) eTokenGridInt::isdummy, 1);
+ grid->AddStringToken((int) eTokenGridStr::title, m_title.c_str());
}
-std::string cDummyElement::GetTitle()
-{
- return "Dummy";
+std::string cDummyElement::GetTitle() {
+ return "Dummy";
}
/*
* cServerElement
*/
-cServerElement::cServerElement(plexclient::PlexServer* server, std::string startPath, std::string startName)
-{
- m_pServer = server;
- m_sStartPath = startPath;
- m_sStartName = startName;
+cServerElement::cServerElement(plexclient::PlexServer *server, std::string startPath, std::string startName) {
+ m_pServer = server;
+ m_sStartPath = startPath;
+ m_sStartName = startName;
}
-void cServerElement::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached)
-{
- if(clear) grid->ClearTokens();
- grid->AddIntToken((int)eTokenGridInt::isserver, 1);
- grid->AddStringToken((int)eTokenGridStr::title, m_pServer->GetServerName().c_str());
- grid->AddStringToken((int)eTokenGridStr::serverstartpointname, m_sStartName.c_str());
- grid->AddStringToken((int)eTokenGridStr::serverip, m_pServer->GetHost().c_str());
- grid->AddIntToken((int)eTokenGridInt::serverport, m_pServer->GetPort());
- grid->AddStringToken((int)eTokenGridStr::serverversion, m_pServer->GetVersion().c_str());
- grid->AddIntToken((int)eTokenGridInt::viewmode, Config::GetInstance().DefaultViewMode);
+void cServerElement::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear,
+ std::function<void(cGridElement *)> OnCached) {
+ if (clear) grid->ClearTokens();
+ grid->AddIntToken((int) eTokenGridInt::isserver, 1);
+ grid->AddStringToken((int) eTokenGridStr::title, m_pServer->GetServerName().c_str());
+ grid->AddStringToken((int) eTokenGridStr::serverstartpointname, m_sStartName.c_str());
+ grid->AddStringToken((int) eTokenGridStr::serverip, m_pServer->GetHost().c_str());
+ grid->AddIntToken((int) eTokenGridInt::serverport, m_pServer->GetPort());
+ grid->AddStringToken((int) eTokenGridStr::serverversion, m_pServer->GetVersion().c_str());
+ grid->AddIntToken((int) eTokenGridInt::viewmode, Config::GetInstance().DefaultViewMode);
}
-std::string cServerElement::GetTitle()
-{
- return "Server";
+std::string cServerElement::GetTitle() {
+ return "Server";
}
diff --git a/browserGrid.h b/browserGrid.h
index 12b35f8..19cd501 100644
--- a/browserGrid.h
+++ b/browserGrid.h
@@ -11,76 +11,99 @@
//#include "viewHeader.h"
#include <libskindesignerapi/osdelements.h>
-class cDummyElement : public cGridElement
-{
+class cDummyElement : public cGridElement {
private:
- std::string m_title;
+ std::string m_title;
public:
- cDummyElement(std::string title);
- cDummyElement();
- virtual std::string GetTitle();
- virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL);
+ cDummyElement(std::string title);
+
+ cDummyElement();
+
+ virtual std::string GetTitle();
+
+ virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true,
+ std::function<void(cGridElement *)> OnCached = NULL);
};
-class cServerElement : public cGridElement
-{
+class cServerElement : public cGridElement {
private:
- plexclient::PlexServer* m_pServer;
- std::string m_sStartPath;
- std::string m_sStartName;
+ plexclient::PlexServer *m_pServer;
+ std::string m_sStartPath;
+ std::string m_sStartName;
public:
- cServerElement(plexclient::PlexServer* server, std::string startPath, std::string startName);
- virtual std::string GetTitle();
- virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL);
- std::string StartPath() { return m_sStartPath; }
- plexclient::PlexServer* Server() { return m_pServer; }
+ cServerElement(plexclient::PlexServer *server, std::string startPath, std::string startName);
+
+ virtual std::string GetTitle();
+
+ virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool clear = true,
+ std::function<void(cGridElement *)> OnCached = NULL);
+
+ std::string StartPath() { return m_sStartPath; }
+
+ plexclient::PlexServer *Server() { return m_pServer; }
};
-class cBrowserGrid : public cViewGridNavigator
-{
+class cBrowserGrid : public cViewGridNavigator {
private:
- //std::shared_ptr<cViewHeader> m_pViewHeader;
- std::shared_ptr<skindesignerapi::cViewElement> m_pHeader;
- std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
- std::shared_ptr<skindesignerapi::cViewElement> m_pfooter;
- std::shared_ptr<skindesignerapi::cViewElement> m_pInfopane;
- std::shared_ptr<skindesignerapi::cViewElement> m_pScrollbar;
- std::shared_ptr<skindesignerapi::cViewElement> m_pWatch;
- int m_lastsecond;
- int m_viewEntryIndex;
- bool m_redrawBackground;
-
- bool m_bServersAreRoot;
- std::vector<cServerElement> m_vServerElements;
- std::shared_ptr<plexclient::MediaContainer> m_pContainer;
- std::shared_ptr<plexclient::Plexservice> m_pService;
- cDummyElement m_Dummy;
-
- void ProcessData();
- void SetServerElements();
- void DrawFooter();
- void DrawBackground();
- void DrawInfopane();
- void DrawScrollbar();
+ //std::shared_ptr<cViewHeader> m_pViewHeader;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pHeader;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pfooter;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pInfopane;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pScrollbar;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pWatch;
+ int m_lastsecond;
+ int m_viewEntryIndex;
+ bool m_redrawBackground;
+
+ bool m_bServersAreRoot;
+ std::vector<cServerElement> m_vServerElements;
+ std::shared_ptr<plexclient::MediaContainer> m_pContainer;
+ std::shared_ptr<plexclient::Plexservice> m_pService;
+ cDummyElement m_Dummy;
+
+ void ProcessData();
+
+ void SetServerElements();
+
+ void DrawFooter();
+
+ void DrawBackground();
+
+ void DrawInfopane();
+
+ void DrawScrollbar();
public:
- cBrowserGrid(std::shared_ptr<skindesignerapi::cOsdView> rootView);
- ~cBrowserGrid();
- //cBrowserGrid(skindesignerapi::cViewGrid* viewGrid, std::shared_ptr<plexclient::Plexservice> service);
- std::shared_ptr<plexclient::MediaContainer> MediaContainer() { return m_pContainer; }
-
- void DrawGrid();
- void SwitchGrid(int index);
- void SwitchView(ViewMode mode = Config::GetInstance().DefaultViewMode);
- void NextViewMode();
- virtual eOSState NavigateSelect();
- virtual eOSState NavigateBack();
- void NextTab();
- void PrevTab();
- bool DrawTime();
- virtual void Flush();
- virtual void Clear();
+ cBrowserGrid(std::shared_ptr<skindesignerapi::cOsdView> rootView);
+
+ ~cBrowserGrid();
+
+ //cBrowserGrid(skindesignerapi::cViewGrid* viewGrid, std::shared_ptr<plexclient::Plexservice> service);
+ std::shared_ptr<plexclient::MediaContainer> MediaContainer() { return m_pContainer; }
+
+ void DrawGrid();
+
+ void SwitchGrid(int index);
+
+ void SwitchView(ViewMode mode = Config::GetInstance().DefaultViewMode);
+
+ void NextViewMode();
+
+ virtual eOSState NavigateSelect();
+
+ virtual eOSState NavigateBack();
+
+ void NextTab();
+
+ void PrevTab();
+
+ bool DrawTime();
+
+ virtual void Flush();
+
+ virtual void Clear();
};
#endif // CBROWSERGRID_H
diff --git a/cPlexOsdItem.cpp b/cPlexOsdItem.cpp
index 4e4272f..de8e4fc 100644
--- a/cPlexOsdItem.cpp
+++ b/cPlexOsdItem.cpp
@@ -1,45 +1,45 @@
#include "cPlexOsdItem.h"
-cPlexOsdItem::cPlexOsdItem(const char* title) :cOsdItem(title) {
- m_bVideo = false;
- m_bDir = false;
+cPlexOsdItem::cPlexOsdItem(const char *title) : cOsdItem(title) {
+ m_bVideo = false;
+ m_bDir = false;
}
-cPlexOsdItem::cPlexOsdItem(const char* title, std::shared_ptr<plexclient::Plexservice> service) :cOsdItem(title) {
- pservice = service;
- m_bVideo = false;
- m_bDir = false;
+cPlexOsdItem::cPlexOsdItem(const char *title, std::shared_ptr<plexclient::Plexservice> service) : cOsdItem(title) {
+ pservice = service;
+ m_bVideo = false;
+ m_bDir = false;
}
-cPlexOsdItem::cPlexOsdItem(const char* title, plexclient::cVideo* obj) :cOsdItem(title) {
- item = obj;
- m_bVideo = true;
- m_bDir = false;
+cPlexOsdItem::cPlexOsdItem(const char *title, plexclient::cVideo *obj) : cOsdItem(title) {
+ item = obj;
+ m_bVideo = true;
+ m_bDir = false;
}
-cPlexOsdItem::cPlexOsdItem(const char* title, plexclient::Directory* obj) :cOsdItem(title) {
- dir = obj;
- m_bDir = true;
- m_bVideo = false;
+cPlexOsdItem::cPlexOsdItem(const char *title, plexclient::Directory *obj) : cOsdItem(title) {
+ dir = obj;
+ m_bDir = true;
+ m_bVideo = false;
}
-cPlexOsdItem::cPlexOsdItem(const char* title, plexclient::Stream* obj) :cOsdItem(title) {
- stream = *obj;
- dir = NULL;
- item = NULL;
- pservice = NULL;
- m_bVideo = false;
- m_bDir = false;
+cPlexOsdItem::cPlexOsdItem(const char *title, plexclient::Stream *obj) : cOsdItem(title) {
+ stream = *obj;
+ dir = NULL;
+ item = NULL;
+ pservice = NULL;
+ m_bVideo = false;
+ m_bDir = false;
}
-plexclient::cVideo* cPlexOsdItem::GetAttachedVideo() {
- return item;
+plexclient::cVideo *cPlexOsdItem::GetAttachedVideo() {
+ return item;
}
-plexclient::Directory* cPlexOsdItem::GetAttachedDirectory() {
- return dir;
+plexclient::Directory *cPlexOsdItem::GetAttachedDirectory() {
+ return dir;
}
std::shared_ptr<plexclient::Plexservice> cPlexOsdItem::GetAttachedService() {
- return pservice;
+ return pservice;
}
diff --git a/cPlexOsdItem.h b/cPlexOsdItem.h
index b5e834f..195be97 100644
--- a/cPlexOsdItem.h
+++ b/cPlexOsdItem.h
@@ -12,42 +12,50 @@
#include "Directory.h"
#include "Plexservice.h"
-class cPlexOsdItem : public cOsdItem
-{
+class cPlexOsdItem : public cOsdItem {
private:
- plexclient::cVideo* item;
- plexclient::Directory* dir;
- plexclient::Stream stream;
- std::shared_ptr<plexclient::Plexservice> pservice;
- bool m_bVideo;
- bool m_bDir;
+ plexclient::cVideo *item;
+ plexclient::Directory *dir;
+ plexclient::Stream stream;
+ std::shared_ptr<plexclient::Plexservice> pservice;
+ bool m_bVideo;
+ bool m_bDir;
public:
- cPlexOsdItem(const char* title);
- cPlexOsdItem(const char* title, std::shared_ptr<plexclient::Plexservice> service);
- cPlexOsdItem(const char* title, plexclient::cVideo* obj);
- cPlexOsdItem(const char* title, plexclient::Directory* obj);
+ cPlexOsdItem(const char *title);
+
+ cPlexOsdItem(const char *title, std::shared_ptr<plexclient::Plexservice> service);
+
+ cPlexOsdItem(const char *title, plexclient::cVideo *obj);
+
+ cPlexOsdItem(const char *title, plexclient::Directory *obj);
+
/**
* @brief
* @param title Title
* @param obj will be copied
*/
- cPlexOsdItem(const char* title, plexclient::Stream* obj);
- plexclient::cVideo* GetAttachedVideo();
- plexclient::Directory* GetAttachedDirectory();
- plexclient::Stream& GetAttachedStream() { return stream; }
- std::shared_ptr<plexclient::Plexservice> GetAttachedService();
-
- bool IsVideo() const {
- return m_bVideo;
- }
- bool IsDir() const {
- return m_bDir;
- }
-
- //virtual eOSState ProcessKey(eKeys Key);
- //virtual void Set(void);
- //virtual void SetMenuItem(cSkinDisplayMenu* DisplayMenu, int Index, bool Current, bool Selectable);
+ cPlexOsdItem(const char *title, plexclient::Stream *obj);
+
+ plexclient::cVideo *GetAttachedVideo();
+
+ plexclient::Directory *GetAttachedDirectory();
+
+ plexclient::Stream &GetAttachedStream() { return stream; }
+
+ std::shared_ptr<plexclient::Plexservice> GetAttachedService();
+
+ bool IsVideo() const {
+ return m_bVideo;
+ }
+
+ bool IsDir() const {
+ return m_bDir;
+ }
+
+ //virtual eOSState ProcessKey(eKeys Key);
+ //virtual void Set(void);
+ //virtual void SetMenuItem(cSkinDisplayMenu* DisplayMenu, int Index, bool Current, bool Selectable);
};
#endif // CPLEXOSDITEM_H
diff --git a/detailView.cpp b/detailView.cpp
index 3055cb0..f44869d 100644
--- a/detailView.cpp
+++ b/detailView.cpp
@@ -2,102 +2,102 @@
#include "Config.h"
cDetailView::cDetailView(std::shared_ptr<skindesignerapi::cOsdView> detailView, plexclient::cVideo *video)
- : cViewGridNavigator(detailView)
-{
- m_pBackground = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::background));
- m_pfooter = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::footer));
- m_pInfo = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::info));
- m_pScrollbar = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::scrollbar));
- m_pWatch = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::watch));
-
- m_pVideo = video;
- m_drawall = true;
-
- m_pGrid = NULL;
- SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(detailView->GetViewGrid((int)eViewDetailViewGrids::extras)));
- SetGridDimensions(Config::GetInstance().ExtrasGridRows, Config::GetInstance().ExtrasGridColumns);
-
- m_vElements.clear();
-
- int pos = 0;
- for(auto it = m_pVideo->m_vExtras.begin(); it != m_pVideo->m_vExtras.end(); ++it) {
- plexclient::cVideo *elem = &(*it);
- elem->AbsolutePosition = pos++;;
- m_vElements.push_back(elem);
- }
-
- m_startIndex = 0;
-
- m_setIterator = true;
- FilterElements(0);
+ : cViewGridNavigator(detailView) {
+ m_pBackground = std::shared_ptr<skindesignerapi::cViewElement>(
+ detailView->GetViewElement((int) eViewElementsDetail::background));
+ m_pfooter = std::shared_ptr<skindesignerapi::cViewElement>(
+ detailView->GetViewElement((int) eViewElementsDetail::footer));
+ m_pInfo = std::shared_ptr<skindesignerapi::cViewElement>(
+ detailView->GetViewElement((int) eViewElementsDetail::info));
+ m_pScrollbar = std::shared_ptr<skindesignerapi::cViewElement>(
+ detailView->GetViewElement((int) eViewElementsDetail::scrollbar));
+ m_pWatch = std::shared_ptr<skindesignerapi::cViewElement>(
+ detailView->GetViewElement((int) eViewElementsDetail::watch));
+
+ m_pVideo = video;
+ m_drawall = true;
+
+ m_pGrid = NULL;
+ SetViewGrid(
+ std::shared_ptr<skindesignerapi::cViewGrid>(detailView->GetViewGrid((int) eViewDetailViewGrids::extras)));
+ SetGridDimensions(Config::GetInstance().ExtrasGridRows, Config::GetInstance().ExtrasGridColumns);
+
+ m_vElements.clear();
+
+ int pos = 0;
+ for (auto it = m_pVideo->m_vExtras.begin(); it != m_pVideo->m_vExtras.end(); ++it) {
+ plexclient::cVideo *elem = &(*it);
+ elem->AbsolutePosition = pos++;;
+ m_vElements.push_back(elem);
+ }
+
+ m_startIndex = 0;
+
+ m_setIterator = true;
+ FilterElements(0);
}
-void cDetailView::Flush()
-{
- if (m_drawall) {
- m_pBackground->Display();
- m_pInfo->Display();
- m_drawall = false;
- }
- m_pfooter->Display();
- m_pGrid->Display();
- m_pScrollbar->Display();
-
- m_pRootView->Display();
+void cDetailView::Flush() {
+ if (m_drawall) {
+ m_pBackground->Display();
+ m_pInfo->Display();
+ m_drawall = false;
+ }
+ m_pfooter->Display();
+ m_pGrid->Display();
+ m_pScrollbar->Display();
+
+ m_pRootView->Display();
}
-void cDetailView::Draw()
-{
- // Draw Grid
-
- DrawBackground();
- DrawFooter();
- DrawInfo();
- DrawScrollbar();
- DrawTime();
+void cDetailView::Draw() {
+ // Draw Grid
+
+ DrawBackground();
+ DrawFooter();
+ DrawInfo();
+ DrawScrollbar();
+ DrawTime();
}
-void cDetailView::Clear()
-{
- m_pBackground->Clear();
- m_pInfo->Clear();
- m_pScrollbar->Clear();
- m_pfooter->Clear();
- m_pGrid->Clear();
- m_pWatch->Clear();
+void cDetailView::Clear() {
+ m_pBackground->Clear();
+ m_pInfo->Clear();
+ m_pScrollbar->Clear();
+ m_pfooter->Clear();
+ m_pGrid->Clear();
+ m_pWatch->Clear();
}
-void cDetailView::DrawBackground()
-{
- m_pBackground->ClearTokens();
- bool art = m_pVideo->m_sArt.empty() == false;
- m_pBackground->AddIntToken((int)eTokenDetailBackgroundInt::hasfanart, art);
- if(art) m_pBackground->AddStringToken((int)eTokenDetailBackgroundStr::fanartpath, m_pVideo->m_sArt.c_str());
-
- bool cover = m_pVideo->m_sThumb.empty() == false;
- m_pBackground->AddIntToken((int)eTokenDetailBackgroundInt::hascover, cover);
- if(cover) m_pBackground->AddStringToken((int)eTokenDetailBackgroundStr::coverpath, m_pVideo->m_sThumb.c_str());
+void cDetailView::DrawBackground() {
+ m_pBackground->ClearTokens();
+ bool art = m_pVideo->m_sArt.empty() == false;
+ m_pBackground->AddIntToken((int) eTokenDetailBackgroundInt::hasfanart, art);
+ if (art) m_pBackground->AddStringToken((int) eTokenDetailBackgroundStr::fanartpath, m_pVideo->m_sArt.c_str());
+
+ bool cover = m_pVideo->m_sThumb.empty() == false;
+ m_pBackground->AddIntToken((int) eTokenDetailBackgroundInt::hascover, cover);
+ if (cover) m_pBackground->AddStringToken((int) eTokenDetailBackgroundStr::coverpath, m_pVideo->m_sThumb.c_str());
}
-void cDetailView::DrawFooter()
-{
- string textRed = tr("Play");
- string textGreen = tr("Rewind");
- string textYellow = "";
- string textBlue = "";
+void cDetailView::DrawFooter() {
+ string textRed = tr("Play");
+ string textGreen = tr("Rewind");
+ string textYellow = "";
+ string textBlue = "";
- if(m_pVideo->m_iViewCount > 0) textYellow = tr("Unscrobble");
- else textYellow = tr("Scrobble");
+ if (m_pVideo->m_iViewCount > 0) textYellow = tr("Unscrobble");
+ else textYellow = tr("Scrobble");
- int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
+ int colorKeys[4] = {Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3};
- m_pfooter->Clear();
- m_pfooter->ClearTokens();
+ m_pfooter->Clear();
+ m_pfooter->ClearTokens();
- m_pfooter->AddStringToken((int)eTokenFooterStr::red, textRed.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::green, textGreen.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::yellow, textYellow.c_str());
- m_pfooter->AddStringToken((int)eTokenFooterStr::blue, textBlue.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::red, textRed.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::green, textGreen.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::yellow, textYellow.c_str());
+ m_pfooter->AddStringToken((int) eTokenFooterStr::blue, textBlue.c_str());
for (int button = 0; button < 4; button++) {
bool isRed = false;
@@ -120,96 +120,91 @@ void cDetailView::DrawFooter()
default:
break;
}
- m_pfooter->AddIntToken(0 + button, isRed);
- m_pfooter->AddIntToken(4 + button, isGreen);
- m_pfooter->AddIntToken(8 + button, isYellow);
+ m_pfooter->AddIntToken(0 + button, isRed);
+ m_pfooter->AddIntToken(4 + button, isGreen);
+ m_pfooter->AddIntToken(8 + button, isYellow);
m_pfooter->AddIntToken(12 + button, isBlue);
}
- m_pfooter->Display();
+ m_pfooter->Display();
}
-void cDetailView::DrawInfo()
-{
- m_pInfo->Clear();
- m_pVideo->AddTokens(m_pInfo, true);
- m_pInfo->Display();
+void cDetailView::DrawInfo() {
+ m_pInfo->Clear();
+ m_pVideo->AddTokens(m_pInfo, true);
+ m_pInfo->Display();
}
-void cDetailView::DrawScrollbar()
-{
- m_pScrollbar->Clear();
- m_pScrollbar->ClearTokens();
-
- if ((int)m_vElements.size() > (m_columns * m_rows)) {
- int currentRow = SelectedObject()->AbsolutePosition / m_columns;
- int totalRows = ceil((double) m_vElements.size() / m_columns);
-
- int scrollBarHeight = 100.0 / totalRows * m_rows;
-
- int offset = 100.0 / totalRows * currentRow;
- if(offset >= 100 - scrollBarHeight) {
- offset = 100.0 - scrollBarHeight;
- }
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::height, scrollBarHeight);
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::offset, offset);
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::hasscrollbar, true);
- } else {
- m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::hasscrollbar, false);
- }
-
- m_pScrollbar->Display();
+void cDetailView::DrawScrollbar() {
+ m_pScrollbar->Clear();
+ m_pScrollbar->ClearTokens();
+
+ if ((int) m_vElements.size() > (m_columns * m_rows)) {
+ int currentRow = SelectedObject()->AbsolutePosition / m_columns;
+ int totalRows = ceil((double) m_vElements.size() / m_columns);
+
+ int scrollBarHeight = 100.0 / totalRows * m_rows;
+
+ int offset = 100.0 / totalRows * currentRow;
+ if (offset >= 100 - scrollBarHeight) {
+ offset = 100.0 - scrollBarHeight;
+ }
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::height, scrollBarHeight);
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::offset, offset);
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::hasscrollbar, true);
+ } else {
+ m_pScrollbar->AddIntToken((int) eTokenScrollbarInt::hasscrollbar, false);
+ }
+
+ m_pScrollbar->Display();
}
-bool cDetailView::DrawTime()
-{
- time_t t = time(0); // get time now
- struct tm * now = localtime(&t);
- int sec = now->tm_sec;
- if (sec == m_lastsecond)
- return false;
-
- int min = now->tm_min;
- int hour = now->tm_hour;
- int hourMinutes = hour%12 * 5 + min / 12;
-
- char monthname[20];
- char monthshort[10];
- strftime(monthshort, sizeof(monthshort), "%b", now);
- strftime(monthname, sizeof(monthname), "%B", now);
-
- m_pWatch->Clear();
- m_pWatch->ClearTokens();
- m_pWatch->AddIntToken((int)eTokenTimeInt::sec, sec);
- m_pWatch->AddIntToken((int)eTokenTimeInt::min, min);
- m_pWatch->AddIntToken((int)eTokenTimeInt::hour, hour);
- m_pWatch->AddIntToken((int)eTokenTimeInt::hmins, hourMinutes);
- m_pWatch->AddIntToken((int)eTokenTimeInt::year, now->tm_year + 1900);
- m_pWatch->AddIntToken((int)eTokenTimeInt::day, now->tm_mday);
- m_pWatch->AddStringToken((int)eTokenTimeStr::time, *TimeString(t));
- m_pWatch->AddStringToken((int)eTokenTimeStr::monthname, monthname);
- m_pWatch->AddStringToken((int)eTokenTimeStr::monthnameshort, monthshort);
- m_pWatch->AddStringToken((int)eTokenTimeStr::month, *cString::sprintf("%02d", now->tm_mon + 1));
- m_pWatch->AddStringToken((int)eTokenTimeStr::dayleadingzero, *cString::sprintf("%02d", now->tm_mday));
- m_pWatch->AddStringToken((int)eTokenTimeStr::dayname, *WeekDayNameFull(now->tm_wday));
- m_pWatch->AddStringToken((int)eTokenTimeStr::daynameshort, *WeekDayName(now->tm_wday));
- m_pWatch->Display();
-
- m_lastsecond = sec;
- return true;
+bool cDetailView::DrawTime() {
+ time_t t = time(0); // get time now
+ struct tm *now = localtime(&t);
+ int sec = now->tm_sec;
+ if (sec == m_lastsecond)
+ return false;
+
+ int min = now->tm_min;
+ int hour = now->tm_hour;
+ int hourMinutes = hour % 12 * 5 + min / 12;
+
+ char monthname[20];
+ char monthshort[10];
+ strftime(monthshort, sizeof(monthshort), "%b", now);
+ strftime(monthname, sizeof(monthname), "%B", now);
+
+ m_pWatch->Clear();
+ m_pWatch->ClearTokens();
+ m_pWatch->AddIntToken((int) eTokenTimeInt::sec, sec);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::min, min);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::hour, hour);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::hmins, hourMinutes);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::year, now->tm_year + 1900);
+ m_pWatch->AddIntToken((int) eTokenTimeInt::day, now->tm_mday);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::time, *TimeString(t));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::monthname, monthname);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::monthnameshort, monthshort);
+ m_pWatch->AddStringToken((int) eTokenTimeStr::month, *cString::sprintf("%02d", now->tm_mon + 1));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::dayleadingzero, *cString::sprintf("%02d", now->tm_mday));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::dayname, *WeekDayNameFull(now->tm_wday));
+ m_pWatch->AddStringToken((int) eTokenTimeStr::daynameshort, *WeekDayName(now->tm_wday));
+ m_pWatch->Display();
+
+ m_lastsecond = sec;
+ return true;
}
-eOSState cDetailView::NavigateSelect()
-{
- if(m_setIterator) return eOSState::osContinue;
-
- if(dynamic_cast<plexclient::cVideo*>(SelectedObject())) {
- return eOSState::osUser1;
- } else return eOSState::osBack;
+eOSState cDetailView::NavigateSelect() {
+ if (m_setIterator) return eOSState::osContinue;
+
+ if (dynamic_cast<plexclient::cVideo *>(SelectedObject())) {
+ return eOSState::osUser1;
+ } else return eOSState::osBack;
}
-eOSState cDetailView::NavigateBack()
-{
- if(m_setIterator) return eOSState::osContinue;
- return eOSState::osBack;
+eOSState cDetailView::NavigateBack() {
+ if (m_setIterator) return eOSState::osContinue;
+ return eOSState::osBack;
}
diff --git a/detailView.h b/detailView.h
index 67f3234..bf0eb33 100644
--- a/detailView.h
+++ b/detailView.h
@@ -8,34 +8,42 @@
#include <libskindesignerapi/osdelements.h>
#include <libskindesignerapi/skindesignerosdbase.h>
-class cDetailView : public cViewGridNavigator
-{
+class cDetailView : public cViewGridNavigator {
public:
- cDetailView(std::shared_ptr<skindesignerapi::cOsdView> detailView, plexclient::cVideo *video);
-
- void Draw();
- virtual void Flush();
- virtual eOSState NavigateSelect();
- virtual eOSState NavigateBack();
- plexclient::cVideo* GetVideo() { return m_pVideo; };
- virtual void Clear();
- bool DrawTime();
-
+ cDetailView(std::shared_ptr<skindesignerapi::cOsdView> detailView, plexclient::cVideo *video);
+
+ void Draw();
+
+ virtual void Flush();
+
+ virtual eOSState NavigateSelect();
+
+ virtual eOSState NavigateBack();
+
+ plexclient::cVideo *GetVideo() { return m_pVideo; };
+
+ virtual void Clear();
+
+ bool DrawTime();
+
private:
- std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
- std::shared_ptr<skindesignerapi::cViewElement> m_pfooter;
- std::shared_ptr<skindesignerapi::cViewElement> m_pInfo;
- std::shared_ptr<skindesignerapi::cViewElement> m_pScrollbar;
- std::shared_ptr<skindesignerapi::cViewElement> m_pWatch;
-
- plexclient::cVideo *m_pVideo;
- bool m_drawall;
- int m_lastsecond;
-
- void DrawBackground();
- void DrawFooter();
- void DrawInfo();
- void DrawScrollbar();
+ std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pfooter;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pInfo;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pScrollbar;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pWatch;
+
+ plexclient::cVideo *m_pVideo;
+ bool m_drawall;
+ int m_lastsecond;
+
+ void DrawBackground();
+
+ void DrawFooter();
+
+ void DrawInfo();
+
+ void DrawScrollbar();
};
#endif // CDETAILVIEW_H
diff --git a/device.cpp b/device.cpp
index 8ff82a7..2f9d141 100644
--- a/device.cpp
+++ b/device.cpp
@@ -1,61 +1,58 @@
#include "device.h"
-namespace plexclient
-{
-
-Connection::Connection(Poco::XML::Node* pNode, Device* parent)
-{
- m_pParent = parent;
-
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
-
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Connection") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
-
- m_sProtocol = GetNodeValue(pAttribs->getNamedItem("protocol"));
- m_sAddress = GetNodeValue(pAttribs->getNamedItem("address"));
- m_iPort = GetNodeValueAsInt(pAttribs->getNamedItem("port"));
- m_sUri = GetNodeValue(pAttribs->getNamedItem("uri"));
- m_bLocal = GetNodeValueAsBool(pAttribs->getNamedItem("local"));
-
- pAttribs->release();
- }
- pChildNode = it.nextNode();
- }
-}
-
-Device::Device(Poco::XML::Node* pNode, MediaContainer* parent)
-{
- m_pParent = parent;
-
- NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
- Poco::XML::Node* pChildNode = it.nextNode();
-
- while(pChildNode) {
- if(Poco::icompare(pChildNode->nodeName(), "Device") == 0) {
- Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
-
- m_sName = GetNodeValue(pAttribs->getNamedItem("name"));
- m_sProduct = GetNodeValue(pAttribs->getNamedItem("product"));
- m_sProvides = GetNodeValue(pAttribs->getNamedItem("provides"));
- m_sClientIdentifier = GetNodeValue(pAttribs->getNamedItem("clientIdentifier"));
- m_bOwned = GetNodeValueAsBool(pAttribs->getNamedItem("owned"));
- m_sAccessToken = GetNodeValue(pAttribs->getNamedItem("accessToken"));
- m_bHttpsRequired = GetNodeValueAsBool(pAttribs->getNamedItem("httpsRequired"));
- m_bPublicAddressMatches = GetNodeValueAsBool(pAttribs->getNamedItem("publicAddressMatches"));
- m_bPresence = GetNodeValueAsBool(pAttribs->getNamedItem("presence"));
- m_sSourceTitle = GetNodeValue(pAttribs->getNamedItem("sourceTitle"));
-
- pAttribs->release();
- } else if(Poco::icompare(pChildNode->nodeName(), "Connection") == 0) {
- m_vConnections.push_back(Connection(pChildNode, this));
- }
-
- pChildNode = it.nextNode();
- }
-}
+namespace plexclient {
+
+ Connection::Connection(Poco::XML::Node *pNode, Device *parent) {
+ m_pParent = parent;
+
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
+
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Connection") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+
+ m_sProtocol = GetNodeValue(pAttribs->getNamedItem("protocol"));
+ m_sAddress = GetNodeValue(pAttribs->getNamedItem("address"));
+ m_iPort = GetNodeValueAsInt(pAttribs->getNamedItem("port"));
+ m_sUri = GetNodeValue(pAttribs->getNamedItem("uri"));
+ m_bLocal = GetNodeValueAsBool(pAttribs->getNamedItem("local"));
+
+ pAttribs->release();
+ }
+ pChildNode = it.nextNode();
+ }
+ }
+
+ Device::Device(Poco::XML::Node *pNode, MediaContainer *parent) {
+ m_pParent = parent;
+
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node *pChildNode = it.nextNode();
+
+ while (pChildNode) {
+ if (Poco::icompare(pChildNode->nodeName(), "Device") == 0) {
+ Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
+
+ m_sName = GetNodeValue(pAttribs->getNamedItem("name"));
+ m_sProduct = GetNodeValue(pAttribs->getNamedItem("product"));
+ m_sProvides = GetNodeValue(pAttribs->getNamedItem("provides"));
+ m_sClientIdentifier = GetNodeValue(pAttribs->getNamedItem("clientIdentifier"));
+ m_bOwned = GetNodeValueAsBool(pAttribs->getNamedItem("owned"));
+ m_sAccessToken = GetNodeValue(pAttribs->getNamedItem("accessToken"));
+ m_bHttpsRequired = GetNodeValueAsBool(pAttribs->getNamedItem("httpsRequired"));
+ m_bPublicAddressMatches = GetNodeValueAsBool(pAttribs->getNamedItem("publicAddressMatches"));
+ m_bPresence = GetNodeValueAsBool(pAttribs->getNamedItem("presence"));
+ m_sSourceTitle = GetNodeValue(pAttribs->getNamedItem("sourceTitle"));
+
+ pAttribs->release();
+ } else if (Poco::icompare(pChildNode->nodeName(), "Connection") == 0) {
+ m_vConnections.push_back(Connection(pChildNode, this));
+ }
+
+ pChildNode = it.nextNode();
+ }
+ }
}
diff --git a/device.h b/device.h
index 5b28047..acba9c6 100644
--- a/device.h
+++ b/device.h
@@ -14,45 +14,42 @@
#include "XmlObject.h"
#include "MediaContainer.h"
-namespace plexclient
-{
-class Device;
-
-class Connection: private XmlObject
-{
-public:
- Connection(Poco::XML::Node* pNode, Device* parent);
-
- std::string m_sProtocol;
- std::string m_sAddress;
- int m_iPort;
- std::string m_sUri;
- bool m_bLocal;
-
- Device* m_pParent;
-
-};
-
-class Device: private XmlObject
-{
-public:
- Device(Poco::XML::Node* pNode, MediaContainer* parent);
-
- std::string m_sName;
- std::string m_sProduct;
- std::string m_sProvides;
- std::string m_sClientIdentifier;
- bool m_bOwned;
- std::string m_sAccessToken;
- bool m_bHttpsRequired;
- bool m_bPublicAddressMatches;
- bool m_bPresence;
- std::string m_sSourceTitle;
-
- std::vector<Connection> m_vConnections;
-
- MediaContainer* m_pParent;
-};
+namespace plexclient {
+ class Device;
+
+ class Connection : private XmlObject {
+ public:
+ Connection(Poco::XML::Node *pNode, Device *parent);
+
+ std::string m_sProtocol;
+ std::string m_sAddress;
+ int m_iPort;
+ std::string m_sUri;
+ bool m_bLocal;
+
+ Device *m_pParent;
+
+ };
+
+ class Device : private XmlObject {
+ public:
+ Device(Poco::XML::Node *pNode, MediaContainer *parent);
+
+ std::string m_sName;
+ std::string m_sProduct;
+ std::string m_sProvides;
+ std::string m_sClientIdentifier;
+ bool m_bOwned;
+ std::string m_sAccessToken;
+ bool m_bHttpsRequired;
+ bool m_bPublicAddressMatches;
+ bool m_bPresence;
+ std::string m_sSourceTitle;
+
+ std::vector<Connection> m_vConnections;
+
+ MediaContainer *m_pParent;
+ };
}
diff --git a/displayReplaySD.cpp b/displayReplaySD.cpp
index 0e4d01c..ff71e9a 100644
--- a/displayReplaySD.cpp
+++ b/displayReplaySD.cpp
@@ -1,43 +1,36 @@
#include "displayReplaySD.h"
-cDisplayReplaySD::cDisplayReplaySD(plexclient::cVideo* video) : cSkindesignerOsdObject(GetPluginStruct())
-{
+cDisplayReplaySD::cDisplayReplaySD(plexclient::cVideo *video) : cSkindesignerOsdObject(GetPluginStruct()) {
}
-cDisplayReplaySD::~cDisplayReplaySD()
-{
+cDisplayReplaySD::~cDisplayReplaySD() {
}
-skindesignerapi::cPluginStructure* cDisplayReplaySD::m_pPlugStructReplay = NULL;
-skindesignerapi::cPluginStructure* cDisplayReplaySD::GetPluginStruct()
-{
- if(m_pPlugStructReplay == NULL) {
- m_pPlugStructReplay = new skindesignerapi::cPluginStructure();
- m_pPlugStructReplay->name = "plexreplay";
- m_pPlugStructReplay->libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION;
- m_pPlugStructReplay->RegisterRootView("root.xml");
- }
- return m_pPlugStructReplay;
+skindesignerapi::cPluginStructure *cDisplayReplaySD::m_pPlugStructReplay = NULL;
+
+skindesignerapi::cPluginStructure *cDisplayReplaySD::GetPluginStruct() {
+ if (m_pPlugStructReplay == NULL) {
+ m_pPlugStructReplay = new skindesignerapi::cPluginStructure();
+ m_pPlugStructReplay->name = "plexreplay";
+ m_pPlugStructReplay->libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION;
+ m_pPlugStructReplay->RegisterRootView("root.xml");
+ }
+ return m_pPlugStructReplay;
}
-void cDisplayReplaySD::Show(void)
-{
+void cDisplayReplaySD::Show(void) {
}
-eOSState cDisplayReplaySD::ProcessKey(eKeys Key)
-{
- return eOSState::osContinue;
+eOSState cDisplayReplaySD::ProcessKey(eKeys Key) {
+ return eOSState::osContinue;
}
-void cDisplayReplaySD::Flush()
-{
+void cDisplayReplaySD::Flush() {
}
-void cDisplayReplaySD::SetCurrent(const char* Current)
-{
+void cDisplayReplaySD::SetCurrent(const char *Current) {
}
-void cDisplayReplaySD::SetMode(bool Play, bool Forward, int Speed)
-{
+void cDisplayReplaySD::SetMode(bool Play, bool Forward, int Speed) {
}
diff --git a/displayReplaySD.h b/displayReplaySD.h
index 8fc4593..e633e95 100644
--- a/displayReplaySD.h
+++ b/displayReplaySD.h
@@ -7,29 +7,33 @@
#include <libskindesignerapi/osdelements.h>
#include <libskindesignerapi/skindesignerosdbase.h>
-class cDisplayReplaySD : public skindesignerapi::cSkindesignerOsdObject
-{
+class cDisplayReplaySD : public skindesignerapi::cSkindesignerOsdObject {
private:
- static skindesignerapi::cPluginStructure* m_pPlugStructReplay;
- static skindesignerapi::cPluginStructure* GetPluginStruct();
-
- std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
- std::shared_ptr<skindesignerapi::cViewElement> m_pProgessbar;
- std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
- std::shared_ptr<skindesignerapi::cViewElement> m_pVideoinfo;
- std::shared_ptr<skindesignerapi::cViewElement> m_pTranscodeinfo;
-
+ static skindesignerapi::cPluginStructure *m_pPlugStructReplay;
+
+ static skindesignerapi::cPluginStructure *GetPluginStruct();
+
+ std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pProgessbar;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pVideoinfo;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pTranscodeinfo;
+
public:
- cDisplayReplaySD(plexclient::cVideo* video);
- ~cDisplayReplaySD();
-
- virtual void Show(void);
- virtual eOSState ProcessKey(eKeys Key);
-
- void Flush();
- void SetCurrent(const char *Current);
- void SetMode(bool Play, bool Forward, int Speed);
-
+ cDisplayReplaySD(plexclient::cVideo *video);
+
+ ~cDisplayReplaySD();
+
+ virtual void Show(void);
+
+ virtual eOSState ProcessKey(eKeys Key);
+
+ void Flush();
+
+ void SetCurrent(const char *Current);
+
+ void SetMode(bool Play, bool Forward, int Speed);
+
};
diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp
index 1ef8ada..fc0c7cb 100644
--- a/hlsPlayer.cpp
+++ b/hlsPlayer.cpp
@@ -21,726 +21,691 @@ const int BUFFERSIZE = 8192;
//--- cHlsSegmentLoader
-cHlsSegmentLoader::cHlsSegmentLoader(std::string startm3u8, plexclient::cVideo* pVideo)
-{
- m_pVideo = pVideo;
- m_newList = false;
- m_bufferFilled = false;
- m_lastLoadedSegment = 0;
- m_segmentsToBuffer = 2;
- m_streamlenght = 0;
- m_lastSegmentSize = 0;
- m_pBuffer = new uchar[BUFFERSIZE];
-
- // Initialize members
- m_pClientSession = NULL;
-
- m_ringBufferSize = MEGABYTE(1);
- m_pRingbuffer = NULL;
-
- m_startUri = Poco::URI(startm3u8);
- m_startParser = cM3u8Parser();
- m_indexParser = cM3u8Parser();
-}
-
-cHlsSegmentLoader::~cHlsSegmentLoader()
-{
- // Stop Thread
- Cancel(0);
-
- delete m_pClientSession;
- delete[] m_pBuffer;
- delete m_pRingbuffer;
-}
-
-void cHlsSegmentLoader::SkipEmptySegments(int segmentDuration)
-{
- pcrecpp::RE re("&offset=(\\d+)", pcrecpp::RE_Options(PCRE_CASELESS));
- int value;
- re.PartialMatch(m_startUri.getQuery(), &value);
- if (value > segmentDuration) {
- m_lastLoadedSegment = (value / segmentDuration) - 1;
- }
-}
-
-bool cHlsSegmentLoader::LoadM3u8(std::string uri)
-{
- //LOCK_THREAD;
- m_startUri = Poco::URI(uri);
- return (m_newList = true);
-}
-
-void cHlsSegmentLoader::Action(void)
-{
- if(!LoadLists()) return;
-
- m_ringBufferSize = MEGABYTE(Config::GetInstance().BufferSize);
-
- isyslog("[plex]%s Create Ringbuffer %d MB", __FUNCTION__, Config::GetInstance().BufferSize);
-
- m_pRingbuffer = new cRingBufferLinear(m_ringBufferSize, 2*TS_SIZE);
-
- while(Running()) {
- if(m_newList) {
- hlsMutex.Lock();
- m_bufferFilled = false;
- m_lastLoadedSegment = 0;
- LoadLists();
- m_newList = false;
- m_pRingbuffer->Clear();
- isyslog("[plex] Ringbuffer Cleared, loading new segments");
- hlsMutex.Unlock();
- }
- int count = 0;
- m_pRingbuffer->Get(count);
- if (!DoLoad() && count < TS_SIZE) {
- isyslog("[plex] No further segments to load and buffer empty, end of stream!");
- Cancel();
-
- }
- cCondWait::SleepMs(3);
- }
- StopLoader();
-}
-
-bool cHlsSegmentLoader::LoadLists(void)
-{
- if( LoadStartList() ) {
- if( false == LoadIndexList() ) {
- esyslog("[plex]LoadIndexList failed!");
- return false;
- }
- } else {
- esyslog("[plex]LoadStartList failed!");
- return false;
- }
- return true;
-}
-
-bool cHlsSegmentLoader::LoadIndexList(void)
-{
- bool res = false;
- try {
- if(m_startParser.MasterPlaylist && m_startParser.vPlaylistItems.size() > 0) {
- // Todo: make it universal, might only work for Plexmediaserver
- ConnectToServer();
-
- std::string startUri = m_startUri.toString();
- startUri = startUri.substr(0, startUri.find_last_of("/")+1);
-
- Poco::URI indexUri(startUri+m_startParser.vPlaylistItems[0].file);
-
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, indexUri.getPath());
- AddHeader(request);
- // same server
- m_pClientSession->sendRequest(request);
-
- Poco::Net::HTTPResponse responseStart;
- std::istream& indexFile = m_pClientSession->receiveResponse(responseStart);
-
- if(responseStart.getStatus() != 200) {
- esyslog("[plex]%s Response Not Valid", __FUNCTION__);
- Poco::StreamCopier::copyStream(indexFile, std::cout);
- return res;
- }
- m_indexParser = cM3u8Parser();
- res = m_indexParser.Parse(indexFile);
-
- if(res) {
- // Segment URI is relative to index.m3u8
- std::string path = indexUri.getPath();
- m_segmentUriPart = path.substr(0, path.find_last_of("/")+1);
- }
- if(m_indexParser.TargetDuration > 3) {
- m_segmentsToBuffer = 2;
- } else {
- m_segmentsToBuffer = 3;
- }
-
- SkipEmptySegments(m_indexParser.TargetDuration);
- m_lastSegmentSize = 0;
-
- // Get stream lenght
- m_streamlenght = 0;
- for(unsigned int i = 0; i < m_indexParser.vPlaylistItems.size(); i++) {
- m_streamlenght += m_indexParser.vPlaylistItems[i].length;
- }
- }
-
- } catch (Poco::Exception &exc) {
- esyslog("[plex] %s %s", __FUNCTION__, exc.displayText().c_str());
- res = false;
- }
- return res;
-}
-
-bool cHlsSegmentLoader::LoadStartList(void)
-{
- bool res = false;
- ConnectToServer();
- try {
- dsyslog("[plex]%s %s", __FUNCTION__, m_startUri.toString().c_str());
- Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, m_startUri.getPathAndQuery());
- AddHeader(request);
- m_pClientSession->sendRequest(request);
-
- Poco::Net::HTTPResponse responseStart;
- std::istream& startFile = m_pClientSession->receiveResponse(responseStart);
-
- if(responseStart.getStatus() != 200) {
- esyslog("[plex]%s Response Not Valid", __FUNCTION__);
- Poco::StreamCopier::copyStream(startFile, std::cout);
- return res;
- }
-
- m_startParser = cM3u8Parser();
- res = m_startParser.Parse(startFile);
- if(res) {
- // Get GUID
- pcrecpp::RE re("([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})", pcrecpp::RE_Options(PCRE_CASELESS));
- string value;
- re.PartialMatch(m_startParser.vPlaylistItems[0].file, &value);
- m_sessionCookie = value;
- }
- } catch (Poco::Exception &exc) {
- esyslog("[plex] %s %s", __FUNCTION__, exc.displayText().c_str());
- res = false;
- }
- return res;
-}
-
-int cHlsSegmentLoader::EstimateSegmentSize()
-{
- if(&m_startParser.vPlaylistItems[0] == NULL) {
- esyslog("[plex]%s first element NULL", __FUNCTION__);
- }
- double bandw = m_startParser.vPlaylistItems[0].bandwidth / 8.0 / 1000.0 / 1000.0;
-
- int len = m_indexParser.TargetDuration;
- double estSize = (bandw) * len;
- estSize = std::max(estSize, 1.0);
- // default
- if(estSize <= 1) {
- estSize = 32;
- }
- return ceil(estSize);
-}
-
-bool cHlsSegmentLoader::LoadSegment(std::string segmentUri)
-{
- try {
- Poco::Net::HTTPRequest segmentRequest(Poco::Net::HTTPRequest::HTTP_GET, segmentUri);
- AddHeader(segmentRequest);
- m_pClientSession->sendRequest(segmentRequest);
- } catch (Poco::Exception&) {
- esyslog("[plex] %s; %s failed.", __FUNCTION__, segmentUri.c_str());
- return false;
- }
- Poco::Net::HTTPResponse segmentResponse;
- std::istream& segmentFile = m_pClientSession->receiveResponse(segmentResponse);
-
- if(segmentResponse.getStatus() != 200) {
- // error
- esyslog("[plex] %s; %s failed.", __FUNCTION__, segmentUri.c_str());
- return false;
- }
-
- if(segmentResponse.getContentLength() <= TS_SIZE) {
- // Empty segment
- dsyslog("[plex] %s: %s <= 188 byte.", __FUNCTION__, segmentUri.c_str());
- return true;
- }
-
- dsyslog("[plex] %s: %s successfully.", __FUNCTION__, segmentUri.c_str());
- // copy response
- segmentFile.read(reinterpret_cast<char*>(m_pBuffer), BUFFERSIZE);
- std::streamsize n = segmentFile.gcount();
- while(n > 0) {
- if(m_pRingbuffer->Free() >= n) {
- m_pRingbuffer->Put(m_pBuffer, n);
-
- segmentFile.read(reinterpret_cast<char*>(m_pBuffer), BUFFERSIZE);
- n = segmentFile.gcount();
- m_bufferFilled = true;
- }
- else {
- cCondWait::SleepMs(1);
- }
- if(m_newList) {
- break;
- }
- }
- return true;
-}
-
-int cHlsSegmentLoader::GetSegmentSize(int segmentIndex)
-{
- //dsyslog("[plex]%s Segment %d", __FUNCTION__, segmentIndex);
- if(m_indexParser.vPlaylistItems[segmentIndex].size >= TS_SIZE) {
- return m_indexParser.vPlaylistItems[segmentIndex].size;
- }
- try {
- Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_HEAD, GetSegmentUri(segmentIndex));
- AddHeader(req);
- m_pClientSession->sendRequest(req);
- Poco::Net::HTTPResponse reqResponse;
- m_pClientSession->receiveResponse(reqResponse);
- return m_indexParser.vPlaylistItems[segmentIndex].size = reqResponse.getContentLength();
- } catch(Poco::IOException& exc) {
- esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
- return 0;
- }
-}
-
-std::string cHlsSegmentLoader::GetSegmentUri(int segmentIndex) const
-{
- return m_segmentUriPart + m_indexParser.vPlaylistItems[segmentIndex].file;
-}
-
-void cHlsSegmentLoader::CloseConnection(void)
-{
- if(m_pClientSession)
- m_pClientSession->abort();
-
- delete m_pClientSession;
- m_pClientSession = NULL;
-}
-
-bool cHlsSegmentLoader::ConnectToServer(void)
-{
- dsyslog("[plex]%s", __FUNCTION__);
- if(!m_pClientSession) {
- if(m_startUri.getScheme().find("https") != std::string::npos) {
- m_pClientSession = new Poco::Net::HTTPSClientSession(m_startUri.getHost(), m_startUri.getPort());
- }
- else {
- m_pClientSession = new Poco::Net::HTTPClientSession(m_startUri.getHost(), m_startUri.getPort());
- }
- }
-
- return m_pClientSession->connected();
-}
-
-bool cHlsSegmentLoader::DoLoad(void)
-{
- LOCK_THREAD;
- bool result = true;
- bool recover = false;
- if(m_lastLoadedSegment < m_indexParser.vPlaylistItems.size()) {
-
- std::string segmentUri = GetSegmentUri(m_lastLoadedSegment);
- if((result = LoadSegment(segmentUri))) {
- m_lastLoadedSegment++;
- } else {
- // transcoder may be died, plex bug, restart transcode session
- esyslog("[plex] %s 404, Transcoder died, see logfile from PMS", __FUNCTION__);
- recover = true;
- std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie;
- try {
-
- bool ok;
- auto cSession = m_pVideo->m_pServer->MakeRequest(ok, stopUri);
- int tmp = m_lastLoadedSegment;
- int tmp2 = m_lastSegmentSize;
- CloseConnection();
- LoadLists();
- m_lastLoadedSegment = tmp;
- m_lastSegmentSize = tmp2;
- } catch (Poco::Exception&) {
- return false;
- }
- }
-
- m_bufferFilled = result;
- } else {
- result = false;
- }
- return recover || result;
-}
-
-bool cHlsSegmentLoader::BufferFilled(void)
-{
- return m_bufferFilled;
-}
-
-bool cHlsSegmentLoader::StopLoader(void)
-{
- dsyslog("[plex]%s", __FUNCTION__);
- try {
- std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie;
-
- bool ok;
- auto cSession = m_pVideo->m_pServer->MakeRequest(ok, stopUri);
-
- Cancel();
-
- return ok;
- } catch(Poco::Exception& exc) {
- esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
- return false;
- }
-}
-void cHlsSegmentLoader::AddHeader(Poco::Net::HTTPRequest& req)
-{
- req.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
+cHlsSegmentLoader::cHlsSegmentLoader(std::string startm3u8, plexclient::cVideo *pVideo) {
+ m_pVideo = pVideo;
+ m_newList = false;
+ m_bufferFilled = false;
+ m_lastLoadedSegment = 0;
+ m_segmentsToBuffer = 2;
+ m_streamlenght = 0;
+ m_lastSegmentSize = 0;
+ m_pBuffer = new uchar[BUFFERSIZE];
+
+ // Initialize members
+ m_pClientSession = NULL;
+
+ m_ringBufferSize = MEGABYTE(1);
+ m_pRingbuffer = NULL;
+
+ m_startUri = Poco::URI(startm3u8);
+ m_startParser = cM3u8Parser();
+ m_indexParser = cM3u8Parser();
+}
+
+cHlsSegmentLoader::~cHlsSegmentLoader() {
+ // Stop Thread
+ Cancel(0);
+
+ delete m_pClientSession;
+ delete[] m_pBuffer;
+ delete m_pRingbuffer;
+}
+
+void cHlsSegmentLoader::SkipEmptySegments(int segmentDuration) {
+ pcrecpp::RE re("&offset=(\\d+)", pcrecpp::RE_Options(PCRE_CASELESS));
+ int value;
+ re.PartialMatch(m_startUri.getQuery(), &value);
+ if (value > segmentDuration) {
+ m_lastLoadedSegment = (value / segmentDuration) - 1;
+ }
+}
+
+bool cHlsSegmentLoader::LoadM3u8(std::string uri) {
+ //LOCK_THREAD;
+ m_startUri = Poco::URI(uri);
+ return (m_newList = true);
+}
+
+void cHlsSegmentLoader::Action(void) {
+ if (!LoadLists()) return;
+
+ m_ringBufferSize = MEGABYTE(Config::GetInstance().BufferSize);
+
+ isyslog("[plex]%s Create Ringbuffer %d MB", __FUNCTION__, Config::GetInstance().BufferSize);
+
+ m_pRingbuffer = new cRingBufferLinear(m_ringBufferSize, 2 * TS_SIZE);
+
+ while (Running()) {
+ if (m_newList) {
+ hlsMutex.Lock();
+ m_bufferFilled = false;
+ m_lastLoadedSegment = 0;
+ LoadLists();
+ m_newList = false;
+ m_pRingbuffer->Clear();
+ isyslog("[plex] Ringbuffer Cleared, loading new segments");
+ hlsMutex.Unlock();
+ }
+ int count = 0;
+ m_pRingbuffer->Get(count);
+ if (!DoLoad() && count < TS_SIZE) {
+ isyslog("[plex] No further segments to load and buffer empty, end of stream!");
+ Cancel();
+
+ }
+ cCondWait::SleepMs(3);
+ }
+ StopLoader();
+}
+
+bool cHlsSegmentLoader::LoadLists(void) {
+ if (LoadStartList()) {
+ if (false == LoadIndexList()) {
+ esyslog("[plex]LoadIndexList failed!");
+ return false;
+ }
+ } else {
+ esyslog("[plex]LoadStartList failed!");
+ return false;
+ }
+ return true;
+}
+
+bool cHlsSegmentLoader::LoadIndexList(void) {
+ bool res = false;
+ try {
+ if (m_startParser.MasterPlaylist && m_startParser.vPlaylistItems.size() > 0) {
+ // Todo: make it universal, might only work for Plexmediaserver
+ ConnectToServer();
+
+ std::string startUri = m_startUri.toString();
+ startUri = startUri.substr(0, startUri.find_last_of("/") + 1);
+
+ Poco::URI indexUri(startUri + m_startParser.vPlaylistItems[0].file);
+
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, indexUri.getPath());
+ AddHeader(request);
+ // same server
+ m_pClientSession->sendRequest(request);
+
+ Poco::Net::HTTPResponse responseStart;
+ std::istream &indexFile = m_pClientSession->receiveResponse(responseStart);
+
+ if (responseStart.getStatus() != 200) {
+ esyslog("[plex]%s Response Not Valid", __FUNCTION__);
+ Poco::StreamCopier::copyStream(indexFile, std::cout);
+ return res;
+ }
+ m_indexParser = cM3u8Parser();
+ res = m_indexParser.Parse(indexFile);
+
+ if (res) {
+ // Segment URI is relative to index.m3u8
+ std::string path = indexUri.getPath();
+ m_segmentUriPart = path.substr(0, path.find_last_of("/") + 1);
+ }
+ if (m_indexParser.TargetDuration > 3) {
+ m_segmentsToBuffer = 2;
+ } else {
+ m_segmentsToBuffer = 3;
+ }
+
+ SkipEmptySegments(m_indexParser.TargetDuration);
+ m_lastSegmentSize = 0;
+
+ // Get stream lenght
+ m_streamlenght = 0;
+ for (unsigned int i = 0; i < m_indexParser.vPlaylistItems.size(); i++) {
+ m_streamlenght += m_indexParser.vPlaylistItems[i].length;
+ }
+ }
+
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex] %s %s", __FUNCTION__, exc.displayText().c_str());
+ res = false;
+ }
+ return res;
+}
+
+bool cHlsSegmentLoader::LoadStartList(void) {
+ bool res = false;
+ ConnectToServer();
+ try {
+ dsyslog("[plex]%s %s", __FUNCTION__, m_startUri.toString().c_str());
+ Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, m_startUri.getPathAndQuery());
+ AddHeader(request);
+ m_pClientSession->sendRequest(request);
+
+ Poco::Net::HTTPResponse responseStart;
+ std::istream &startFile = m_pClientSession->receiveResponse(responseStart);
+
+ if (responseStart.getStatus() != 200) {
+ esyslog("[plex]%s Response Not Valid", __FUNCTION__);
+ Poco::StreamCopier::copyStream(startFile, std::cout);
+ return res;
+ }
+
+ m_startParser = cM3u8Parser();
+ res = m_startParser.Parse(startFile);
+ if (res) {
+ // Get GUID
+ pcrecpp::RE re("([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})",
+ pcrecpp::RE_Options(PCRE_CASELESS));
+ string value;
+ re.PartialMatch(m_startParser.vPlaylistItems[0].file, &value);
+ m_sessionCookie = value;
+ }
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex] %s %s", __FUNCTION__, exc.displayText().c_str());
+ res = false;
+ }
+ return res;
+}
+
+int cHlsSegmentLoader::EstimateSegmentSize() {
+ if (&m_startParser.vPlaylistItems[0] == NULL) {
+ esyslog("[plex]%s first element NULL", __FUNCTION__);
+ }
+ double bandw = m_startParser.vPlaylistItems[0].bandwidth / 8.0 / 1000.0 / 1000.0;
+
+ int len = m_indexParser.TargetDuration;
+ double estSize = (bandw) * len;
+ estSize = std::max(estSize, 1.0);
+ // default
+ if (estSize <= 1) {
+ estSize = 32;
+ }
+ return ceil(estSize);
+}
+
+bool cHlsSegmentLoader::LoadSegment(std::string segmentUri) {
+ try {
+ Poco::Net::HTTPRequest segmentRequest(Poco::Net::HTTPRequest::HTTP_GET, segmentUri);
+ AddHeader(segmentRequest);
+ m_pClientSession->sendRequest(segmentRequest);
+ } catch (Poco::Exception &) {
+ esyslog("[plex] %s; %s failed.", __FUNCTION__, segmentUri.c_str());
+ return false;
+ }
+ Poco::Net::HTTPResponse segmentResponse;
+ std::istream &segmentFile = m_pClientSession->receiveResponse(segmentResponse);
+
+ if (segmentResponse.getStatus() != 200) {
+ // error
+ esyslog("[plex] %s; %s failed.", __FUNCTION__, segmentUri.c_str());
+ return false;
+ }
+
+ if (segmentResponse.getContentLength() <= TS_SIZE) {
+ // Empty segment
+ dsyslog("[plex] %s: %s <= 188 byte.", __FUNCTION__, segmentUri.c_str());
+ return true;
+ }
+
+ dsyslog("[plex] %s: %s successfully.", __FUNCTION__, segmentUri.c_str());
+ // copy response
+ segmentFile.read(reinterpret_cast<char *>(m_pBuffer), BUFFERSIZE);
+ std::streamsize n = segmentFile.gcount();
+ while (n > 0) {
+ if (m_pRingbuffer->Free() >= n) {
+ m_pRingbuffer->Put(m_pBuffer, n);
+
+ segmentFile.read(reinterpret_cast<char *>(m_pBuffer), BUFFERSIZE);
+ n = segmentFile.gcount();
+ m_bufferFilled = true;
+ }
+ else {
+ cCondWait::SleepMs(1);
+ }
+ if (m_newList) {
+ break;
+ }
+ }
+ return true;
+}
+
+int cHlsSegmentLoader::GetSegmentSize(int segmentIndex) {
+ //dsyslog("[plex]%s Segment %d", __FUNCTION__, segmentIndex);
+ if (m_indexParser.vPlaylistItems[segmentIndex].size >= TS_SIZE) {
+ return m_indexParser.vPlaylistItems[segmentIndex].size;
+ }
+ try {
+ Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_HEAD, GetSegmentUri(segmentIndex));
+ AddHeader(req);
+ m_pClientSession->sendRequest(req);
+ Poco::Net::HTTPResponse reqResponse;
+ m_pClientSession->receiveResponse(reqResponse);
+ return m_indexParser.vPlaylistItems[segmentIndex].size = reqResponse.getContentLength();
+ } catch (Poco::IOException &exc) {
+ esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
+ return 0;
+ }
+}
+
+std::string cHlsSegmentLoader::GetSegmentUri(int segmentIndex) const {
+ return m_segmentUriPart + m_indexParser.vPlaylistItems[segmentIndex].file;
+}
+
+void cHlsSegmentLoader::CloseConnection(void) {
+ if (m_pClientSession)
+ m_pClientSession->abort();
+
+ delete m_pClientSession;
+ m_pClientSession = NULL;
+}
+
+bool cHlsSegmentLoader::ConnectToServer(void) {
+ dsyslog("[plex]%s", __FUNCTION__);
+ if (!m_pClientSession) {
+ if (m_startUri.getScheme().find("https") != std::string::npos) {
+ m_pClientSession = new Poco::Net::HTTPSClientSession(m_startUri.getHost(), m_startUri.getPort());
+ }
+ else {
+ m_pClientSession = new Poco::Net::HTTPClientSession(m_startUri.getHost(), m_startUri.getPort());
+ }
+ }
+
+ return m_pClientSession->connected();
+}
+
+bool cHlsSegmentLoader::DoLoad(void) {
+ LOCK_THREAD;
+ bool result = true;
+ bool recover = false;
+ if (m_lastLoadedSegment < m_indexParser.vPlaylistItems.size()) {
+
+ std::string segmentUri = GetSegmentUri(m_lastLoadedSegment);
+ if ((result = LoadSegment(segmentUri))) {
+ m_lastLoadedSegment++;
+ } else {
+ // transcoder may be died, plex bug, restart transcode session
+ esyslog("[plex] %s 404, Transcoder died, see logfile from PMS", __FUNCTION__);
+ recover = true;
+ std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie;
+ try {
+
+ bool ok;
+ auto cSession = m_pVideo->m_pServer->MakeRequest(ok, stopUri);
+ int tmp = m_lastLoadedSegment;
+ int tmp2 = m_lastSegmentSize;
+ CloseConnection();
+ LoadLists();
+ m_lastLoadedSegment = tmp;
+ m_lastSegmentSize = tmp2;
+ } catch (Poco::Exception &) {
+ return false;
+ }
+ }
+
+ m_bufferFilled = result;
+ } else {
+ result = false;
+ }
+ return recover || result;
+}
+
+bool cHlsSegmentLoader::BufferFilled(void) {
+ return m_bufferFilled;
+}
+
+bool cHlsSegmentLoader::StopLoader(void) {
+ dsyslog("[plex]%s", __FUNCTION__);
+ try {
+ std::string stopUri = "/video/:/transcode/universal/stop?session=" + m_sessionCookie;
+
+ bool ok;
+ auto cSession = m_pVideo->m_pServer->MakeRequest(ok, stopUri);
+
+ Cancel();
+
+ return ok;
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
+ return false;
+ }
+}
+
+void cHlsSegmentLoader::AddHeader(Poco::Net::HTTPRequest &req) {
+ req.add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
// req.add("X-Plex-Device", "PC");
- req.add("X-Plex-Model", "Linux");
- if(Config::GetInstance().UseCustomTranscodeProfile) {
- req.add("X-Plex-Device", "VDR Plex Plugin");
- } else {
- req.add("X-Plex-Device", "Plex Home Theater");
- //req.add("X-Plex-Device", "tvOS");
- }
-
- if(Config::GetInstance().UsePlexAccount && !m_pVideo->m_pServer->GetAuthToken().empty()) {
- // Add PlexToken to Header
- req.add("X-Plex-Token", m_pVideo->m_pServer->GetAuthToken());
- }
-}
-
-bool cHlsSegmentLoader::Active(void)
-{
- return Running();
-}
-
-void cHlsSegmentLoader::Ping(void)
-{
- dsyslog("[plex]%s", __FUNCTION__);
- try {
- std::string uri = "/video/:/transcode/universal/ping?session=" + Config::GetInstance().GetUUID();
-
- bool ok;
- auto cSession = m_pVideo->m_pServer->MakeRequest(ok, uri);
-
- } catch(Poco::Exception& exc) {
- esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
- }
-}
-
-void cHlsSegmentLoader::ResizeRingbuffer(int newsize)
-{
- hlsMutex.Lock();
- isyslog("[plex] %s, Oldsize: %d, Newsize: %d", __FUNCTION__, m_ringBufferSize, newsize);
- //Create new Ringbuffer
- cRingBufferLinear* newBuffer = new cRingBufferLinear(newsize, TS_SIZE);
- // Copy old data
- int count = 0;
- uchar* pData = m_pRingbuffer->Get(count);
- newBuffer->Put(pData, count);
- // delete old buffer
- delete m_pRingbuffer;
- m_pRingbuffer = NULL;
- // assing new buffer
- m_pRingbuffer = newBuffer;
- m_ringBufferSize = newsize;
- hlsMutex.Unlock();
-}
-
-int cHlsSegmentLoader::GetStreamLenght()
-{
- return m_streamlenght;
+ req.add("X-Plex-Model", "Linux");
+ if (Config::GetInstance().UseCustomTranscodeProfile) {
+ req.add("X-Plex-Device", "VDR Plex Plugin");
+ } else {
+ req.add("X-Plex-Device", "Plex Home Theater");
+ //req.add("X-Plex-Device", "tvOS");
+ }
+
+ if (Config::GetInstance().UsePlexAccount && !m_pVideo->m_pServer->GetAuthToken().empty()) {
+ // Add PlexToken to Header
+ req.add("X-Plex-Token", m_pVideo->m_pServer->GetAuthToken());
+ }
+}
+
+bool cHlsSegmentLoader::Active(void) {
+ return Running();
+}
+
+void cHlsSegmentLoader::Ping(void) {
+ dsyslog("[plex]%s", __FUNCTION__);
+ try {
+ std::string uri = "/video/:/transcode/universal/ping?session=" + Config::GetInstance().GetUUID();
+
+ bool ok;
+ auto cSession = m_pVideo->m_pServer->MakeRequest(ok, uri);
+
+ } catch (Poco::Exception &exc) {
+ esyslog("[plex]%s %s ", __FUNCTION__, exc.displayText().c_str());
+ }
+}
+
+void cHlsSegmentLoader::ResizeRingbuffer(int newsize) {
+ hlsMutex.Lock();
+ isyslog("[plex] %s, Oldsize: %d, Newsize: %d", __FUNCTION__, m_ringBufferSize, newsize);
+ //Create new Ringbuffer
+ cRingBufferLinear *newBuffer = new cRingBufferLinear(newsize, TS_SIZE);
+ // Copy old data
+ int count = 0;
+ uchar *pData = m_pRingbuffer->Get(count);
+ newBuffer->Put(pData, count);
+ // delete old buffer
+ delete m_pRingbuffer;
+ m_pRingbuffer = NULL;
+ // assing new buffer
+ m_pRingbuffer = newBuffer;
+ m_ringBufferSize = newsize;
+ hlsMutex.Unlock();
+}
+
+int cHlsSegmentLoader::GetStreamLenght() {
+ return m_streamlenght;
}
//--- cHlsPlayer
-cHlsPlayer::cHlsPlayer(std::string startm3u8, plexclient::cVideo Video, int offset)
-{
- dsyslog("[plex]: '%s'", __FUNCTION__);
- m_Video = Video;
- m_timeOffset = offset;
- m_jumpOffset = 0;
- m_tTimeSum = 0;
- m_doJump = false;
- m_isBuffering = false;
- AudioIndexOffset = 1000; // Just a magic number
- m_tTimer.Set(1);
- m_pSegmentLoader = new cHlsSegmentLoader(startm3u8, &m_Video);
-
- m_pDebugFile = NULL;
- //m_pDebugFile = new std::ofstream();
- //m_pDebugFile->open("debug.ts", std::ios::out);
-}
-
-cHlsPlayer::~cHlsPlayer()
-{
- dsyslog("[plex]: '%s'", __FUNCTION__);
- Cancel();
- if(m_pDebugFile) m_pDebugFile->close();
- delete m_pDebugFile;
- m_pDebugFile = NULL;
-
- delete m_pSegmentLoader;
- m_pSegmentLoader = NULL;
- Detach();
-}
-
-void cHlsPlayer::SetAudioAndSubtitleTracks(void)
-{
- //DeviceClrAvailableTracks();
- DeviceSetAvailableTrack(ttDolby, 0, 0, "Current");
- if(m_Video.m_Media.m_vStreams.size() > 0) {
- std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
- for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
- plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
- DeviceSetAvailableTrack(ttDolby, pStream->m_iIndex, pStream->m_iIndex + AudioIndexOffset, pStream->m_sLanguage.c_str(), pStream->m_sCodec.c_str());
- }
- }
- }
-}
-
-
-void cHlsPlayer::Action(void)
-{
- // Start SegmentLoader
- m_pSegmentLoader->Start();
-
- m_bFirstPlay = true;
-
- while (Running()) {
- if(m_doJump && m_pSegmentLoader && m_pSegmentLoader->BufferFilled()) {
- LOCK_THREAD;
-
- DeviceFreeze();
- m_doJump = false;
- m_bFirstPlay = true;
- std::string uri = plexclient::Plexservice::GetUniversalTranscodeUrl(&m_Video, m_jumpOffset);
- m_pSegmentLoader->LoadM3u8(uri);
- m_timeOffset = m_jumpOffset;
- DeviceClear();
- DevicePlay();
- playMode = pmPlay;
- } else if(m_pSegmentLoader && m_pSegmentLoader->BufferFilled()) {
- DoPlay();
- if(m_bFirstPlay) {
- SetAudioAndSubtitleTracks();
- ResetPlayedSeconds();
- playMode = pmPlay;
- m_bFirstPlay = false;
- }
- CountPlayedSeconds();
- } else {
- // Pause
- cCondWait::SleepMs(3);
- }
- // statusupdates to pms every 60s
- if(m_pSegmentLoader && m_tTimer.TimedOut()) {
- if(playMode == pmPause) {
- m_pSegmentLoader->Ping();
- }
- ReportProgress();
- m_tTimer.Set(60000);
- }
- }
- // set as watched if >= 90%
- int t = m_Video.m_Media.m_lDuration / 1000 * 0.9;
- if( GetPlayedSeconds() >= t) {
- SetWatched();
- }
- DeviceClear();
-}
-
-bool cHlsPlayer::DoPlay(void)
-{
- bool res = false;
- cPoller Poller;
- if(DevicePoll(Poller, 10)) {
- hlsMutex.Lock();
+cHlsPlayer::cHlsPlayer(std::string startm3u8, plexclient::cVideo Video, int offset) {
+ dsyslog("[plex]: '%s'", __FUNCTION__);
+ m_Video = Video;
+ m_timeOffset = offset;
+ m_jumpOffset = 0;
+ m_tTimeSum = 0;
+ m_doJump = false;
+ m_isBuffering = false;
+ AudioIndexOffset = 1000; // Just a magic number
+ m_tTimer.Set(1);
+ m_pSegmentLoader = new cHlsSegmentLoader(startm3u8, &m_Video);
+
+ m_pDebugFile = NULL;
+ //m_pDebugFile = new std::ofstream();
+ //m_pDebugFile->open("debug.ts", std::ios::out);
+}
+
+cHlsPlayer::~cHlsPlayer() {
+ dsyslog("[plex]: '%s'", __FUNCTION__);
+ Cancel();
+ if (m_pDebugFile) m_pDebugFile->close();
+ delete m_pDebugFile;
+ m_pDebugFile = NULL;
+
+ delete m_pSegmentLoader;
+ m_pSegmentLoader = NULL;
+ Detach();
+}
+
+void cHlsPlayer::SetAudioAndSubtitleTracks(void) {
+ //DeviceClrAvailableTracks();
+ DeviceSetAvailableTrack(ttDolby, 0, 0, "Current");
+ if (m_Video.m_Media.m_vStreams.size() > 0) {
+ std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
+ for (std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
+ plexclient::Stream *pStream = &(*it);
+ if (pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
+ DeviceSetAvailableTrack(ttDolby, pStream->m_iIndex, pStream->m_iIndex + AudioIndexOffset,
+ pStream->m_sLanguage.c_str(), pStream->m_sCodec.c_str());
+ }
+ }
+ }
+}
+
+
+void cHlsPlayer::Action(void) {
+ // Start SegmentLoader
+ m_pSegmentLoader->Start();
+
+ m_bFirstPlay = true;
+
+ while (Running()) {
+ if (m_doJump && m_pSegmentLoader && m_pSegmentLoader->BufferFilled()) {
+ LOCK_THREAD;
+
+ DeviceFreeze();
+ m_doJump = false;
+ m_bFirstPlay = true;
+ std::string uri = plexclient::Plexservice::GetUniversalTranscodeUrl(&m_Video, m_jumpOffset);
+ m_pSegmentLoader->LoadM3u8(uri);
+ m_timeOffset = m_jumpOffset;
+ DeviceClear();
+ DevicePlay();
+ playMode = pmPlay;
+ } else if (m_pSegmentLoader && m_pSegmentLoader->BufferFilled()) {
+ DoPlay();
+ if (m_bFirstPlay) {
+ SetAudioAndSubtitleTracks();
+ ResetPlayedSeconds();
+ playMode = pmPlay;
+ m_bFirstPlay = false;
+ }
+ CountPlayedSeconds();
+ } else {
+ // Pause
+ cCondWait::SleepMs(3);
+ }
+ // statusupdates to pms every 60s
+ if (m_pSegmentLoader && m_tTimer.TimedOut()) {
+ if (playMode == pmPause) {
+ m_pSegmentLoader->Ping();
+ }
+ ReportProgress();
+ m_tTimer.Set(60000);
+ }
+ }
+ // set as watched if >= 90%
+ int t = m_Video.m_Media.m_lDuration / 1000 * 0.9;
+ if (GetPlayedSeconds() >= t) {
+ SetWatched();
+ }
+ DeviceClear();
+}
+
+bool cHlsPlayer::DoPlay(void) {
+ bool res = false;
+ cPoller Poller;
+ if (DevicePoll(Poller, 10)) {
+ hlsMutex.Lock();
// Handle running out of packets. Buffer-> Play-> Pause-> Buffer-> Play
- for(int i = 0; i < 10; i++) {
- // Get a pointer to start of the data and the number of avaliable bytes
- int bytesAvaliable = 0;
- uchar* toPlay = m_pSegmentLoader->m_pRingbuffer->Get(bytesAvaliable);
- if(bytesAvaliable >= TS_SIZE) {
- int playedBytes = PlayTs(toPlay, TS_SIZE, false);
- // save stream to disk to debug data
- if(m_pDebugFile) {
- m_pDebugFile-> write((char*)toPlay, playedBytes);
- }
-
- m_pSegmentLoader->m_pRingbuffer->Del(playedBytes);
- res = true;
- } else {
- // Pause & Buffer
- break;
- }
- }
- hlsMutex.Unlock();
- }
- return res;
-}
-
-void cHlsPlayer::Activate(bool On)
-{
- if(On) {
- Start();
- } else {
- Cancel(1);
- }
-}
-
-bool cHlsPlayer::GetIndex(int& Current, int& Total, bool SnapToIFrame __attribute__((unused)))
-{
- if(m_Video.m_Media.m_lDuration > 0) {
- Total = m_Video.m_Media.m_lDuration / 1000 * FramesPerSecond(); // milliseconds
- } else {
- Total = m_pSegmentLoader->GetStreamLenght() * FramesPerSecond();
- }
- Current = GetPlayedSeconds() * FramesPerSecond();
- return true;
-}
-
-bool cHlsPlayer::GetReplayMode(bool& Play, bool& Forward, int& Speed)
-{
- Play = (playMode == pmPlay);
- Forward = true;
- Speed = -1;
- return true;
-}
-
-void cHlsPlayer::Pause(void)
-{
- LOCK_THREAD;
- dsyslog("[plex]%s", __FUNCTION__);
- if (playMode == pmPause) {
- Play();
- } else {
- DeviceFreeze();
- playMode = pmPause;
- }
-}
-
-void cHlsPlayer::Play(void)
-{
- LOCK_THREAD;
- dsyslog("[plex]%s", __FUNCTION__);
- if (playMode != pmPlay) {
- DevicePlay();
- playMode = pmPlay;
- }
-}
-
-bool cHlsPlayer::Active(void)
-{
- return Running() && m_pSegmentLoader && m_pSegmentLoader->Active();
-}
-
-void cHlsPlayer::Stop(void)
-{
- LOCK_THREAD;
- dsyslog("[plex]%s", __FUNCTION__);
- ReportProgress(true);
- if (m_pSegmentLoader)
- m_pSegmentLoader->StopLoader();
- Cancel(1);
-}
-
-double cHlsPlayer::FramesPerSecond(void)
-{
- return m_Video.m_Media.m_VideoFrameRate == "24p" ? 24 : DEFAULTFRAMESPERSECOND;
-}
-
-void cHlsPlayer::JumpRelative(int seconds)
-{
- JumpTo(GetPlayedSeconds() + seconds);
-}
-
-void cHlsPlayer::JumpTo(int seconds)
-{
- LOCK_THREAD;
- dsyslog("[plex]%s %d", __FUNCTION__, seconds);
- if(seconds < 0) seconds = 0;
- m_jumpOffset = seconds;
- m_doJump = true;
-}
-
-void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tTrackId* TrackId)
-{
- LOCK_THREAD;
- dsyslog("[plex]%s %d %s", __FUNCTION__, TrackId->id, TrackId->language);
- // Check if stream availiable
- int streamId = 0;
- if(m_Video.m_Media.m_vStreams.size() > 0) {
- std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
- for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
- plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO && pStream->m_iIndex + AudioIndexOffset == TrackId->id) {
- streamId = pStream->m_iID;
- break;
- }
- }
- }
- // Then do the request
- if(streamId > 0) {
- std::string uri = "/library/parts/" + std::string(itoa(m_Video.m_Media.m_iPartId)) + "?audioStreamID=" + std::string(itoa(streamId));
-
- bool ok;
- auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
- if(ok) {
- DeviceSetCurrentAudioTrack(eTrackType(ttDolby + 0)); // hacky
- DeviceSetAvailableTrack(ttDolby, 0, 0, TrackId->language);
- JumpRelative(0); // Reload Stream to get new Audio
- dsyslog("[plex]: Set AudioStream: %d\n", TrackId->id);
- }
- }
-}
-
-int cHlsPlayer::GetPlayedSeconds(void)
-{
- return m_timeOffset + (m_tTimeSum / 1000);
-}
-
-void cHlsPlayer::CountPlayedSeconds(void)
-{
- if (playMode == pmPlay) {
- unsigned long long tTmp = cTimeMs::Now();
- m_tTimeSum += (tTmp - m_tLastTime);
- m_tLastTime = tTmp;
- } else {
- m_tLastTime = cTimeMs::Now();
- }
-}
-
-void cHlsPlayer::ResetPlayedSeconds(void)
-{
- m_tTimeSum = 0;
- m_tLastTime = cTimeMs::Now();
-}
-
-void cHlsPlayer::ReportProgress(bool stopped)
-{
- std::string state;
- if(stopped) {
- state = "stopped";
- } else if (playMode == pmPlay) {
- state = "playing";
- } else {
- state = "paused";
- }
-
- try {
- std::string uri = "/:/progress?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library&time=" + std::string(itoa(GetPlayedSeconds()*1000)) + "&state=" + state;
-
- bool ok;
- auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
-
- if(ok) {
- dsyslog("[plex] %s", __FUNCTION__);
- }
- } catch (Poco::Exception&) {}
-
-}
-
-void cHlsPlayer::SetWatched(void)
-{
- std::string uri = "/:/scrobble?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library";
-
- bool ok;
- auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
-
- if(ok) {
- dsyslog("[plex] %s", __FUNCTION__);
- }
+ for (int i = 0; i < 10; i++) {
+ // Get a pointer to start of the data and the number of avaliable bytes
+ int bytesAvaliable = 0;
+ uchar *toPlay = m_pSegmentLoader->m_pRingbuffer->Get(bytesAvaliable);
+ if (bytesAvaliable >= TS_SIZE) {
+ int playedBytes = PlayTs(toPlay, TS_SIZE, false);
+ // save stream to disk to debug data
+ if (m_pDebugFile) {
+ m_pDebugFile->write((char *) toPlay, playedBytes);
+ }
+
+ m_pSegmentLoader->m_pRingbuffer->Del(playedBytes);
+ res = true;
+ } else {
+ // Pause & Buffer
+ break;
+ }
+ }
+ hlsMutex.Unlock();
+ }
+ return res;
+}
+
+void cHlsPlayer::Activate(bool On) {
+ if (On) {
+ Start();
+ } else {
+ Cancel(1);
+ }
+}
+
+bool cHlsPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame __attribute__((unused))) {
+ if (m_Video.m_Media.m_lDuration > 0) {
+ Total = m_Video.m_Media.m_lDuration / 1000 * FramesPerSecond(); // milliseconds
+ } else {
+ Total = m_pSegmentLoader->GetStreamLenght() * FramesPerSecond();
+ }
+ Current = GetPlayedSeconds() * FramesPerSecond();
+ return true;
+}
+
+bool cHlsPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed) {
+ Play = (playMode == pmPlay);
+ Forward = true;
+ Speed = -1;
+ return true;
+}
+
+void cHlsPlayer::Pause(void) {
+ LOCK_THREAD;
+ dsyslog("[plex]%s", __FUNCTION__);
+ if (playMode == pmPause) {
+ Play();
+ } else {
+ DeviceFreeze();
+ playMode = pmPause;
+ }
+}
+
+void cHlsPlayer::Play(void) {
+ LOCK_THREAD;
+ dsyslog("[plex]%s", __FUNCTION__);
+ if (playMode != pmPlay) {
+ DevicePlay();
+ playMode = pmPlay;
+ }
+}
+
+bool cHlsPlayer::Active(void) {
+ return Running() && m_pSegmentLoader && m_pSegmentLoader->Active();
+}
+
+void cHlsPlayer::Stop(void) {
+ LOCK_THREAD;
+ dsyslog("[plex]%s", __FUNCTION__);
+ ReportProgress(true);
+ if (m_pSegmentLoader)
+ m_pSegmentLoader->StopLoader();
+ Cancel(1);
+}
+
+double cHlsPlayer::FramesPerSecond(void) {
+ return m_Video.m_Media.m_VideoFrameRate == "24p" ? 24 : DEFAULTFRAMESPERSECOND;
+}
+
+void cHlsPlayer::JumpRelative(int seconds) {
+ JumpTo(GetPlayedSeconds() + seconds);
+}
+
+void cHlsPlayer::JumpTo(int seconds) {
+ LOCK_THREAD;
+ dsyslog("[plex]%s %d", __FUNCTION__, seconds);
+ if (seconds < 0) seconds = 0;
+ m_jumpOffset = seconds;
+ m_doJump = true;
+}
+
+void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tTrackId *TrackId) {
+ LOCK_THREAD;
+ dsyslog("[plex]%s %d %s", __FUNCTION__, TrackId->id, TrackId->language);
+ // Check if stream availiable
+ int streamId = 0;
+ if (m_Video.m_Media.m_vStreams.size() > 0) {
+ std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
+ for (std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
+ plexclient::Stream *pStream = &(*it);
+ if (pStream->m_eStreamType == plexclient::StreamType::sAUDIO &&
+ pStream->m_iIndex + AudioIndexOffset == TrackId->id) {
+ streamId = pStream->m_iID;
+ break;
+ }
+ }
+ }
+ // Then do the request
+ if (streamId > 0) {
+ std::string uri = "/library/parts/" + std::string(itoa(m_Video.m_Media.m_iPartId)) + "?audioStreamID=" +
+ std::string(itoa(streamId));
+
+ bool ok;
+ auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
+ if (ok) {
+ DeviceSetCurrentAudioTrack(eTrackType(ttDolby + 0)); // hacky
+ DeviceSetAvailableTrack(ttDolby, 0, 0, TrackId->language);
+ JumpRelative(0); // Reload Stream to get new Audio
+ dsyslog("[plex]: Set AudioStream: %d\n", TrackId->id);
+ }
+ }
+}
+
+int cHlsPlayer::GetPlayedSeconds(void) {
+ return m_timeOffset + (m_tTimeSum / 1000);
+}
+
+void cHlsPlayer::CountPlayedSeconds(void) {
+ if (playMode == pmPlay) {
+ unsigned long long tTmp = cTimeMs::Now();
+ m_tTimeSum += (tTmp - m_tLastTime);
+ m_tLastTime = tTmp;
+ } else {
+ m_tLastTime = cTimeMs::Now();
+ }
+}
+
+void cHlsPlayer::ResetPlayedSeconds(void) {
+ m_tTimeSum = 0;
+ m_tLastTime = cTimeMs::Now();
+}
+
+void cHlsPlayer::ReportProgress(bool stopped) {
+ std::string state;
+ if (stopped) {
+ state = "stopped";
+ } else if (playMode == pmPlay) {
+ state = "playing";
+ } else {
+ state = "paused";
+ }
+
+ try {
+ std::string uri = "/:/progress?key=" + std::string(itoa(m_Video.m_iRatingKey)) +
+ "&identifier=com.plexapp.plugins.library&time=" +
+ std::string(itoa(GetPlayedSeconds() * 1000)) + "&state=" + state;
+
+ bool ok;
+ auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
+
+ if (ok) {
+ dsyslog("[plex] %s", __FUNCTION__);
+ }
+ } catch (Poco::Exception &) { }
+
+}
+
+void cHlsPlayer::SetWatched(void) {
+ std::string uri =
+ "/:/scrobble?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library";
+
+ bool ok;
+ auto cSession = m_Video.m_pServer->MakeRequest(ok, uri);
+
+ if (ok) {
+ dsyslog("[plex] %s", __FUNCTION__);
+ }
}
diff --git a/hlsPlayer.h b/hlsPlayer.h
index 21e6651..3918d4f 100644
--- a/hlsPlayer.h
+++ b/hlsPlayer.h
@@ -19,114 +19,150 @@
#include "PVideo.h"
#include "Media.h"
-class cHlsSegmentLoader : public cThread
-{
+class cHlsSegmentLoader : public cThread {
private:
- int m_ringBufferSize;
- unsigned int m_segmentsToBuffer;
- unsigned int m_lastLoadedSegment;
- int m_lastSegmentSize;
- bool m_bufferFilled;
- bool m_newList;
- int m_streamlenght;
-
- uchar* m_pBuffer;
-
- Poco::Net::HTTPClientSession* m_pClientSession;
- plexclient::cVideo* m_pVideo;
- Poco::URI m_startUri;
- std::string m_sessionUriPart;
- std::string m_segmentUriPart;
- std::string m_sessionCookie;
-
- cM3u8Parser m_startParser;
- cM3u8Parser m_indexParser;
-
- bool ConnectToServer(void);
- void CloseConnection(void);
- bool LoadStartList(void);
- bool LoadIndexList(void);
- std::string GetSegmentUri(int segmentIndex) const;
- int GetSegmentSize(int segmentIndex);
- bool LoadSegment(std::string uri);
- int EstimateSegmentSize();
- bool LoadLists(void);
- void ResizeRingbuffer(int newsize);
- void SkipEmptySegments(int segmentLenght);
-
+ int m_ringBufferSize;
+ unsigned int m_segmentsToBuffer;
+ unsigned int m_lastLoadedSegment;
+ int m_lastSegmentSize;
+ bool m_bufferFilled;
+ bool m_newList;
+ int m_streamlenght;
+
+ uchar *m_pBuffer;
+
+ Poco::Net::HTTPClientSession *m_pClientSession;
+ plexclient::cVideo *m_pVideo;
+ Poco::URI m_startUri;
+ std::string m_sessionUriPart;
+ std::string m_segmentUriPart;
+ std::string m_sessionCookie;
+
+ cM3u8Parser m_startParser;
+ cM3u8Parser m_indexParser;
+
+ bool ConnectToServer(void);
+
+ void CloseConnection(void);
+
+ bool LoadStartList(void);
+
+ bool LoadIndexList(void);
+
+ std::string GetSegmentUri(int segmentIndex) const;
+
+ int GetSegmentSize(int segmentIndex);
+
+ bool LoadSegment(std::string uri);
+
+ int EstimateSegmentSize();
+
+ bool LoadLists(void);
+
+ void ResizeRingbuffer(int newsize);
+
+ void SkipEmptySegments(int segmentLenght);
+
protected:
- void Action(void);
- bool DoLoad(void);
+ void Action(void);
+
+ bool DoLoad(void);
public:
- cHlsSegmentLoader(std::string startm3u8, plexclient::cVideo* pVideo);
- ~cHlsSegmentLoader();
-
- cRingBufferLinear* m_pRingbuffer;
- bool BufferFilled(void);
- bool Active(void);
- bool StopLoader(void);
- bool LoadM3u8(std::string uri);
- void AddHeader(Poco::Net::HTTPRequest& req);
- void Ping(void);
- int GetStreamLenght();
+ cHlsSegmentLoader(std::string startm3u8, plexclient::cVideo *pVideo);
+
+ ~cHlsSegmentLoader();
+
+ cRingBufferLinear *m_pRingbuffer;
+
+ bool BufferFilled(void);
+
+ bool Active(void);
+
+ bool StopLoader(void);
+
+ bool LoadM3u8(std::string uri);
+
+ void AddHeader(Poco::Net::HTTPRequest &req);
+
+ void Ping(void);
+
+ int GetStreamLenght();
};
-class cHlsPlayer : public cPlayer, cThread
-{
+class cHlsPlayer : public cPlayer, cThread {
private:
- std::ofstream* m_pDebugFile;
- int AudioIndexOffset;
- cHlsSegmentLoader* m_pSegmentLoader;
- plexclient::cVideo m_Video;
-
- int m_jumpOffset;
- int m_timeOffset;
- bool m_doJump;
- bool m_isBuffering;
-
- int m_videoLenght;
- int m_actualSegment;
- int m_actualTime;
- long m_lastValidSTC;
-
- unsigned long long m_tLastTime;
- unsigned long long m_tTimeSum;
- bool m_bFirstPlay;
- cTimeMs m_tTimer;
-
- enum ePlayModes { pmPlay, pmPause };
- ePlayModes playMode;
-
- virtual void Activate(bool On);
- int GetPlayedSeconds(void);
- void CountPlayedSeconds(void);
- void ResetPlayedSeconds(void);
- void ReportProgress(bool stopped = false);
- void SetWatched(void);
+ std::ofstream *m_pDebugFile;
+ int AudioIndexOffset;
+ cHlsSegmentLoader *m_pSegmentLoader;
+ plexclient::cVideo m_Video;
+
+ int m_jumpOffset;
+ int m_timeOffset;
+ bool m_doJump;
+ bool m_isBuffering;
+
+ int m_videoLenght;
+ int m_actualSegment;
+ int m_actualTime;
+ long m_lastValidSTC;
+
+ unsigned long long m_tLastTime;
+ unsigned long long m_tTimeSum;
+ bool m_bFirstPlay;
+ cTimeMs m_tTimer;
+
+ enum ePlayModes {
+ pmPlay, pmPause
+ };
+ ePlayModes playMode;
+
+ virtual void Activate(bool On);
+
+ int GetPlayedSeconds(void);
+
+ void CountPlayedSeconds(void);
+
+ void ResetPlayedSeconds(void);
+
+ void ReportProgress(bool stopped = false);
+
+ void SetWatched(void);
protected:
- void Action(void);
- bool DoPlay(void);
+ void Action(void);
+
+ bool DoPlay(void);
public:
- //static cMutex s_mutex;
- cHlsPlayer(std::string startm3u8, plexclient::cVideo Video, int offset = 0);
- ~cHlsPlayer();
-
- virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
- virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
- virtual double FramesPerSecond(void);
- virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
- void Pause(void);
- void Play(void);
- void Stop(void);
- bool Active(void);
- void JumpTo(int seconds);
- void JumpRelative(int seconds);
- void SetAudioAndSubtitleTracks(void);
+ //static cMutex s_mutex;
+ cHlsPlayer(std::string startm3u8, plexclient::cVideo Video, int offset = 0);
+
+ ~cHlsPlayer();
+
+ virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
+
+ virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
+
+ virtual double FramesPerSecond(void);
+
+ virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
+
+ void Pause(void);
+
+ void Play(void);
+
+ void Stop(void);
+
+ bool Active(void);
+
+ void JumpTo(int seconds);
+
+ void JumpRelative(int seconds);
+
+ void SetAudioAndSubtitleTracks(void);
};
diff --git a/hlsPlayerControl.cpp b/hlsPlayerControl.cpp
index 50ba441..f5068be 100644
--- a/hlsPlayerControl.cpp
+++ b/hlsPlayerControl.cpp
@@ -13,379 +13,365 @@
#include "cPlexOsdItem.h"
// static
-cControl* cHlsPlayerControl::Create(plexclient::cVideo Video)
-{
- // Stop already playing stream
- cHlsPlayerControl* c = dynamic_cast<cHlsPlayerControl*>(cControl::Control(true));
- if(c) {
- c->Stop();
- }
-
- // get Metadata
- std::string uri = Video.m_pServer->GetUri() + Video.m_sKey;
- auto pmcontainer = plexclient::Plexservice::GetMediaContainer(uri);
- if(pmcontainer == NULL) return NULL;
-
- std::string transcodeUri = plexclient::Plexservice::GetUniversalTranscodeUrl(&pmcontainer->m_vVideos[0], Video.m_iMyPlayOffset);
- cHlsPlayerControl* playerControl = new cHlsPlayerControl(new cHlsPlayer(transcodeUri, pmcontainer->m_vVideos[0], Video.m_iMyPlayOffset), pmcontainer->m_vVideos[0]);
- playerControl->m_title = pmcontainer->m_vVideos[0].m_sTitle;
- return playerControl;
+cControl *cHlsPlayerControl::Create(plexclient::cVideo Video) {
+ // Stop already playing stream
+ cHlsPlayerControl *c = dynamic_cast<cHlsPlayerControl *>(cControl::Control(true));
+ if (c) {
+ c->Stop();
+ }
+
+ // get Metadata
+ std::string uri = Video.m_pServer->GetUri() + Video.m_sKey;
+ auto pmcontainer = plexclient::Plexservice::GetMediaContainer(uri);
+ if (pmcontainer == NULL) return NULL;
+
+ std::string transcodeUri = plexclient::Plexservice::GetUniversalTranscodeUrl(&pmcontainer->m_vVideos[0],
+ Video.m_iMyPlayOffset);
+ cHlsPlayerControl *playerControl = new cHlsPlayerControl(
+ new cHlsPlayer(transcodeUri, pmcontainer->m_vVideos[0], Video.m_iMyPlayOffset), pmcontainer->m_vVideos[0]);
+ playerControl->m_title = pmcontainer->m_vVideos[0].m_sTitle;
+ return playerControl;
}
-cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer* Player, plexclient::cVideo Video) :cControl(Player)
-{
- dsyslog("[plex]: '%s'", __FUNCTION__);
- player = Player;
- m_Video = Video;
- //m_title = title;
-
- displayReplay = NULL;
- visible = modeOnly = shown = false;
- lastCurrent = lastTotal = -1;
- lastPlay = lastForward = false;
- lastSpeed = -2; // an invalid value
- timeoutShow = 0;
- menu = NULL;
-
- cStatus::MsgReplaying(this, m_title.c_str(), m_Video.m_Media.m_sPartFile.c_str(), true);
+cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer *Player, plexclient::cVideo Video) : cControl(Player) {
+ dsyslog("[plex]: '%s'", __FUNCTION__);
+ player = Player;
+ m_Video = Video;
+ //m_title = title;
+
+ displayReplay = NULL;
+ visible = modeOnly = shown = false;
+ lastCurrent = lastTotal = -1;
+ lastPlay = lastForward = false;
+ lastSpeed = -2; // an invalid value
+ timeoutShow = 0;
+ menu = NULL;
+
+ cStatus::MsgReplaying(this, m_title.c_str(), m_Video.m_Media.m_sPartFile.c_str(), true);
}
-cHlsPlayerControl::~cHlsPlayerControl()
-{
- dsyslog("[plex]: '%s'", __FUNCTION__);
- cStatus::MsgReplaying(this, NULL, NULL, false);
- Hide();
- delete player;
- delete menu;
- player = NULL;
+cHlsPlayerControl::~cHlsPlayerControl() {
+ dsyslog("[plex]: '%s'", __FUNCTION__);
+ cStatus::MsgReplaying(this, NULL, NULL, false);
+ Hide();
+ delete player;
+ delete menu;
+ player = NULL;
}
-cString cHlsPlayerControl::GetHeader(void)
-{
- return m_title.c_str();
+cString cHlsPlayerControl::GetHeader(void) {
+ return m_title.c_str();
}
-void cHlsPlayerControl::Hide(void)
-{
- if (visible) {
- delete displayReplay;
- displayReplay = NULL;
- SetNeedsFastResponse(false);
- visible = false;
- modeOnly = false;
- lastPlay = lastForward = false;
- lastSpeed = -2; // an invalid value
- //timeSearchActive = false;
- timeoutShow = 0;
- }
+void cHlsPlayerControl::Hide(void) {
+ if (visible) {
+ delete displayReplay;
+ displayReplay = NULL;
+ SetNeedsFastResponse(false);
+ visible = false;
+ modeOnly = false;
+ lastPlay = lastForward = false;
+ lastSpeed = -2; // an invalid value
+ //timeSearchActive = false;
+ timeoutShow = 0;
+ }
}
-void cHlsPlayerControl::Show(void)
-{
- ShowTimed(3);
+void cHlsPlayerControl::Show(void) {
+ ShowTimed(3);
}
-eOSState cHlsPlayerControl::ProcessKey(eKeys Key)
-{
- if (!Active())
- return osEnd;
- if (Key == kPlayPause) {
- bool Play, Forward;
- int Speed;
- GetReplayMode(Play, Forward, Speed);
- if (Speed >= 0)
- Key = Play ? kPlay : kPause;
- else
- Key = Play ? kPause : kPlay;
- }
- if (visible) {
- if (timeoutShow && time(NULL) > timeoutShow) {
- Hide();
- ShowMode();
- timeoutShow = 0;
- } else if (modeOnly)
- ShowMode();
- else
- shown = ShowProgress(!shown) || shown;
- }
-
- // Handle menus
- if (menu) {
- eOSState state = menu->ProcessKey(Key);
- if (state == osEnd) {
- JumpRelative(0);
- delete menu;
- menu = NULL;
- }
- if (state == osBack) {
- Hide();
- delete menu;
- menu = NULL;
- }
- return osContinue;
- }
-
- bool DoShowMode = true;
- switch (int(Key)) {
- // Positioning:
- case kPlay:
- case kUp:
- Play();
- break;
- case kPause:
- case kDown:
- Pause();
- break;
- case kFastRew:
- case kLeft:
- player->JumpRelative(-10);
- break;
- case kFastFwd:
- case kRight:
- player->JumpRelative(10);
- break;
- case kGreen|k_Repeat:
+eOSState cHlsPlayerControl::ProcessKey(eKeys Key) {
+ if (!Active())
+ return osEnd;
+ if (Key == kPlayPause) {
+ bool Play, Forward;
+ int Speed;
+ GetReplayMode(Play, Forward, Speed);
+ if (Speed >= 0)
+ Key = Play ? kPlay : kPause;
+ else
+ Key = Play ? kPause : kPlay;
+ }
+ if (visible) {
+ if (timeoutShow && time(NULL) > timeoutShow) {
+ Hide();
+ ShowMode();
+ timeoutShow = 0;
+ } else if (modeOnly)
+ ShowMode();
+ else
+ shown = ShowProgress(!shown) || shown;
+ }
+
+ // Handle menus
+ if (menu) {
+ eOSState state = menu->ProcessKey(Key);
+ if (state == osEnd) {
+ JumpRelative(0);
+ delete menu;
+ menu = NULL;
+ }
+ if (state == osBack) {
+ Hide();
+ delete menu;
+ menu = NULL;
+ }
+ return osContinue;
+ }
+
+ bool DoShowMode = true;
+ switch (int(Key)) {
+ // Positioning:
+ case kPlay:
+ case kUp:
+ Play();
+ break;
+ case kPause:
+ case kDown:
+ Pause();
+ break;
+ case kFastRew:
+ case kLeft:
+ player->JumpRelative(-10);
+ break;
+ case kFastFwd:
+ case kRight:
+ player->JumpRelative(10);
+ break;
+ case kGreen | k_Repeat:
#if APIVERSNUM >= 20200
- player->JumpRelative(-Setup.SkipSecondsRepeat);
- break;
+ player->JumpRelative(-Setup.SkipSecondsRepeat);
+ break;
#endif
- case kGreen:
+ case kGreen:
#if APIVERSNUM >= 20200
- player->JumpRelative(-Setup.SkipSeconds);
+ player->JumpRelative(-Setup.SkipSeconds);
#else
- player->JumpRelative(-300);
+ player->JumpRelative(-300);
#endif
- break;
- case kYellow|k_Repeat:
+ break;
+ case kYellow | k_Repeat:
#if APIVERSNUM >= 20200
- player->JumpRelative(Setup.SkipSecondsRepeat);
- break;
+ player->JumpRelative(Setup.SkipSecondsRepeat);
+ break;
#endif
- case kYellow:
+ case kYellow:
#if APIVERSNUM >= 20200
- player->JumpRelative(Setup.SkipSeconds);
+ player->JumpRelative(Setup.SkipSeconds);
#else
- player->JumpRelative(300);
+ player->JumpRelative(300);
#endif
- break;
- case kStop:
- case kBlue:
- Hide();
- Stop();
- cMyPlugin::CalledFromCode = true;
- cRemote::CallPlugin(PLUGIN);
- return osEnd;
- default: {
- DoShowMode = false;
- switch (int(Key)) {
- default: {
- switch (Key) {
- case kOk:
- if (visible && !modeOnly) {
- Hide();
- DoShowMode = true;
- } else
- Show();
- break;
- case kBack:
- Hide();
- menu = new cStreamSelectMenu(&m_Video);
- break;
- default:
- return osUnknown;
- }
- }
- }
- }
- if (DoShowMode)
- ShowMode();
- }
-
- return osContinue;
+ break;
+ case kStop:
+ case kBlue:
+ Hide();
+ Stop();
+ cMyPlugin::CalledFromCode = true;
+ cRemote::CallPlugin(PLUGIN);
+ return osEnd;
+ default: {
+ DoShowMode = false;
+ switch (int(Key)) {
+ default: {
+ switch (Key) {
+ case kOk:
+ if (visible && !modeOnly) {
+ Hide();
+ DoShowMode = true;
+ } else
+ Show();
+ break;
+ case kBack:
+ Hide();
+ menu = new cStreamSelectMenu(&m_Video);
+ break;
+ default:
+ return osUnknown;
+ }
+ }
+ }
+ }
+ if (DoShowMode)
+ ShowMode();
+ }
+
+ return osContinue;
}
-bool cHlsPlayerControl::Active(void)
-{
- return player && player->Active();
+bool cHlsPlayerControl::Active(void) {
+ return player && player->Active();
}
-void cHlsPlayerControl::Pause(void)
-{
- if(player)
- player->Pause();
+void cHlsPlayerControl::Pause(void) {
+ if (player)
+ player->Pause();
}
-void cHlsPlayerControl::Play(void)
-{
- if(player)
- player->Play();
+void cHlsPlayerControl::Play(void) {
+ if (player)
+ player->Play();
}
-void cHlsPlayerControl::Stop(void)
-{
- if(player)
- player->Stop();
+void cHlsPlayerControl::Stop(void) {
+ if (player)
+ player->Stop();
}
-void cHlsPlayerControl::SeekTo(int offset)
-{
- if (player) {
- player->JumpTo(offset);
- }
+void cHlsPlayerControl::SeekTo(int offset) {
+ if (player) {
+ player->JumpTo(offset);
+ }
}
-void cHlsPlayerControl::JumpRelative(int offset)
-{
- if (player)
- player->JumpRelative(offset);
+void cHlsPlayerControl::JumpRelative(int offset) {
+ if (player)
+ player->JumpRelative(offset);
}
-void cHlsPlayerControl::ShowMode(void)
-{
- //dsyslog("[plex]: '%s'\n", __FUNCTION__);
- if (visible || (Setup.ShowReplayMode && !cOsd::IsOpen())) {
- bool Play, Forward;
- int Speed;
- if (GetReplayMode(Play, Forward, Speed) && (!visible || Play != lastPlay || Forward != lastForward || Speed != lastSpeed)) {
- bool NormalPlay = (Play && Speed == -1);
-
- if (!visible) {
- if (NormalPlay)
- return; // no need to do indicate ">" unless there was a different mode displayed before
- visible = modeOnly = true;
- displayReplay = Skins.Current()->DisplayReplay(modeOnly);
- }
-
- if (modeOnly && !timeoutShow && NormalPlay)
- timeoutShow = time(NULL) + 3;
- displayReplay->SetMode(Play, Forward, Speed);
- lastPlay = Play;
- lastForward = Forward;
- lastSpeed = Speed;
- }
- }
+void cHlsPlayerControl::ShowMode(void) {
+ //dsyslog("[plex]: '%s'\n", __FUNCTION__);
+ if (visible || (Setup.ShowReplayMode && !cOsd::IsOpen())) {
+ bool Play, Forward;
+ int Speed;
+ if (GetReplayMode(Play, Forward, Speed) &&
+ (!visible || Play != lastPlay || Forward != lastForward || Speed != lastSpeed)) {
+ bool NormalPlay = (Play && Speed == -1);
+
+ if (!visible) {
+ if (NormalPlay)
+ return; // no need to do indicate ">" unless there was a different mode displayed before
+ visible = modeOnly = true;
+ displayReplay = Skins.Current()->DisplayReplay(modeOnly);
+ }
+
+ if (modeOnly && !timeoutShow && NormalPlay)
+ timeoutShow = time(NULL) + 3;
+ displayReplay->SetMode(Play, Forward, Speed);
+ lastPlay = Play;
+ lastForward = Forward;
+ lastSpeed = Speed;
+ }
+ }
}
-bool cHlsPlayerControl::ShowProgress(bool Initial)
-{
- int Current, Total;
-
- if (GetIndex(Current, Total)) {
- if (!visible) {
- displayReplay = Skins.Current()->DisplayReplay(modeOnly);
- displayReplay->SetButtons(NULL,tr("Skip Back"),tr("Skip Forward"),tr("Stop"));
- SetNeedsFastResponse(true);
- visible = true;
- }
- if (Initial) {
- lastCurrent = lastTotal = -1;
- }
- if (Current != lastCurrent || Total != lastTotal) {
- if (Setup.ShowRemainingTime || Total != lastTotal) {
- int Index = Total;
- if (Setup.ShowRemainingTime)
- Index = Current - Index;
- displayReplay->SetTotal(IndexToHMSF(Index, false, FramesPerSecond()));
- if (!Initial)
- displayReplay->Flush();
- }
- displayReplay->SetProgress(Current, Total);
- if (!Initial)
- displayReplay->Flush();
- displayReplay->SetCurrent(IndexToHMSF(Current, false, FramesPerSecond()));
- displayReplay->SetTitle(m_title.c_str());
- displayReplay->Flush();
- lastCurrent = Current;
- }
- lastTotal = Total;
- ShowMode();
- return true;
- }
- return false;
+bool cHlsPlayerControl::ShowProgress(bool Initial) {
+ int Current, Total;
+
+ if (GetIndex(Current, Total)) {
+ if (!visible) {
+ displayReplay = Skins.Current()->DisplayReplay(modeOnly);
+ displayReplay->SetButtons(NULL, tr("Skip Back"), tr("Skip Forward"), tr("Stop"));
+ SetNeedsFastResponse(true);
+ visible = true;
+ }
+ if (Initial) {
+ lastCurrent = lastTotal = -1;
+ }
+ if (Current != lastCurrent || Total != lastTotal) {
+ if (Setup.ShowRemainingTime || Total != lastTotal) {
+ int Index = Total;
+ if (Setup.ShowRemainingTime)
+ Index = Current - Index;
+ displayReplay->SetTotal(IndexToHMSF(Index, false, FramesPerSecond()));
+ if (!Initial)
+ displayReplay->Flush();
+ }
+ displayReplay->SetProgress(Current, Total);
+ if (!Initial)
+ displayReplay->Flush();
+ displayReplay->SetCurrent(IndexToHMSF(Current, false, FramesPerSecond()));
+ displayReplay->SetTitle(m_title.c_str());
+ displayReplay->Flush();
+ lastCurrent = Current;
+ }
+ lastTotal = Total;
+ ShowMode();
+ return true;
+ }
+ return false;
}
-void cHlsPlayerControl::ShowTimed(int Seconds)
-{
- if (modeOnly)
- Hide();
- if (!visible) {
- shown = ShowProgress(true);
- timeoutShow = (shown && Seconds > 0) ? time(NULL) + Seconds : 0;
- } else if (timeoutShow && Seconds > 0)
- timeoutShow = time(NULL) + Seconds;
+void cHlsPlayerControl::ShowTimed(int Seconds) {
+ if (modeOnly)
+ Hide();
+ if (!visible) {
+ shown = ShowProgress(true);
+ timeoutShow = (shown && Seconds > 0) ? time(NULL) + Seconds : 0;
+ } else if (timeoutShow && Seconds > 0)
+ timeoutShow = time(NULL) + Seconds;
}
-cStreamSelectMenu::cStreamSelectMenu(plexclient::cVideo* Video) : cOsdMenu("StreamSelect")
-{
- pVideo = Video;
- CreateMenu();
+cStreamSelectMenu::cStreamSelectMenu(plexclient::cVideo *Video) : cOsdMenu("StreamSelect") {
+ pVideo = Video;
+ CreateMenu();
}
-void cStreamSelectMenu::CreateMenu()
-{
- SetTitle(cString::sprintf(tr("%s - Select Audio / Subtitle"), pVideo->GetTitle().c_str()));
- pVideo->UpdateFromServer();
-
- if(pVideo->m_Media.m_vStreams.size() > 0) {
- std::vector<plexclient::Stream> streams = pVideo->m_Media.m_vStreams;
-
- Add(new cOsdItem(tr("Audiostreams"), osUnknown, false));
- for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
- plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
- // Audio
- cString item = cString::sprintf(tr("%s%s - %s %d Channels"), pStream->m_bSelected ? "[*] ":"", pStream->m_sLanguage.c_str(), pStream->m_sCodecId.c_str(), pStream->m_iChannels);
- Add(new cPlexOsdItem(item, pStream));
- }
- }
-
- Add(new cOsdItem(tr("Subtitlestreams"), osUnknown, false));
- plexclient::Stream stre;
- stre.m_eStreamType = plexclient::StreamType::sSUBTITLE;
- stre.m_iID = -1;
- Add(new cPlexOsdItem(tr("None"), &stre));
- for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
- plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::StreamType::sSUBTITLE) {
- // Subtitle
- cString item = cString::sprintf("%s%s", pStream->m_bSelected ? "[*] ":"", pStream->m_sLanguage.c_str());
- Add(new cPlexOsdItem(item, pStream));
- }
- }
- }
-
- Display();
+void cStreamSelectMenu::CreateMenu() {
+ SetTitle(cString::sprintf(tr("%s - Select Audio / Subtitle"), pVideo->GetTitle().c_str()));
+ pVideo->UpdateFromServer();
+
+ if (pVideo->m_Media.m_vStreams.size() > 0) {
+ std::vector<plexclient::Stream> streams = pVideo->m_Media.m_vStreams;
+
+ Add(new cOsdItem(tr("Audiostreams"), osUnknown, false));
+ for (std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
+ plexclient::Stream *pStream = &(*it);
+ if (pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
+ // Audio
+ cString item = cString::sprintf(tr("%s%s - %s %d Channels"), pStream->m_bSelected ? "[*] " : "",
+ pStream->m_sLanguage.c_str(), pStream->m_sCodecId.c_str(),
+ pStream->m_iChannels);
+ Add(new cPlexOsdItem(item, pStream));
+ }
+ }
+
+ Add(new cOsdItem(tr("Subtitlestreams"), osUnknown, false));
+ plexclient::Stream stre;
+ stre.m_eStreamType = plexclient::StreamType::sSUBTITLE;
+ stre.m_iID = -1;
+ Add(new cPlexOsdItem(tr("None"), &stre));
+ for (std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
+ plexclient::Stream *pStream = &(*it);
+ if (pStream->m_eStreamType == plexclient::StreamType::sSUBTITLE) {
+ // Subtitle
+ cString item = cString::sprintf("%s%s", pStream->m_bSelected ? "[*] " : "",
+ pStream->m_sLanguage.c_str());
+ Add(new cPlexOsdItem(item, pStream));
+ }
+ }
+ }
+
+ Display();
}
-bool cStreamSelectMenu::SelectStream()
-{
- int current = Current(); // get current menu item index
- cPlexOsdItem *item = static_cast<cPlexOsdItem*>(Get(current));
- return pVideo->SetStream(&item->GetAttachedStream());
+bool cStreamSelectMenu::SelectStream() {
+ int current = Current(); // get current menu item index
+ cPlexOsdItem *item = static_cast<cPlexOsdItem *>(Get(current));
+ return pVideo->SetStream(&item->GetAttachedStream());
}
-eOSState cStreamSelectMenu::ProcessKey(eKeys Keys)
-{
- eOSState state;
-
- // call standard function
- state = cOsdMenu::ProcessKey(Keys);
-
- switch (state) {
- case osUnknown:
- switch (Keys) {
- case kOk:
- return SelectStream() ? osEnd : osBack;
- case kBack:
- return osBack;
- default:
- break;
- }
- break;
- case osBack:
- return osBack;
- default:
- break;
- }
- return state;
+eOSState cStreamSelectMenu::ProcessKey(eKeys Keys) {
+ eOSState state;
+
+ // call standard function
+ state = cOsdMenu::ProcessKey(Keys);
+
+ switch (state) {
+ case osUnknown:
+ switch (Keys) {
+ case kOk:
+ return SelectStream() ? osEnd : osBack;
+ case kBack:
+ return osBack;
+ default:
+ break;
+ }
+ break;
+ case osBack:
+ return osBack;
+ default:
+ break;
+ }
+ return state;
}
diff --git a/hlsPlayerControl.h b/hlsPlayerControl.h
index c208502..b777c40 100644
--- a/hlsPlayerControl.h
+++ b/hlsPlayerControl.h
@@ -8,60 +8,71 @@
#include "MediaContainer.h"
#include "PVideo.h"
-class cStreamSelectMenu : public cOsdMenu
-{
+class cStreamSelectMenu : public cOsdMenu {
private:
- plexclient::cVideo* pVideo;
- void CreateMenu();
- bool SelectStream();
-
+ plexclient::cVideo *pVideo;
+
+ void CreateMenu();
+
+ bool SelectStream();
+
public:
- cStreamSelectMenu(plexclient::cVideo* Video);
- virtual eOSState ProcessKey(eKeys Keys);
+ cStreamSelectMenu(plexclient::cVideo *Video);
+
+ virtual eOSState ProcessKey(eKeys Keys);
};
-class cHlsPlayerControl : public cControl
-{
+class cHlsPlayerControl : public cControl {
private:
- static volatile int active;
- cHlsPlayer* player;
- std::string m_title;
-
- cStreamSelectMenu* menu;
- cSkinDisplayReplay *displayReplay;
- bool visible, modeOnly, shown;
- int lastCurrent, lastTotal;
- bool lastPlay, lastForward;
- int lastSpeed;
- time_t timeoutShow;
-
- void ShowMode(void);
- bool ShowProgress(bool Initial);
- void ShowTimed(int Seconds = 0);
+ static volatile int active;
+ cHlsPlayer *player;
+ std::string m_title;
+
+ cStreamSelectMenu *menu;
+ cSkinDisplayReplay *displayReplay;
+ bool visible, modeOnly, shown;
+ int lastCurrent, lastTotal;
+ bool lastPlay, lastForward;
+ int lastSpeed;
+ time_t timeoutShow;
+
+ void ShowMode(void);
+
+ bool ShowProgress(bool Initial);
+
+ void ShowTimed(int Seconds = 0);
protected:
- //void ShowMode();
+ //void ShowMode();
public:
- plexclient::cVideo m_Video;
+ plexclient::cVideo m_Video;
+
+ static cControl *Create(plexclient::cVideo Video);
+
+ cHlsPlayerControl(cHlsPlayer *Player, plexclient::cVideo Video);
+
+ virtual ~cHlsPlayerControl();
+
+ virtual void Show(void);
+
+ virtual void Hide(void);
+
+ virtual cString GetHeader(void);
+
+ virtual eOSState ProcessKey(eKeys Key);
+
+ bool Active(void);
- static cControl* Create(plexclient::cVideo Video);
- cHlsPlayerControl(cHlsPlayer* Player, plexclient::cVideo Video);
- virtual ~cHlsPlayerControl();
+ void Pause(void);
- virtual void Show(void);
- virtual void Hide(void);
+ void Play(void);
- virtual cString GetHeader(void);
- virtual eOSState ProcessKey(eKeys Key);
+ void Stop(void);
- bool Active(void);
+ void SeekTo(int offset);
- void Pause(void);
- void Play(void);
- void Stop(void);
- void SeekTo(int offset);
- void JumpRelative(int offset);
+ void JumpRelative(int offset);
};
diff --git a/m3u8Parser.cpp b/m3u8Parser.cpp
index 9c2657f..35b6747 100644
--- a/m3u8Parser.cpp
+++ b/m3u8Parser.cpp
@@ -2,116 +2,113 @@
#include <pcrecpp.h>
#include <vdr/tools.h>
-cM3u8Parser::cM3u8Parser()
-{
- Init();
+cM3u8Parser::cM3u8Parser() {
+ Init();
}
-cM3u8Parser::cM3u8Parser(std::istream& m3u8)
-{
- Init();
- Parse(m3u8);
+
+cM3u8Parser::cM3u8Parser(std::istream &m3u8) {
+ Init();
+ Parse(m3u8);
}
-void cM3u8Parser::Init()
-{
- TargetDuration = -1;
- MediaSequence = -1;
- MasterPlaylist = false;
- AllowCache = true;
+
+void cM3u8Parser::Init() {
+ TargetDuration = -1;
+ MediaSequence = -1;
+ MasterPlaylist = false;
+ AllowCache = true;
}
-bool cM3u8Parser::Parse(std::istream& m3u8)
-{
- bool ok = true;
- bool nextLineIsMedia = false;
- int lineNo = 0;
+bool cM3u8Parser::Parse(std::istream &m3u8) {
+ bool ok = true;
+ bool nextLineIsMedia = false;
+ int lineNo = 0;
- // prepare regex
- pcrecpp::RE re("#(EXT[^:\\n]+)(?::[^\\n]+)");
- pcrecpp::RE reVal("(?::([^\\n]+))");
+ // prepare regex
+ pcrecpp::RE re("#(EXT[^:\\n]+)(?::[^\\n]+)");
+ pcrecpp::RE reVal("(?::([^\\n]+))");
- std::string line;
- playListItem pItem;
- pItem.bandwidth = -1;
- pItem.file = "";
- pItem.length = -1;
- pItem.programId = -1;
+ std::string line;
+ playListItem pItem;
+ pItem.bandwidth = -1;
+ pItem.file = "";
+ pItem.length = -1;
+ pItem.programId = -1;
- while (std::getline(m3u8, line)) {
- if(lineNo == 0 && "#EXTM3U" == line ) {
- lineNo++;
- continue;
- } else if(lineNo == 0) {
- // Invalid File
- ok = false;
- esyslog("[plex]%s m3u8 is invalid. dumping File:", __FUNCTION__);
- esyslog("[plex]%s", line.c_str());
- eDump(m3u8);
- break;
- }
+ while (std::getline(m3u8, line)) {
+ if (lineNo == 0 && "#EXTM3U" == line) {
+ lineNo++;
+ continue;
+ } else if (lineNo == 0) {
+ // Invalid File
+ ok = false;
+ esyslog("[plex]%s m3u8 is invalid. dumping File:", __FUNCTION__);
+ esyslog("[plex]%s", line.c_str());
+ eDump(m3u8);
+ break;
+ }
- if( re.FullMatch(line) ) {
- string var;
- //string value;
- re.PartialMatch(line, &var);
- if("EXT-X-TARGETDURATION" == var) {
- int value;
- reVal.PartialMatch(line, &value);
- TargetDuration = value;
- } else if ("EXT-X-ALLOW-CACHE" == var) {
- string value;
- reVal.PartialMatch(line, &value);
- AllowCache = "YES" == value;
- } else if ("EXT-X-MEDIA-SEQUENCE" == var) {
- int value;
- reVal.PartialMatch(line, &value);
- MediaSequence = value;
- } else if ("EXT-X-STREAM-INF" == var) {
- MasterPlaylist = true;
- nextLineIsMedia = true;
+ if (re.FullMatch(line)) {
+ string var;
+ //string value;
+ re.PartialMatch(line, &var);
+ if ("EXT-X-TARGETDURATION" == var) {
+ int value;
+ reVal.PartialMatch(line, &value);
+ TargetDuration = value;
+ } else if ("EXT-X-ALLOW-CACHE" == var) {
+ string value;
+ reVal.PartialMatch(line, &value);
+ AllowCache = "YES" == value;
+ } else if ("EXT-X-MEDIA-SEQUENCE" == var) {
+ int value;
+ reVal.PartialMatch(line, &value);
+ MediaSequence = value;
+ } else if ("EXT-X-STREAM-INF" == var) {
+ MasterPlaylist = true;
+ nextLineIsMedia = true;
- int bandw;
- pcrecpp::RE reBand("BANDWIDTH=(\\d+)");
- if(reBand.PartialMatch(line, &bandw)) {
- pItem.bandwidth = bandw;
- }
+ int bandw;
+ pcrecpp::RE reBand("BANDWIDTH=(\\d+)");
+ if (reBand.PartialMatch(line, &bandw)) {
+ pItem.bandwidth = bandw;
+ }
- int id;
- pcrecpp::RE reId("PROGRAM-ID=(\\d+)");
- if(reId.PartialMatch(line, &id)) {
- pItem.programId = id;
- }
+ int id;
+ pcrecpp::RE reId("PROGRAM-ID=(\\d+)");
+ if (reId.PartialMatch(line, &id)) {
+ pItem.programId = id;
+ }
- } else if ("EXTINF" == var) {
- MasterPlaylist = false;
- int value;
- pcrecpp::RE reInt("(?:#EXTINF:([\\d]+))");
- if( reInt.PartialMatch(line, &value)) {
- nextLineIsMedia = true;
- pItem.length = value;
- }
- }
- }
- // possible mediafile
- else {
- if(nextLineIsMedia) {
- nextLineIsMedia = false;
- pItem.file = line;
- pItem.size = 0;
- vPlaylistItems.push_back(pItem);
- }
- }
- lineNo++;
- }
- return ok;
+ } else if ("EXTINF" == var) {
+ MasterPlaylist = false;
+ int value;
+ pcrecpp::RE reInt("(?:#EXTINF:([\\d]+))");
+ if (reInt.PartialMatch(line, &value)) {
+ nextLineIsMedia = true;
+ pItem.length = value;
+ }
+ }
+ }
+ // possible mediafile
+ else {
+ if (nextLineIsMedia) {
+ nextLineIsMedia = false;
+ pItem.file = line;
+ pItem.size = 0;
+ vPlaylistItems.push_back(pItem);
+ }
+ }
+ lineNo++;
+ }
+ return ok;
}
-void cM3u8Parser::eDump(std::istream &m3u8)
-{
- std::string line;
- while (std::getline(m3u8, line)) {
- esyslog("[plex]%s", line.c_str());
- }
+void cM3u8Parser::eDump(std::istream &m3u8) {
+ std::string line;
+ while (std::getline(m3u8, line)) {
+ esyslog("[plex]%s", line.c_str());
+ }
}
/*
diff --git a/m3u8Parser.h b/m3u8Parser.h
index 3bd0ae2..ed915f9 100644
--- a/m3u8Parser.h
+++ b/m3u8Parser.h
@@ -5,32 +5,35 @@
#include <string>
#include <iostream>
-class cM3u8Parser
-{
+class cM3u8Parser {
public:
- struct playListItem {
- int length;
- int bandwidth;
- int programId;
- std::string file;
- int size;
- };
+ struct playListItem {
+ int length;
+ int bandwidth;
+ int programId;
+ std::string file;
+ int size;
+ };
private:
- void Init();
- void eDump(std::istream &m3u8);
+ void Init();
+
+ void eDump(std::istream &m3u8);
public:
- std::vector<playListItem> vPlaylistItems;
- int TargetDuration;
- int MediaSequence;
- bool MasterPlaylist;
- bool AllowCache;
- bool Parse(std::istream &m3u8);
+ std::vector<playListItem> vPlaylistItems;
+ int TargetDuration;
+ int MediaSequence;
+ bool MasterPlaylist;
+ bool AllowCache;
+
+ bool Parse(std::istream &m3u8);
public:
- cM3u8Parser(std::istream &m3u8);
- cM3u8Parser();
- ~cM3u8Parser() {};
+ cM3u8Parser(std::istream &m3u8);
+
+ cM3u8Parser();
+
+ ~cM3u8Parser() { };
};
diff --git a/pictureCache.cpp b/pictureCache.cpp
index 2fcc6eb..af0871a 100644
--- a/pictureCache.cpp
+++ b/pictureCache.cpp
@@ -18,149 +18,147 @@ using Poco::StreamCopier;
using Poco::Path;
using Poco::Exception;
-cPictureCache::cPictureCache()
-{
- m_cacheDir = cPlugin::CacheDirectory(PLUGIN_NAME_I18N);
-
- Poco::Path path(m_cacheDir);
- Poco::File f(path.toString());
- f.createDirectories();
- m_bAllInvalidated = false;
+cPictureCache::cPictureCache() {
+ m_cacheDir = cPlugin::CacheDirectory(PLUGIN_NAME_I18N);
+
+ Poco::Path path(m_cacheDir);
+ Poco::File f(path.toString());
+ f.createDirectories();
+ m_bAllInvalidated = false;
}
-bool cPictureCache::DownloadFileAndSave(std::string Uri, std::string localFile)
-{
- try {
- Poco::URI fileUri(Uri);
- plexclient::PlexServer* pServer = plexclient::plexgdm::GetInstance().GetServer(fileUri.getHost(), fileUri.getPort());
-
- bool ok;
- auto cSession = pServer->MakeRequest(ok, fileUri.getPathAndQuery());
- Poco::Net::HTTPResponse response;
- std::istream &rs = cSession->receiveResponse(response);
-
- if (!ok || response.getStatus() != 200)
- return false;
-
- std::string type = response.getContentType();
- std::string fileName = localFile;
-
- // check filetype
- char buffer[2];
- rs.read(buffer, 2);
- bool isPng = false;
-
- if(buffer[0] == char(0x89) && buffer[1] == char(0x50) ) {
- isPng = true;
- }
- rs.putback(buffer[1]);
- rs.putback(buffer[0]);
-
- if(isPng) {
- fileName += ".png";
- } else if(type == "image/jpeg" || fileUri.getPathAndQuery().find(".jpg") != std::string::npos) {
- fileName += ".jpg";
- }
-
- Poco::Path p(fileName);
- Poco::File f(p.makeParent().toString());
- f.createDirectories();
-
- std::ofstream outFile;
- outFile.open(fileName);
- Poco::StreamCopier::copyStream(rs, outFile);
- outFile.close();
- return true;
- } catch (Poco::Exception &exc) {
- std::cout << exc.displayText() << std::endl;
- return false;
- }
+bool cPictureCache::DownloadFileAndSave(std::string Uri, std::string localFile) {
+ try {
+ Poco::URI fileUri(Uri);
+ plexclient::PlexServer *pServer = plexclient::plexgdm::GetInstance().GetServer(fileUri.getHost(),
+ fileUri.getPort());
+
+ bool ok;
+ auto cSession = pServer->MakeRequest(ok, fileUri.getPathAndQuery());
+ Poco::Net::HTTPResponse response;
+ std::istream &rs = cSession->receiveResponse(response);
+
+ if (!ok || response.getStatus() != 200)
+ return false;
+
+ std::string type = response.getContentType();
+ std::string fileName = localFile;
+
+ // check filetype
+ char buffer[2];
+ rs.read(buffer, 2);
+ bool isPng = false;
+
+ if (buffer[0] == char(0x89) && buffer[1] == char(0x50)) {
+ isPng = true;
+ }
+ rs.putback(buffer[1]);
+ rs.putback(buffer[0]);
+
+ if (isPng) {
+ fileName += ".png";
+ } else if (type == "image/jpeg" || fileUri.getPathAndQuery().find(".jpg") != std::string::npos) {
+ fileName += ".jpg";
+ }
+
+ Poco::Path p(fileName);
+ Poco::File f(p.makeParent().toString());
+ f.createDirectories();
+
+ std::ofstream outFile;
+ outFile.open(fileName);
+ Poco::StreamCopier::copyStream(rs, outFile);
+ outFile.close();
+ return true;
+ } catch (Poco::Exception &exc) {
+ std::cout << exc.displayText() << std::endl;
+ return false;
+ }
}
-std::string cPictureCache::FileName(std::string uri, int width)
-{
- Poco::URI u(uri);
- plexclient::PlexServer* pServer = plexclient::plexgdm::GetInstance().GetServer(u.getHost(), u.getPort());
- std::string uuid = "default";
- if(pServer && !pServer->GetUuid().empty()) {
- uuid = pServer->GetUuid();
- }
- std::string file = Poco::format("%s/%s_%d", uuid, u.getPathAndQuery(), width);
+std::string cPictureCache::FileName(std::string uri, int width) {
+ Poco::URI u(uri);
+ plexclient::PlexServer *pServer = plexclient::plexgdm::GetInstance().GetServer(u.getHost(), u.getPort());
+ std::string uuid = "default";
+ if (pServer && !pServer->GetUuid().empty()) {
+ uuid = pServer->GetUuid();
+ }
+ std::string file = Poco::format("%s/%s_%d", uuid, u.getPathAndQuery(), width);
- Poco::Path path(m_cacheDir);
- path.append(file);
+ Poco::Path path(m_cacheDir);
+ path.append(file);
- return path.toString();
+ return path.toString();
}
-std::string cPictureCache::TranscodeUri(std::string uri, int width, int height)
-{
- // We have to transform the uri a little...
- // httpX://ServerUri/.../queryUri=localhost
-
- Poco::URI u(uri);
- auto plServer = plexclient::plexgdm::GetInstance().GetServer(u.getHost(), u.getPort());
- u.setHost("127.0.0.1"); // set to localhost and http only!
- u.setScheme("http");
-
- Poco::URI serverUri(plServer->GetUri());
- serverUri.setPath("/photo/:/transcode");
- serverUri.addQueryParameter("width", std::to_string(width));
- serverUri.addQueryParameter("height", std::to_string(height));
- serverUri.addQueryParameter("url", u.toString());
-
- return serverUri.toString();
+std::string cPictureCache::TranscodeUri(std::string uri, int width, int height) {
+ // We have to transform the uri a little...
+ // httpX://ServerUri/.../queryUri=localhost
+
+ Poco::URI u(uri);
+ auto plServer = plexclient::plexgdm::GetInstance().GetServer(u.getHost(), u.getPort());
+ u.setHost("127.0.0.1"); // set to localhost and http only!
+ u.setScheme("http");
+
+ Poco::URI serverUri(plServer->GetUri());
+ serverUri.setPath("/photo/:/transcode");
+ serverUri.addQueryParameter("width", std::to_string(width));
+ serverUri.addQueryParameter("height", std::to_string(height));
+ serverUri.addQueryParameter("url", u.toString());
+
+ return serverUri.toString();
}
-bool cPictureCache::Cached(std::string uri, int width)
-{
- bool cached = true;
- try {
- cached = m_mCached.at(FileName(uri, width));
- } catch (std::out_of_range) { }
-
- bool onDisk = Poco::File(FileName(uri, width) + ".jpg").exists() || Poco::File(FileName(uri, width) + ".png").exists();
- return onDisk && cached;
+bool cPictureCache::Cached(std::string uri, int width) {
+ bool cached = true;
+ try {
+ cached = m_mCached.at(FileName(uri, width));
+ } catch (std::out_of_range) { }
+
+ bool onDisk =
+ Poco::File(FileName(uri, width) + ".jpg").exists() || Poco::File(FileName(uri, width) + ".png").exists();
+ return onDisk && cached;
}
-std::string cPictureCache::GetPath(std::string uri, int width, int height, bool& cached, std::function<void(cGridElement*)> OnCached, cGridElement* calle)
-{
- m_bAllInvalidated = false;
- cached = Cached(uri, width);
- std::string file = FileName(uri, width);
- if(cached) {
- if(Poco::File(FileName(uri, width) + ".jpg").exists()) {
- file += ".jpg";
- } else if(Poco::File(FileName(uri, width) + ".png").exists()) {
- file += ".png";
- }
- return file;
- } else {
-
- try {
- m_mCached.at(file);
- return file;
- } catch (std::out_of_range) { }
-
- std::string transcodeUri = TranscodeUri(uri, width, height);
-
- m_mCached[file] = false;
-
- m_vFutures.push_back(std::async(std::launch::async,
- [&] (std::string tsUri, std::string fn, std::function<void(cGridElement*)> onCached, cGridElement* ca) {
- bool ok = DownloadFileAndSave(tsUri, fn);
- if(ok) {
- m_mCached[fn] = true;
- }
- if (ok && onCached && ca && ca->IsVisible()) {
- onCached(ca);
- }
- return;
- },
- transcodeUri, file, OnCached, calle) );
- }
-
- return file;
+std::string cPictureCache::GetPath(std::string uri, int width, int height, bool &cached,
+ std::function<void(cGridElement *)> OnCached, cGridElement *calle) {
+ m_bAllInvalidated = false;
+ cached = Cached(uri, width);
+ std::string file = FileName(uri, width);
+ if (cached) {
+ if (Poco::File(FileName(uri, width) + ".jpg").exists()) {
+ file += ".jpg";
+ } else if (Poco::File(FileName(uri, width) + ".png").exists()) {
+ file += ".png";
+ }
+ return file;
+ } else {
+
+ try {
+ m_mCached.at(file);
+ return file;
+ } catch (std::out_of_range) { }
+
+ std::string transcodeUri = TranscodeUri(uri, width, height);
+
+ m_mCached[file] = false;
+
+ m_vFutures.push_back(std::async(std::launch::async,
+ [&](std::string tsUri, std::string fn,
+ std::function<void(cGridElement *)> onCached, cGridElement *ca) {
+ bool ok = DownloadFileAndSave(tsUri, fn);
+ if (ok) {
+ m_mCached[fn] = true;
+ }
+ if (ok && onCached && ca && ca->IsVisible()) {
+ onCached(ca);
+ }
+ return;
+ },
+ transcodeUri, file, OnCached, calle));
+ }
+
+ return file;
}
diff --git a/pictureCache.h b/pictureCache.h
index e259c6f..2cf1bd6 100644
--- a/pictureCache.h
+++ b/pictureCache.h
@@ -14,50 +14,55 @@
#include "viewGridNavigator.h"
enum ImageResolution {
- SD384,
- SD480,
- HD720,
- HD1080
+ SD384,
+ SD480,
+ HD720,
+ HD1080
};
-class cPictureCache
-{
+class cPictureCache {
private:
- struct CacheInfo {
- CacheInfo(std::string Uri, int Width, int Height, std::function<void(cGridElement*)> OnCached, cGridElement* Calle) {
- uri = Uri;
- width = Width;
- height = Height;
- onCached = OnCached;
- calle = Calle;
- };
- std::string uri;
- int width;
- int height;
- std::function<void(cGridElement*)> onCached;
- cGridElement* calle;
- bool downloaded;
- };
- cPictureCache();
- std::map<std::string, bool> m_mCached;
- std::vector<std::future<void>> m_vFutures;
- volatile bool m_bAllInvalidated;
-
- std::string FileName(std::string uri, int width);
- std::string TranscodeUri(std::string uri, int width, int height);
-
- static bool DownloadFileAndSave(std::string uri, std::string localFile);
- bool Cached(std::string uri, int width);
-
- std::string m_cacheDir;
+ struct CacheInfo {
+ CacheInfo(std::string Uri, int Width, int Height, std::function<void(cGridElement *)> OnCached,
+ cGridElement *Calle) {
+ uri = Uri;
+ width = Width;
+ height = Height;
+ onCached = OnCached;
+ calle = Calle;
+ };
+ std::string uri;
+ int width;
+ int height;
+ std::function<void(cGridElement *)> onCached;
+ cGridElement *calle;
+ bool downloaded;
+ };
+
+ cPictureCache();
+
+ std::map<std::string, bool> m_mCached;
+ std::vector<std::future<void>> m_vFutures;
+ volatile bool m_bAllInvalidated;
+
+ std::string FileName(std::string uri, int width);
+
+ std::string TranscodeUri(std::string uri, int width, int height);
+
+ static bool DownloadFileAndSave(std::string uri, std::string localFile);
+
+ bool Cached(std::string uri, int width);
+
+ std::string m_cacheDir;
public:
- static cPictureCache& GetInstance() {
- static cPictureCache instance;
- return instance;
- }
+ static cPictureCache &GetInstance() {
+ static cPictureCache instance;
+ return instance;
+ }
- std::string GetPath(std::string uri, int width, int height, bool& cached, std::function<void(cGridElement*)> OnCached = NULL, cGridElement* calle = NULL);
+ std::string GetPath(std::string uri, int width, int height, bool &cached,
+ std::function<void(cGridElement *)> OnCached = NULL, cGridElement *calle = NULL);
};
#endif // CPICTURECACHE_H
diff --git a/playlist.cpp b/playlist.cpp
index 4162591..772e14d 100644
--- a/playlist.cpp
+++ b/playlist.cpp
@@ -1,11 +1,9 @@
#include "playlist.h"
-namespace plexclient
-{
+namespace plexclient {
-Playlist::Playlist(Poco::XML::Node* pNode, MediaContainer* parent)
-{
-}
+ Playlist::Playlist(Poco::XML::Node *pNode, MediaContainer *parent) {
+ }
}
diff --git a/playlist.h b/playlist.h
index 6363949..34e723c 100644
--- a/playlist.h
+++ b/playlist.h
@@ -4,15 +4,13 @@
#include "XmlObject.h" // Base class: plexclient::XmlObject
#include "MediaContainer.h"
-namespace plexclient
-{
+namespace plexclient {
-class Playlist : private plexclient::XmlObject
-{
-public:
- Playlist(Poco::XML::Node* pNode, MediaContainer* parent);
+ class Playlist : private plexclient::XmlObject {
+ public:
+ Playlist(Poco::XML::Node *pNode, MediaContainer *parent);
-};
+ };
}
diff --git a/plex.cpp b/plex.cpp
index 74b31f7..9d9523a 100644
--- a/plex.cpp
+++ b/plex.cpp
@@ -30,17 +30,15 @@ bool cMyPlugin::PlayingFile = false;
** @note DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
** VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
*/
-cMyPlugin::cMyPlugin(void)
-{
+cMyPlugin::cMyPlugin(void) {
}
/**
** Clean up after yourself!
*/
-cMyPlugin::~cMyPlugin(void)
-{
- plexclient::plexgdm::GetInstance().stopRegistration();
- plexclient::ControlServer::GetInstance().Stop();
+cMyPlugin::~cMyPlugin(void) {
+ plexclient::plexgdm::GetInstance().stopRegistration();
+ plexclient::ControlServer::GetInstance().Stop();
}
/**
@@ -48,9 +46,8 @@ cMyPlugin::~cMyPlugin(void)
**
** @returns version number as constant string.
*/
-const char *cMyPlugin::Version(void)
-{
- return VERSION;
+const char *cMyPlugin::Version(void) {
+ return VERSION;
}
/**
@@ -58,153 +55,158 @@ const char *cMyPlugin::Version(void)
**
** @returns short description as constant string.
*/
-const char *cMyPlugin::Description(void)
-{
- return DESCRIPTION;
+const char *cMyPlugin::Description(void) {
+ return DESCRIPTION;
}
-bool cMyPlugin::Start(void)
-{
+bool cMyPlugin::Start(void) {
#ifdef SKINDESIGNER
- m_pPlugStruct = new skindesignerapi::cPluginStructure();
- m_pPlugStruct->name = "plex";
- m_pPlugStruct->libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION;
-
- m_pPlugStruct->RegisterRootView("root.xml");
- skindesignerapi::cTokenContainer *tkBackground = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::background, tkBackground);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::background, "background", tkBackground);
-
- skindesignerapi::cTokenContainer *tkHeader = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::header, tkHeader);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::header, "header", tkHeader);
-
- skindesignerapi::cTokenContainer *tkFooter = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::footer, tkFooter);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::footer, "footer", tkFooter);
-
- skindesignerapi::cTokenContainer *tkInfopane = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::infopane, tkInfopane);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::infopane, "infopane", tkInfopane);
-
- skindesignerapi::cTokenContainer *tkWatch = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::watch, tkWatch);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::watch, "time", tkWatch);
-
- skindesignerapi::cTokenContainer *tkMessage = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::message, tkMessage);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::message, "message", tkMessage);
-
- skindesignerapi::cTokenContainer *tkScrollbar = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineTokens(eViewElementsRoot::scrollbar, tkScrollbar);
- m_pPlugStruct->RegisterViewElement((int)eViews::rootView, (int)eViewElementsRoot::scrollbar, "scrollbar", tkScrollbar);
-
- skindesignerapi::cTokenContainer *tkGridCover = new skindesignerapi::cTokenContainer();
- skindesignerapi::cTokenContainer *tkGridDetail = new skindesignerapi::cTokenContainer();
- skindesignerapi::cTokenContainer *tkGridList = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineGridTokens(tkGridCover);
- cPlexSdOsd::DefineGridTokens(tkGridDetail);
- cPlexSdOsd::DefineGridTokens(tkGridList);
- m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::cover, "coverbrowser", tkGridCover);
- m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::detail, "detailbrowser", tkGridDetail);
- m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::list, "listbrowser", tkGridList);
-
- // DetailsView
- m_pPlugStruct->RegisterSubView((int)eViews::detailView, "detail.xml");
- skindesignerapi::cTokenContainer *tkBackgroundDetail = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::background, tkBackgroundDetail);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::background, "background", tkBackgroundDetail);
-
- skindesignerapi::cTokenContainer *tkDetailInfo = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::info, tkDetailInfo);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::info, "info", tkDetailInfo);
-
- skindesignerapi::cTokenContainer *tkDetailFooter = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::footer, tkDetailFooter);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::footer, "footer", tkDetailFooter);
-
- skindesignerapi::cTokenContainer *tkDetailScrollbar = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::scrollbar, tkDetailScrollbar);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::scrollbar, "scrollbar", tkDetailScrollbar);
-
- skindesignerapi::cTokenContainer *tkDetailMessage = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::message, tkDetailMessage);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::message, "message", tkDetailMessage);
-
- skindesignerapi::cTokenContainer *tkDetailExtraGrid = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineGridTokens(tkDetailExtraGrid);
- m_pPlugStruct->RegisterViewGrid((int)eViews::detailView, (int)eViewDetailViewGrids::extras, "extragrid", tkDetailExtraGrid);
-
- skindesignerapi::cTokenContainer *tkDetailWatch = new skindesignerapi::cTokenContainer();
- cPlexSdOsd::DefineWatchTokens(tkDetailWatch);
- m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::watch, "time", tkDetailWatch);
-
-
- if (!skindesignerapi::SkindesignerAPI::RegisterPlugin(m_pPlugStruct)) {
- esyslog("[plex]: skindesigner not available");
- bSkindesigner = false;
- } else {
- dsyslog("[plex]: successfully registered at skindesigner, id %d", m_pPlugStruct->id);
- m_pTestOsd = new cPlexSdOsd(m_pPlugStruct);
- bSkindesigner = true;
- }
+ m_pPlugStruct = new skindesignerapi::cPluginStructure();
+ m_pPlugStruct->name = "plex";
+ m_pPlugStruct->libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION;
+
+ m_pPlugStruct->RegisterRootView("root.xml");
+ skindesignerapi::cTokenContainer *tkBackground = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::background, tkBackground);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::background, "background",
+ tkBackground);
+
+ skindesignerapi::cTokenContainer *tkHeader = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::header, tkHeader);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::header, "header", tkHeader);
+
+ skindesignerapi::cTokenContainer *tkFooter = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::footer, tkFooter);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::footer, "footer", tkFooter);
+
+ skindesignerapi::cTokenContainer *tkInfopane = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::infopane, tkInfopane);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::infopane, "infopane",
+ tkInfopane);
+
+ skindesignerapi::cTokenContainer *tkWatch = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::watch, tkWatch);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::watch, "time", tkWatch);
+
+ skindesignerapi::cTokenContainer *tkMessage = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::message, tkMessage);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::message, "message", tkMessage);
+
+ skindesignerapi::cTokenContainer *tkScrollbar = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineTokens(eViewElementsRoot::scrollbar, tkScrollbar);
+ m_pPlugStruct->RegisterViewElement((int) eViews::rootView, (int) eViewElementsRoot::scrollbar, "scrollbar",
+ tkScrollbar);
+
+ skindesignerapi::cTokenContainer *tkGridCover = new skindesignerapi::cTokenContainer();
+ skindesignerapi::cTokenContainer *tkGridDetail = new skindesignerapi::cTokenContainer();
+ skindesignerapi::cTokenContainer *tkGridList = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineGridTokens(tkGridCover);
+ cPlexSdOsd::DefineGridTokens(tkGridDetail);
+ cPlexSdOsd::DefineGridTokens(tkGridList);
+ m_pPlugStruct->RegisterViewGrid((int) eViews::rootView, (int) eViewGrids::cover, "coverbrowser", tkGridCover);
+ m_pPlugStruct->RegisterViewGrid((int) eViews::rootView, (int) eViewGrids::detail, "detailbrowser", tkGridDetail);
+ m_pPlugStruct->RegisterViewGrid((int) eViews::rootView, (int) eViewGrids::list, "listbrowser", tkGridList);
+
+ // DetailsView
+ m_pPlugStruct->RegisterSubView((int) eViews::detailView, "detail.xml");
+ skindesignerapi::cTokenContainer *tkBackgroundDetail = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::background, tkBackgroundDetail);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::background, "background",
+ tkBackgroundDetail);
+
+ skindesignerapi::cTokenContainer *tkDetailInfo = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::info, tkDetailInfo);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::info, "info", tkDetailInfo);
+
+ skindesignerapi::cTokenContainer *tkDetailFooter = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::footer, tkDetailFooter);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::footer, "footer",
+ tkDetailFooter);
+
+ skindesignerapi::cTokenContainer *tkDetailScrollbar = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::scrollbar, tkDetailScrollbar);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::scrollbar, "scrollbar",
+ tkDetailScrollbar);
+
+ skindesignerapi::cTokenContainer *tkDetailMessage = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::message, tkDetailMessage);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::message, "message",
+ tkDetailMessage);
+
+ skindesignerapi::cTokenContainer *tkDetailExtraGrid = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineGridTokens(tkDetailExtraGrid);
+ m_pPlugStruct->RegisterViewGrid((int) eViews::detailView, (int) eViewDetailViewGrids::extras, "extragrid",
+ tkDetailExtraGrid);
+
+ skindesignerapi::cTokenContainer *tkDetailWatch = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineWatchTokens(tkDetailWatch);
+ m_pPlugStruct->RegisterViewElement((int) eViews::detailView, (int) eViewElementsDetail::watch, "time",
+ tkDetailWatch);
+
+
+ if (!skindesignerapi::SkindesignerAPI::RegisterPlugin(m_pPlugStruct)) {
+ esyslog("[plex]: skindesigner not available");
+ bSkindesigner = false;
+ } else {
+ dsyslog("[plex]: successfully registered at skindesigner, id %d", m_pPlugStruct->id);
+ m_pTestOsd = new cPlexSdOsd(m_pPlugStruct);
+ bSkindesigner = true;
+ }
#endif
- return true;
+ return true;
}
/**
** Start any background activities the plugin shall perform.
*/
-bool cMyPlugin::Initialize(void)
-{
- // Initialize SSL
- {
- using namespace Poco;
- using namespace Poco::Net;
- using Poco::Net::SSLManager;
- using Poco::Net::Context;
- using Poco::Net::AcceptCertificateHandler;
- using Poco::Net::PrivateKeyPassphraseHandler;
- using Poco::Net::InvalidCertificateHandler;
- using Poco::Net::ConsoleCertificateHandler;
-
- //SharedPtr<PrivateKeyPassphraseHandler> pConsoleHandler = new PrivateKeyPassphraseHandler;
- SharedPtr<InvalidCertificateHandler> pInvalidCertHandler = new AcceptCertificateHandler(false);
- Context::Ptr pContext = new Poco::Net::Context(
- Context::CLIENT_USE, "", "", "", Context::VERIFY_NONE, // VERIFY_NONE...?!
- 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
- SSLManager::instance().initializeClient(NULL, pInvalidCertHandler, pContext);
- }
- // First Startup? Save UUID
- SetupStore("UUID", Config::GetInstance().GetUUID().c_str());
-
- plexclient::plexgdm::GetInstance().clientDetails(Config::GetInstance().GetUUID(), Config::GetInstance().GetHostname(), "3200", DESCRIPTION, VERSION);
- plexclient::plexgdm::GetInstance().Start();
- plexclient::ControlServer::GetInstance().Start();
-
- return true;
+bool cMyPlugin::Initialize(void) {
+ // Initialize SSL
+ {
+ using namespace Poco;
+ using namespace Poco::Net;
+ using Poco::Net::SSLManager;
+ using Poco::Net::Context;
+ using Poco::Net::AcceptCertificateHandler;
+ using Poco::Net::PrivateKeyPassphraseHandler;
+ using Poco::Net::InvalidCertificateHandler;
+ using Poco::Net::ConsoleCertificateHandler;
+
+ //SharedPtr<PrivateKeyPassphraseHandler> pConsoleHandler = new PrivateKeyPassphraseHandler;
+ SharedPtr<InvalidCertificateHandler> pInvalidCertHandler = new AcceptCertificateHandler(false);
+ Context::Ptr pContext = new Poco::Net::Context(
+ Context::CLIENT_USE, "", "", "", Context::VERIFY_NONE, // VERIFY_NONE...?!
+ 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
+ SSLManager::instance().initializeClient(NULL, pInvalidCertHandler, pContext);
+ }
+ // First Startup? Save UUID
+ SetupStore("UUID", Config::GetInstance().GetUUID().c_str());
+
+ plexclient::plexgdm::GetInstance().clientDetails(Config::GetInstance().GetUUID(),
+ Config::GetInstance().GetHostname(), "3200", DESCRIPTION, VERSION);
+ plexclient::plexgdm::GetInstance().Start();
+ plexclient::ControlServer::GetInstance().Start();
+
+ return true;
}
/**
** Create main menu entry.
*/
-const char *cMyPlugin::MainMenuEntry(void)
-{
- return Config::GetInstance().HideMainMenuEntry ? NULL : MAINMENUENTRY;
+const char *cMyPlugin::MainMenuEntry(void) {
+ return Config::GetInstance().HideMainMenuEntry ? NULL : MAINMENUENTRY;
}
/**
** Perform the action when selected from the main VDR menu.
*/
-cOsdObject *cMyPlugin::MainMenuAction(void)
-{
- //dsyslog("[plex]%s:\n", __FUNCTION__);
+cOsdObject *cMyPlugin::MainMenuAction(void) {
+ //dsyslog("[plex]%s:\n", __FUNCTION__);
#ifdef SKINDESIGNER
- if(bSkindesigner && m_pTestOsd->SdSupport()) return new cPlexSdOsd(m_pPlugStruct);
- else return cPlexMenu::ProcessMenu();
+ if (bSkindesigner && m_pTestOsd->SdSupport()) return new cPlexSdOsd(m_pPlugStruct);
+ else return cPlexMenu::ProcessMenu();
#else
- return cPlexMenu::ProcessMenu();
+ return cPlexMenu::ProcessMenu();
#endif
}
@@ -212,23 +214,21 @@ cOsdObject *cMyPlugin::MainMenuAction(void)
** Called for every plugin once during every cycle of VDR's main program
** loop.
*/
-void cMyPlugin::MainThreadHook(void)
-{
- // dsyslog("[plex]%s:\n", __FUNCTION__);
- // Start Tasks, e.g. Play Video
- if(plexclient::ActionManager::GetInstance().IsAction()) {
- PlayFile(plexclient::ActionManager::GetInstance().GetAction());
- }
+void cMyPlugin::MainThreadHook(void) {
+ // dsyslog("[plex]%s:\n", __FUNCTION__);
+ // Start Tasks, e.g. Play Video
+ if (plexclient::ActionManager::GetInstance().IsAction()) {
+ PlayFile(plexclient::ActionManager::GetInstance().GetAction());
+ }
}
/**
** Return our setup menu.
*/
-cMenuSetupPage *cMyPlugin::SetupMenu(void)
-{
- //dsyslog("[plex]%s:\n", __FUNCTION__);
+cMenuSetupPage *cMyPlugin::SetupMenu(void) {
+ //dsyslog("[plex]%s:\n", __FUNCTION__);
- return new cMyMenuSetupPage;
+ return new cMyMenuSetupPage;
}
/**
@@ -239,11 +239,10 @@ cMenuSetupPage *cMyPlugin::SetupMenu(void)
**
** @returns true if the parameter is supported.
*/
-bool cMyPlugin::SetupParse(const char *name, const char *value)
-{
- //dsyslog("[plex]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
+bool cMyPlugin::SetupParse(const char *name, const char *value) {
+ //dsyslog("[plex]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
- return Config::GetInstance().Parse(name, value);
+ return Config::GetInstance().Parse(name, value);
}
/**
@@ -251,56 +250,55 @@ bool cMyPlugin::SetupParse(const char *name, const char *value)
**
** @param filename path and file name
*/
-void cMyPlugin::PlayFile(plexclient::cVideo Vid)
-{
- if(Vid.m_iMyPlayOffset == 0 && Vid.m_lViewoffset > 0 ) {
- cString message = cString::sprintf(tr("To start from %ld minutes, press Ok."), Vid.m_lViewoffset / 60000);
- eKeys response = Skins.Message(eMessageType::mtInfo, message, 5);
- if(response == kOk) {
- Vid.m_iMyPlayOffset = Vid.m_lViewoffset/1000;
- }
- }
-
- cPlugin* mpvPlugin = cPluginManager::GetPlugin("mpv");
-
- if(Config::GetInstance().UseMpv && mpvPlugin) {
- CurrentVideo = Vid;
- cMyPlugin::PlayingFile = true;
-
- Mpv_PlayFile req;
- Mpv_SetTitle reqTitle;
- std::string file;
- if(Config::GetInstance().UsePlexAccount && Vid.m_pServer->IsLocal() == false) {
- file = plexclient::Plexservice::GetUniversalTranscodeUrl(&Vid, Vid.m_iMyPlayOffset, NULL, true);
- }
- else {
- file = (Vid.m_pServer->GetUri() + Vid.m_Media.m_sPartKey);
- }
-
- req.Filename = (char*)file.c_str();
- mpvPlugin->Service(MPV_PLAY_FILE, &req);
-
- reqTitle.Title = (char*)Vid.GetTitle().c_str();
- mpvPlugin->Service(MPV_SET_TITLE, &reqTitle);
-
- // Set "StartAt" for mpv player
- Mpv_Seek seekData;
- seekData.SeekAbsolute = Vid.m_iMyPlayOffset;
- seekData.SeekRelative = 0;
- mpvPlugin->Service(MPV_SEEK, &seekData);
-
- return;
-
- } else if (Config::GetInstance().UseMpv) {
- isyslog("Can't find mpv %s, playing directly.", mpvPlugin ? "service" : "plugin");
- }
-
-
- isyslog("[plex]: play file '%s'\n", Vid.m_sKey.c_str());
- cControl* control = cHlsPlayerControl::Create(Vid);
- if(control) {
- cControl::Launch(control);
- }
+void cMyPlugin::PlayFile(plexclient::cVideo Vid) {
+ if (Vid.m_iMyPlayOffset == 0 && Vid.m_lViewoffset > 0) {
+ cString message = cString::sprintf(tr("To start from %ld minutes, press Ok."), Vid.m_lViewoffset / 60000);
+ eKeys response = Skins.Message(eMessageType::mtInfo, message, 5);
+ if (response == kOk) {
+ Vid.m_iMyPlayOffset = Vid.m_lViewoffset / 1000;
+ }
+ }
+
+ cPlugin *mpvPlugin = cPluginManager::GetPlugin("mpv");
+
+ if (Config::GetInstance().UseMpv && mpvPlugin) {
+ CurrentVideo = Vid;
+ cMyPlugin::PlayingFile = true;
+
+ Mpv_PlayFile req;
+ Mpv_SetTitle reqTitle;
+ std::string file;
+ if (Config::GetInstance().UsePlexAccount && Vid.m_pServer->IsLocal() == false) {
+ file = plexclient::Plexservice::GetUniversalTranscodeUrl(&Vid, Vid.m_iMyPlayOffset, NULL, true);
+ }
+ else {
+ file = (Vid.m_pServer->GetUri() + Vid.m_Media.m_sPartKey);
+ }
+
+ req.Filename = (char *) file.c_str();
+ mpvPlugin->Service(MPV_PLAY_FILE, &req);
+
+ reqTitle.Title = (char *) Vid.GetTitle().c_str();
+ mpvPlugin->Service(MPV_SET_TITLE, &reqTitle);
+
+ // Set "StartAt" for mpv player
+ Mpv_Seek seekData;
+ seekData.SeekAbsolute = Vid.m_iMyPlayOffset;
+ seekData.SeekRelative = 0;
+ mpvPlugin->Service(MPV_SEEK, &seekData);
+
+ return;
+
+ } else if (Config::GetInstance().UseMpv) {
+ isyslog("Can't find mpv %s, playing directly.", mpvPlugin ? "service" : "plugin");
+ }
+
+
+ isyslog("[plex]: play file '%s'\n", Vid.m_sKey.c_str());
+ cControl *control = cHlsPlayerControl::Create(Vid);
+ if (control) {
+ cControl::Launch(control);
+ }
}
-VDRPLUGINCREATOR(cMyPlugin); // Don't touch this!
+VDRPLUGINCREATOR(cMyPlugin); // Don't touch this!
diff --git a/plex.h b/plex.h
index 316871d..182c302 100644
--- a/plex.h
+++ b/plex.h
@@ -18,9 +18,11 @@
#include "hlsPlayerControl.h"
#ifdef SKINDESIGNER
- #include <libskindesignerapi/skindesignerapi.h>
- #include "plexSdOsd.h"
- #include "pictureCache.h"
+
+#include <libskindesignerapi/skindesignerapi.h>
+#include "plexSdOsd.h"
+#include "pictureCache.h"
+
#endif
#include <iostream>
@@ -35,41 +37,52 @@
/// for the distribution archive.
static const char *const VERSION = "0.3.0"
#ifdef GIT_REV
- "-GIT" GIT_REV
+"-GIT" GIT_REV
#endif
- ;
+;
static const char *const DESCRIPTION = "Plex for VDR Plugin";
static const char *const MAINMENUENTRY = "Plex for VDR";
-class cMyPlugin:public cPlugin
-{
+class cMyPlugin : public cPlugin {
private:
#ifdef SKINDESIGNER
- skindesignerapi::cPluginStructure *m_pPlugStruct;
- cPlexSdOsd *m_pTestOsd;
- static bool bSkindesigner;
+ skindesignerapi::cPluginStructure *m_pPlugStruct;
+ cPlexSdOsd *m_pTestOsd;
+ static bool bSkindesigner;
#endif
-
+
public:
- cMyPlugin(void);
- virtual ~ cMyPlugin(void);
- virtual const char *Version(void);
- virtual const char *Description(void);
- virtual bool Initialize(void);
- virtual bool Start(void);
- virtual void MainThreadHook(void);
- virtual const char *MainMenuEntry(void);
- virtual cOsdObject *MainMenuAction(void);
- virtual cMenuSetupPage *SetupMenu(void);
- virtual bool SetupParse(const char *, const char *);
-
- static plexclient::cVideo CurrentVideo;
- static bool PlayingFile;
- static void PlayFile(plexclient::cVideo Vid);
+ cMyPlugin(void);
+
+ virtual ~ cMyPlugin(void);
+
+ virtual const char *Version(void);
+
+ virtual const char *Description(void);
+
+ virtual bool Initialize(void);
+
+ virtual bool Start(void);
+
+ virtual void MainThreadHook(void);
+
+ virtual const char *MainMenuEntry(void);
+
+ virtual cOsdObject *MainMenuAction(void);
+
+ virtual cMenuSetupPage *SetupMenu(void);
+
+ virtual bool SetupParse(const char *, const char *);
+
+ static plexclient::cVideo CurrentVideo;
+ static bool PlayingFile;
+
+ static void PlayFile(plexclient::cVideo Vid);
public:
- static volatile bool CalledFromCode;
+ static volatile bool CalledFromCode;
};
+
#endif
diff --git a/plexOsd.cpp b/plexOsd.cpp
index 0d89041..13cb86e 100644
--- a/plexOsd.cpp
+++ b/plexOsd.cpp
@@ -9,158 +9,154 @@ static std::shared_ptr<plexclient::Plexservice> pPlexService;
std::shared_ptr<plexclient::Plexservice> cPlexBrowser::pLastService;
int cPlexBrowser::lastCurrentItem;
-cPlexBrowser::cPlexBrowser(const char *title, std::shared_ptr<plexclient::Plexservice> Service) :cOsdMenu(title)
-{
- dsyslog("[plex]%s:\n", __FUNCTION__);
- pService = Service;
- //pService->Authenticate();
- if(pService == pLastService) {
- pCont = pService->GetLastSection(true);
- } else {
- pCont = pService->GetSection(pService->StartUri);
- }
- SetMenuCategory(mcRecording);
- CreateMenu();
+cPlexBrowser::cPlexBrowser(const char *title, std::shared_ptr<plexclient::Plexservice> Service) : cOsdMenu(title) {
+ dsyslog("[plex]%s:\n", __FUNCTION__);
+ pService = Service;
+ //pService->Authenticate();
+ if (pService == pLastService) {
+ pCont = pService->GetLastSection(true);
+ } else {
+ pCont = pService->GetSection(pService->StartUri);
+ }
+ SetMenuCategory(mcRecording);
+ CreateMenu();
}
-cPlexBrowser* cPlexBrowser::RecoverLastState()
-{
- if (cPlexBrowser::pLastService != NULL) {
- cPlexBrowser* pBrowser = new cPlexBrowser("", cPlexBrowser::pLastService);
- return pBrowser;
- }
- return NULL;
+cPlexBrowser *cPlexBrowser::RecoverLastState() {
+ if (cPlexBrowser::pLastService != NULL) {
+ cPlexBrowser *pBrowser = new cPlexBrowser("", cPlexBrowser::pLastService);
+ return pBrowser;
+ }
+ return NULL;
}
-void cPlexBrowser::CreateMenu()
-{
- // Clear Menu
- Clear();
- // Directory or Video?
- if(pCont && pCont->m_vDirectories.size() > 0) {
-
- for(std::vector<plexclient::Directory>::iterator it = pCont->m_vDirectories.begin(); it != pCont->m_vDirectories.end(); ++it) {
- plexclient::Directory *pDir = &(*it);
- Add(new cPlexOsdItem( tr(pDir->GetTitle().c_str()), pDir) );
- }
- }
-
- if(pCont && pCont->m_vVideos.size() > 0) {
- for(std::vector<plexclient::cVideo>::iterator it = pCont->m_vVideos.begin(); it != pCont->m_vVideos.end(); ++it) {
- plexclient::cVideo *vid = &(*it); // cast raw pointer
- Add(new cPlexOsdItem( vid->GetTitle().c_str(), vid) );
- }
- }
-
- if(Count() < 1) {
- Add(new cPlexOsdItem("Empty"));
- } else if (pService == pLastService) {
- // recover last selected item
- cOsdItem* item = Get(lastCurrentItem);
- SetCurrent(item);
- pLastService = NULL;
- }
-
- Display();
+void cPlexBrowser::CreateMenu() {
+ // Clear Menu
+ Clear();
+ // Directory or Video?
+ if (pCont && pCont->m_vDirectories.size() > 0) {
+
+ for (std::vector<plexclient::Directory>::iterator it = pCont->m_vDirectories.begin();
+ it != pCont->m_vDirectories.end(); ++it) {
+ plexclient::Directory *pDir = &(*it);
+ Add(new cPlexOsdItem(tr(pDir->GetTitle().c_str()), pDir));
+ }
+ }
+
+ if (pCont && pCont->m_vVideos.size() > 0) {
+ for (std::vector<plexclient::cVideo>::iterator it = pCont->m_vVideos.begin();
+ it != pCont->m_vVideos.end(); ++it) {
+ plexclient::cVideo *vid = &(*it); // cast raw pointer
+ Add(new cPlexOsdItem(vid->GetTitle().c_str(), vid));
+ }
+ }
+
+ if (Count() < 1) {
+ Add(new cPlexOsdItem("Empty"));
+ } else if (pService == pLastService) {
+ // recover last selected item
+ cOsdItem *item = Get(lastCurrentItem);
+ SetCurrent(item);
+ pLastService = NULL;
+ }
+
+ Display();
}
-eOSState cPlexBrowser::ProcessKey(eKeys key)
-{
- eOSState state;
-
- // call standard function
- state = cOsdMenu::ProcessKey(key);
-
- int current = Current(); // get current menu item index
- cPlexOsdItem *item = static_cast<cPlexOsdItem*>(Get(current));
-
- if(item->IsVideo()) {
- if(item->GetAttachedVideo()->m_iViewCount > 0) SetHelp(tr("Info"), tr("Unscrobble"));
- else SetHelp(tr("Info"), tr("Scrobble"));
- } else {
- SetHelp(NULL);
- }
-
- switch (state) {
- case osUnknown:
- switch (key) {
- case kOk:
- return ProcessSelected();
- case kBack:
- return LevelUp();
- case kRed:
- if(item->IsVideo()) {
- std::cout << " Video Info";
- }
- std::cout << std::endl;
- break;
- case kGreen:
- if(item->IsVideo()) {
- if(item->GetAttachedVideo()->m_iViewCount > 0) {
- if(item->GetAttachedVideo()->SetUnwatched()) {
- item->GetAttachedVideo()->UpdateFromServer();
- }
- } else {
- if(item->GetAttachedVideo()->SetWatched()) {
- item->GetAttachedVideo()->UpdateFromServer();
- }
- }
- }
- if(item->GetAttachedVideo()->m_iViewCount > 0) SetHelp(tr("Info"), tr("Unscrobble"));
- else SetHelp(tr("Info"), tr("Scrobble"));
- break;
- default:
- break;
- }
- break;
- case osBack:
- state = LevelUp();
- if (state == osEnd) { // top level reached
- return osPlugin;
- }
- default:
- break;
- }
- return state;
+eOSState cPlexBrowser::ProcessKey(eKeys key) {
+ eOSState state;
+
+ // call standard function
+ state = cOsdMenu::ProcessKey(key);
+
+ int current = Current(); // get current menu item index
+ cPlexOsdItem *item = static_cast<cPlexOsdItem *>(Get(current));
+
+ if (item->IsVideo()) {
+ if (item->GetAttachedVideo()->m_iViewCount > 0) SetHelp(tr("Info"), tr("Unscrobble"));
+ else SetHelp(tr("Info"), tr("Scrobble"));
+ } else {
+ SetHelp(NULL);
+ }
+
+ switch (state) {
+ case osUnknown:
+ switch (key) {
+ case kOk:
+ return ProcessSelected();
+ case kBack:
+ return LevelUp();
+ case kRed:
+ if (item->IsVideo()) {
+ std::cout << " Video Info";
+ }
+ std::cout << std::endl;
+ break;
+ case kGreen:
+ if (item->IsVideo()) {
+ if (item->GetAttachedVideo()->m_iViewCount > 0) {
+ if (item->GetAttachedVideo()->SetUnwatched()) {
+ item->GetAttachedVideo()->UpdateFromServer();
+ }
+ } else {
+ if (item->GetAttachedVideo()->SetWatched()) {
+ item->GetAttachedVideo()->UpdateFromServer();
+ }
+ }
+ }
+ if (item->GetAttachedVideo()->m_iViewCount > 0) SetHelp(tr("Info"), tr("Unscrobble"));
+ else SetHelp(tr("Info"), tr("Scrobble"));
+ break;
+ default:
+ break;
+ }
+ break;
+ case osBack:
+ state = LevelUp();
+ if (state == osEnd) { // top level reached
+ return osPlugin;
+ }
+ default:
+ break;
+ }
+ return state;
}
-eOSState cPlexBrowser::LevelUp()
-{
- pCont = pService->GetLastSection();
- if(!pCont) {
- cPlexMenu::eShow = menuShow::MAIN;
- return osEnd;
- }
- cString title = cString::sprintf(tr("Browse Plex - %s"), tr(pCont->m_sTitle1.c_str()));
- SetTitle(title);
- CreateMenu();
- return osContinue;
+eOSState cPlexBrowser::LevelUp() {
+ pCont = pService->GetLastSection();
+ if (!pCont) {
+ cPlexMenu::eShow = menuShow::MAIN;
+ return osEnd;
+ }
+ cString title = cString::sprintf(tr("Browse Plex - %s"), tr(pCont->m_sTitle1.c_str()));
+ SetTitle(title);
+ CreateMenu();
+ return osContinue;
}
-eOSState cPlexBrowser::ProcessSelected()
-{
- int current = Current(); // get current menu item index
- cPlexOsdItem *item = static_cast<cPlexOsdItem*>(Get(current));
-
-
- if(item->IsVideo()) {
- pLastService = pService;
- lastCurrentItem = current;
- cMyPlugin::PlayFile(*item->GetAttachedVideo());
- return osEnd;
- }
-
- if(item->IsDir()) {
- plexclient::Directory* pDir = item->GetAttachedDirectory();
- pCont = pService->GetSection(pDir->m_sKey);
- cString title = cString::sprintf(tr("Browse Plex - %s"), tr(pDir->m_sTitle.c_str()));
- SetTitle(title);
- CreateMenu();
- return osContinue;
- }
-
- //return osEnd;
- return osContinue;
+eOSState cPlexBrowser::ProcessSelected() {
+ int current = Current(); // get current menu item index
+ cPlexOsdItem *item = static_cast<cPlexOsdItem *>(Get(current));
+
+
+ if (item->IsVideo()) {
+ pLastService = pService;
+ lastCurrentItem = current;
+ cMyPlugin::PlayFile(*item->GetAttachedVideo());
+ return osEnd;
+ }
+
+ if (item->IsDir()) {
+ plexclient::Directory *pDir = item->GetAttachedDirectory();
+ pCont = pService->GetSection(pDir->m_sKey);
+ cString title = cString::sprintf(tr("Browse Plex - %s"), tr(pDir->m_sTitle.c_str()));
+ SetTitle(title);
+ CreateMenu();
+ return osContinue;
+ }
+
+ //return osEnd;
+ return osContinue;
}
@@ -174,40 +170,41 @@ menuShow cPlexMenu::eShow = MAIN;
** Plex menu constructor.
*/
cPlexMenu::cPlexMenu(const char *title, int c0, int c1, int c2, int c3, int c4)
- :cOsdMenu(title)
-{
- SetHasHotkeys();
-
- for(std::vector<plexclient::PlexServer>::iterator it = plexclient::plexgdm::GetInstance().GetPlexservers().begin(); it != plexclient::plexgdm::GetInstance().GetPlexservers().end(); ++it) {
- for(std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_serverViewentries.begin(); vEntry != Config::GetInstance().m_serverViewentries.end(); ++vEntry) {
- auto plexService = std::make_shared<plexclient::Plexservice>( &(*it) );
- plexService->StartUri = vEntry->PlexPath;
- Add(new cPlexOsdItem(Poco::format("%s - %s", it->GetServerName(), vEntry->Name ).c_str(), plexService ));
- }
- for(std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_viewentries.begin(); vEntry != Config::GetInstance().m_viewentries.end(); ++vEntry) {
- auto plexService = std::make_shared<plexclient::Plexservice>( &(*it) );
- plexService->StartUri = vEntry->PlexPath;
- Add(new cPlexOsdItem(Poco::format("%s - %s", it->GetServerName(), vEntry->Name ).c_str(), plexService ));
- }
- }
-
-
- if(Count() < 1) {
- Add(new cPlexOsdItem(tr("No Plex Media Server found.")), false);
- }
+ : cOsdMenu(title) {
+ SetHasHotkeys();
+
+ for (std::vector<plexclient::PlexServer>::iterator it = plexclient::plexgdm::GetInstance().GetPlexservers().begin();
+ it != plexclient::plexgdm::GetInstance().GetPlexservers().end(); ++it) {
+ for (std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_serverViewentries.begin();
+ vEntry != Config::GetInstance().m_serverViewentries.end(); ++vEntry) {
+ auto plexService = std::make_shared<plexclient::Plexservice>(&(*it));
+ plexService->StartUri = vEntry->PlexPath;
+ Add(new cPlexOsdItem(Poco::format("%s - %s", it->GetServerName(), vEntry->Name).c_str(), plexService));
+ }
+ for (std::vector<ViewEntry>::iterator vEntry = Config::GetInstance().m_viewentries.begin();
+ vEntry != Config::GetInstance().m_viewentries.end(); ++vEntry) {
+ auto plexService = std::make_shared<plexclient::Plexservice>(&(*it));
+ plexService->StartUri = vEntry->PlexPath;
+ Add(new cPlexOsdItem(Poco::format("%s - %s", it->GetServerName(), vEntry->Name).c_str(), plexService));
+ }
+ }
+
+
+ if (Count() < 1) {
+ Add(new cPlexOsdItem(tr("No Plex Media Server found.")), false);
+ }
}
-cOsdMenu* cPlexMenu::ProcessMenu()
-{
- if(cMyPlugin::CalledFromCode) {
- cMyPlugin::CalledFromCode = false;
- return cPlexBrowser::RecoverLastState();
- }
-
- if (cPlexMenu::eShow == menuShow::BROWSER) {
- return new cPlexBrowser(tr("Browse Plex"), pPlexService);
- }
- return new cPlexMenu("Plex");
+cOsdMenu *cPlexMenu::ProcessMenu() {
+ if (cMyPlugin::CalledFromCode) {
+ cMyPlugin::CalledFromCode = false;
+ return cPlexBrowser::RecoverLastState();
+ }
+
+ if (cPlexMenu::eShow == menuShow::BROWSER) {
+ return new cPlexBrowser(tr("Browse Plex"), pPlexService);
+ }
+ return new cPlexMenu("Plex");
}
@@ -216,33 +213,32 @@ cOsdMenu* cPlexMenu::ProcessMenu()
**
** @param key key event
*/
-eOSState cPlexMenu::ProcessKey(eKeys key)
-{
- eOSState state;
-
- //if (key != kNone) {
- // dsyslog("[plex]%s: key=%d\n", __FUNCTION__, key);
- //}
- // call standard function
- state = cOsdMenu::ProcessKey(key);
-
- int current = Current(); // get current menu item index
- cPlexOsdItem *item = static_cast<cPlexOsdItem*>(Get(current));
-
- switch (state) {
- case osUnknown:
- switch (key) {
- case kOk:
- pPlexService = item->GetAttachedService();
- cPlexMenu::eShow = menuShow::BROWSER;
- return osPlugin; // restart with OSD browser
- default:
- break;
- }
- default:
- break;
- }
- return state;
+eOSState cPlexMenu::ProcessKey(eKeys key) {
+ eOSState state;
+
+ //if (key != kNone) {
+ // dsyslog("[plex]%s: key=%d\n", __FUNCTION__, key);
+ //}
+ // call standard function
+ state = cOsdMenu::ProcessKey(key);
+
+ int current = Current(); // get current menu item index
+ cPlexOsdItem *item = static_cast<cPlexOsdItem *>(Get(current));
+
+ switch (state) {
+ case osUnknown:
+ switch (key) {
+ case kOk:
+ pPlexService = item->GetAttachedService();
+ cPlexMenu::eShow = menuShow::BROWSER;
+ return osPlugin; // restart with OSD browser
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ return state;
}
diff --git a/plexOsd.h b/plexOsd.h
index df0fcff..2b1f0b0 100644
--- a/plexOsd.h
+++ b/plexOsd.h
@@ -26,31 +26,34 @@ enum menuShow {
* Plex Browser
*/
-class cPlexBrowser :public cOsdMenu
-{
+class cPlexBrowser : public cOsdMenu {
private:
- std::shared_ptr<plexclient::Plexservice> pService;
- std::shared_ptr<plexclient::MediaContainer> pCont;
- std::vector<plexclient::cVideo> *v_Vid;
- std::vector<plexclient::Directory> *v_Dir;
- std::vector<std::string> m_vStack;
- std::string m_sSection;
- std::string m_sActualPos;
- /// Create a browser menu for current directory
- void CreateMenu();
- /// Handle menu level up
- eOSState LevelUp(void);
- /// Handle menu item selection
- eOSState ProcessSelected();
-
- static std::shared_ptr<plexclient::Plexservice> pLastService;
- static int lastCurrentItem;
+ std::shared_ptr<plexclient::Plexservice> pService;
+ std::shared_ptr<plexclient::MediaContainer> pCont;
+ std::vector<plexclient::cVideo> *v_Vid;
+ std::vector<plexclient::Directory> *v_Dir;
+ std::vector<std::string> m_vStack;
+ std::string m_sSection;
+ std::string m_sActualPos;
+
+ /// Create a browser menu for current directory
+ void CreateMenu();
+
+ /// Handle menu level up
+ eOSState LevelUp(void);
+
+ /// Handle menu item selection
+ eOSState ProcessSelected();
+
+ static std::shared_ptr<plexclient::Plexservice> pLastService;
+ static int lastCurrentItem;
public:
- cPlexBrowser(const char *title, std::shared_ptr<plexclient::Plexservice> Service);
- virtual eOSState ProcessKey(eKeys);
+ cPlexBrowser(const char *title, std::shared_ptr<plexclient::Plexservice> Service);
- static cPlexBrowser* RecoverLastState();
+ virtual eOSState ProcessKey(eKeys);
+
+ static cPlexBrowser *RecoverLastState();
};
@@ -58,14 +61,15 @@ public:
/**
** Play plugin menu class.
*/
-class cPlexMenu:public cOsdMenu
-{
+class cPlexMenu : public cOsdMenu {
public:
- cPlexMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0);
- virtual eOSState ProcessKey(eKeys);
-
- static cOsdMenu* ProcessMenu();
- static menuShow eShow;
+ cPlexMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0);
+
+ virtual eOSState ProcessKey(eKeys);
+
+ static cOsdMenu *ProcessMenu();
+
+ static menuShow eShow;
};
#endif // CPLEXOSD_H
diff --git a/plexSdOsd.cpp b/plexSdOsd.cpp
index ac699f2..f7f1228 100644
--- a/plexSdOsd.cpp
+++ b/plexSdOsd.cpp
@@ -7,413 +7,401 @@
cMutex cPlexSdOsd::RedrawMutex;
-cPlexSdOsd::cPlexSdOsd(skindesignerapi::cPluginStructure *plugStruct) : cSkindesignerOsdObject(plugStruct)
-{
- m_pRootView = NULL;
+cPlexSdOsd::cPlexSdOsd(skindesignerapi::cPluginStructure *plugStruct) : cSkindesignerOsdObject(plugStruct) {
+ m_pRootView = NULL;
}
-cPlexSdOsd::~cPlexSdOsd()
-{
- if(m_pRootView)
- m_pRootView->Deactivate(true);
- if(m_pBrowserGrid)
- m_pBrowserGrid->Clear();
- if(m_pMessage)
- m_pMessage->Clear();
+cPlexSdOsd::~cPlexSdOsd() {
+ if (m_pRootView)
+ m_pRootView->Deactivate(true);
+ if (m_pBrowserGrid)
+ m_pBrowserGrid->Clear();
+ if (m_pMessage)
+ m_pMessage->Clear();
}
-bool cPlexSdOsd::SdSupport()
-{
- if (SkindesignerAvailable()) {
- skindesignerapi::cOsdView *rootView = GetOsdView();
- if (!rootView) {
- esyslog("[plex]: used skindesigner skin does not support plex");
- return false;
- }
- }
- return true;
+bool cPlexSdOsd::SdSupport() {
+ if (SkindesignerAvailable()) {
+ skindesignerapi::cOsdView *rootView = GetOsdView();
+ if (!rootView) {
+ esyslog("[plex]: used skindesigner skin does not support plex");
+ return false;
+ }
+ }
+ return true;
}
-void cPlexSdOsd::Show(void)
-{
- if (!SkindesignerAvailable()) {
- return;
- }
-
- m_pRootView = std::shared_ptr<skindesignerapi::cOsdView>(GetOsdView((int)eViews::rootView));
- if (!m_pRootView) {
- esyslog("[plex]: used skindesigner skin does not support plex");
- return;
- }
-
- m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(new cBrowserGrid(m_pRootView));
- m_pMessage = std::shared_ptr<skindesignerapi::cViewElement>(m_pRootView->GetViewElement((int)eViewElementsRoot::message));
- m_messageDisplayed = false;
- m_detailsActive = false;
- Flush();
+void cPlexSdOsd::Show(void) {
+ if (!SkindesignerAvailable()) {
+ return;
+ }
+
+ m_pRootView = std::shared_ptr<skindesignerapi::cOsdView>(GetOsdView((int) eViews::rootView));
+ if (!m_pRootView) {
+ esyslog("[plex]: used skindesigner skin does not support plex");
+ return;
+ }
+
+ m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(new cBrowserGrid(m_pRootView));
+ m_pMessage = std::shared_ptr<skindesignerapi::cViewElement>(
+ m_pRootView->GetViewElement((int) eViewElementsRoot::message));
+ m_messageDisplayed = false;
+ m_detailsActive = false;
+ Flush();
}
-void cPlexSdOsd::Flush()
-{
- if(m_detailsActive) {
- m_pDetailGrid->Draw();
- m_pDetailGrid->Flush();
- }
- else {
- m_pBrowserGrid->DrawGrid();
- m_pBrowserGrid->Flush();
- }
+void cPlexSdOsd::Flush() {
+ if (m_detailsActive) {
+ m_pDetailGrid->Draw();
+ m_pDetailGrid->Flush();
+ }
+ else {
+ m_pBrowserGrid->DrawGrid();
+ m_pBrowserGrid->Flush();
+ }
}
-eOSState cPlexSdOsd::ProcessKey(eKeys Key)
-{
- eOSState state = eOSState::osContinue;
-
- if(m_detailsActive) {
- state = ProcessKeyDetailView(Key);
- } else {
- //check if some plexservers are online
- if(plexclient::plexgdm::GetInstance().GetFirstServer() == NULL ||
- (plexclient::plexgdm::GetInstance().GetFirstServer() && plexclient::plexgdm::GetInstance().GetFirstServer()->Offline)
- ) {
- DrawMessage(std::string(tr("No Plex Media Server found.")));
- switch (Key & ~k_Repeat) {
- case kOk:
- case kBack:
- return eOSState::osEnd;
- default:
- return eOSState::osContinue;
- }
- }
- state = ProcessKeyBrowserView(Key);
- }
-
- return state;
+eOSState cPlexSdOsd::ProcessKey(eKeys Key) {
+ eOSState state = eOSState::osContinue;
+
+ if (m_detailsActive) {
+ state = ProcessKeyDetailView(Key);
+ } else {
+ //check if some plexservers are online
+ if (plexclient::plexgdm::GetInstance().GetFirstServer() == NULL ||
+ (plexclient::plexgdm::GetInstance().GetFirstServer() &&
+ plexclient::plexgdm::GetInstance().GetFirstServer()->Offline)
+ ) {
+ DrawMessage(std::string(tr("No Plex Media Server found.")));
+ switch (Key & ~k_Repeat) {
+ case kOk:
+ case kBack:
+ return eOSState::osEnd;
+ default:
+ return eOSState::osContinue;
+ }
+ }
+ state = ProcessKeyBrowserView(Key);
+ }
+
+ return state;
}
-eOSState cPlexSdOsd::ProcessKeyDetailView(eKeys Key)
-{
- eOSState state = eOSState::osContinue;
- plexclient::cVideo* vid = NULL;
-
- switch (Key & ~k_Repeat) {
- case kUp:
- if(m_pDetailGrid->NavigateUp()) Flush();
- break;
- case kDown:
- if(m_pDetailGrid->NavigateDown()) Flush();
- break;
- case kLeft:
- if(m_pDetailGrid->NavigateLeft()) Flush();
- break;
- case kRight:
- if(m_pDetailGrid->NavigateRight()) Flush();
- break;
- case kOk:
- state = m_pDetailGrid->NavigateSelect();
- vid = dynamic_cast<plexclient::cVideo*>(m_pDetailGrid->SelectedObject());
- Flush();
- break;
- case kBack:
- state = eOSState::osContinue;
- m_pDetailGrid->Clear();
- m_pDetailGrid->Deactivate(true);
- m_pDetailGrid = nullptr;
- m_pDetailsView = nullptr;
- m_detailsActive = false;
- m_pBrowserGrid->Activate();
- Flush();
- break;
- case kYellow:
- if(m_pDetailGrid->GetVideo()) {
- if(m_pDetailGrid->GetVideo()->m_iViewCount > 0) m_pDetailGrid->GetVideo()->SetUnwatched();
- else m_pDetailGrid->GetVideo()->SetWatched();
- m_pDetailGrid->GetVideo()->UpdateFromServer();
- Flush();
- }
- break;
- case kGreen:
- vid = m_pDetailGrid->GetVideo();
- state = eOSState::osUser1;
- break;
- case kRed:
- vid = m_pDetailGrid->GetVideo();
- vid->m_iMyPlayOffset = vid->m_lViewoffset/1000;
- state = eOSState::osUser1;
- break;
- case kBlue:
- default:
- break;
- }
-
- if(state == eOSState::osUser1 && vid) {
- cMyPlugin::PlayFile(*vid);
- state = eOSState::osEnd;
- }
-
- if (state != osEnd && m_pDetailGrid && m_pDetailGrid->DrawTime()) m_pDetailGrid->Flush();
-
- return state;
+eOSState cPlexSdOsd::ProcessKeyDetailView(eKeys Key) {
+ eOSState state = eOSState::osContinue;
+ plexclient::cVideo *vid = NULL;
+
+ switch (Key & ~k_Repeat) {
+ case kUp:
+ if (m_pDetailGrid->NavigateUp()) Flush();
+ break;
+ case kDown:
+ if (m_pDetailGrid->NavigateDown()) Flush();
+ break;
+ case kLeft:
+ if (m_pDetailGrid->NavigateLeft()) Flush();
+ break;
+ case kRight:
+ if (m_pDetailGrid->NavigateRight()) Flush();
+ break;
+ case kOk:
+ state = m_pDetailGrid->NavigateSelect();
+ vid = dynamic_cast<plexclient::cVideo *>(m_pDetailGrid->SelectedObject());
+ Flush();
+ break;
+ case kBack:
+ state = eOSState::osContinue;
+ m_pDetailGrid->Clear();
+ m_pDetailGrid->Deactivate(true);
+ m_pDetailGrid = nullptr;
+ m_pDetailsView = nullptr;
+ m_detailsActive = false;
+ m_pBrowserGrid->Activate();
+ Flush();
+ break;
+ case kYellow:
+ if (m_pDetailGrid->GetVideo()) {
+ if (m_pDetailGrid->GetVideo()->m_iViewCount > 0) m_pDetailGrid->GetVideo()->SetUnwatched();
+ else m_pDetailGrid->GetVideo()->SetWatched();
+ m_pDetailGrid->GetVideo()->UpdateFromServer();
+ Flush();
+ }
+ break;
+ case kGreen:
+ vid = m_pDetailGrid->GetVideo();
+ state = eOSState::osUser1;
+ break;
+ case kRed:
+ vid = m_pDetailGrid->GetVideo();
+ vid->m_iMyPlayOffset = vid->m_lViewoffset / 1000;
+ state = eOSState::osUser1;
+ break;
+ case kBlue:
+ default:
+ break;
+ }
+
+ if (state == eOSState::osUser1 && vid) {
+ cMyPlugin::PlayFile(*vid);
+ state = eOSState::osEnd;
+ }
+
+ if (state != osEnd && m_pDetailGrid && m_pDetailGrid->DrawTime()) m_pDetailGrid->Flush();
+
+ return state;
}
-eOSState cPlexSdOsd::ProcessKeyBrowserView(eKeys Key)
-{
- eOSState state = eOSState::osContinue;
- plexclient::cVideo* vid = NULL;
-
- switch (Key & ~k_Repeat) {
- case kUp:
- if(m_pBrowserGrid->NavigateUp()) Flush();
- break;
- case kDown:
- if(m_pBrowserGrid->NavigateDown()) Flush();
- break;
- case kLeft:
- if(m_pBrowserGrid->NavigateLeft()) Flush();
- break;
- case kRight:
- if(m_pBrowserGrid->NavigateRight()) Flush();
- break;
- case kOk:
- // Play movie or change dir
- state = m_pBrowserGrid->NavigateSelect();
- if(state == eOSState::osUser1) {
- vid = dynamic_cast<plexclient::cVideo*>(m_pBrowserGrid->SelectedObject());
- vid->m_iMyPlayOffset = vid->m_lViewoffset/1000;
- }
- Flush();
- break;
- case kBack:
- state = m_pBrowserGrid->NavigateBack();
- Flush();
- break;
- case kBlue:
- m_pBrowserGrid->NextViewMode();
- Flush();
- break;
- case kRed:
- vid = dynamic_cast<plexclient::cVideo*>(m_pBrowserGrid->SelectedObject());
- if(vid) {
- if(vid->m_iViewCount > 0) vid->SetUnwatched();
- else vid->SetWatched();
- vid->UpdateFromServer();
- Flush();
- }
- break;
- case kGreen: // Show Details OSD
- vid = dynamic_cast<plexclient::cVideo*>(m_pBrowserGrid->SelectedObject());
- if(vid) {
- vid->UpdateFromServer();
- ShowDetails(vid);
- }
- break;
- case kYellow:
- m_pBrowserGrid->NextTab();
- Flush();
- break;
- default:
- break;
- }
-
- if(state == eOSState::osUser1 && vid) {
- cMyPlugin::PlayFile(*vid);
- state = eOSState::osEnd;
- }
-
- if (state != osEnd && m_pBrowserGrid->DrawTime()) m_pBrowserGrid->Flush();
-
- return state;
+eOSState cPlexSdOsd::ProcessKeyBrowserView(eKeys Key) {
+ eOSState state = eOSState::osContinue;
+ plexclient::cVideo *vid = NULL;
+
+ switch (Key & ~k_Repeat) {
+ case kUp:
+ if (m_pBrowserGrid->NavigateUp()) Flush();
+ break;
+ case kDown:
+ if (m_pBrowserGrid->NavigateDown()) Flush();
+ break;
+ case kLeft:
+ if (m_pBrowserGrid->NavigateLeft()) Flush();
+ break;
+ case kRight:
+ if (m_pBrowserGrid->NavigateRight()) Flush();
+ break;
+ case kOk:
+ // Play movie or change dir
+ state = m_pBrowserGrid->NavigateSelect();
+ if (state == eOSState::osUser1) {
+ vid = dynamic_cast<plexclient::cVideo *>(m_pBrowserGrid->SelectedObject());
+ vid->m_iMyPlayOffset = vid->m_lViewoffset / 1000;
+ }
+ Flush();
+ break;
+ case kBack:
+ state = m_pBrowserGrid->NavigateBack();
+ Flush();
+ break;
+ case kBlue:
+ m_pBrowserGrid->NextViewMode();
+ Flush();
+ break;
+ case kRed:
+ vid = dynamic_cast<plexclient::cVideo *>(m_pBrowserGrid->SelectedObject());
+ if (vid) {
+ if (vid->m_iViewCount > 0) vid->SetUnwatched();
+ else vid->SetWatched();
+ vid->UpdateFromServer();
+ Flush();
+ }
+ break;
+ case kGreen: // Show Details OSD
+ vid = dynamic_cast<plexclient::cVideo *>(m_pBrowserGrid->SelectedObject());
+ if (vid) {
+ vid->UpdateFromServer();
+ ShowDetails(vid);
+ }
+ break;
+ case kYellow:
+ m_pBrowserGrid->NextTab();
+ Flush();
+ break;
+ default:
+ break;
+ }
+
+ if (state == eOSState::osUser1 && vid) {
+ cMyPlugin::PlayFile(*vid);
+ state = eOSState::osEnd;
+ }
+
+ if (state != osEnd && m_pBrowserGrid->DrawTime()) m_pBrowserGrid->Flush();
+
+ return state;
}
-void cPlexSdOsd::ShowDetails(plexclient::cVideo *vid)
-{
- if(m_detailsActive) return;
-
- m_pBrowserGrid->Deactivate(true);
- m_pDetailsView = std::shared_ptr<skindesignerapi::cOsdView>(GetOsdView((int)eViews::detailView));
- m_pDetailGrid = std::shared_ptr<cDetailView>(new cDetailView(m_pDetailsView, vid));
-
- m_pDetailGrid->Activate();
- m_pDetailGrid->Draw();
- m_pDetailGrid->Flush();
- m_detailsActive = true;
+void cPlexSdOsd::ShowDetails(plexclient::cVideo *vid) {
+ if (m_detailsActive) return;
+
+ m_pBrowserGrid->Deactivate(true);
+ m_pDetailsView = std::shared_ptr<skindesignerapi::cOsdView>(GetOsdView((int) eViews::detailView));
+ m_pDetailGrid = std::shared_ptr<cDetailView>(new cDetailView(m_pDetailsView, vid));
+
+ m_pDetailGrid->Activate();
+ m_pDetailGrid->Draw();
+ m_pDetailGrid->Flush();
+ m_detailsActive = true;
}
-void cPlexSdOsd::DrawMessage(std::string message)
-{
- m_pMessage->ClearTokens();
- m_pMessage->AddStringToken((int)eTokenMessageStr::message, message.c_str());
- m_pMessage->AddIntToken((int)eTokenMessageInt::displaymessage, true);
- m_pMessage->Display();
- m_pRootView->Display();
+void cPlexSdOsd::DrawMessage(std::string message) {
+ m_pMessage->ClearTokens();
+ m_pMessage->AddStringToken((int) eTokenMessageStr::message, message.c_str());
+ m_pMessage->AddIntToken((int) eTokenMessageInt::displaymessage, true);
+ m_pMessage->Display();
+ m_pRootView->Display();
}
-void cPlexSdOsd::DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenContainer* tk)
-{
- switch(ve) {
- case eViewElementsRoot::background:
- tk->DefineIntToken("{viewmode}", (int)eTokenBackgroundInt::viewmode);
- tk->DefineIntToken("{isdirectory}", (int)eTokenBackgroundInt::isdirectory);
- tk->DefineStringToken("{selecteditembackground}", (int)eTokenBackgroundStr::selecteditembackground);
- tk->DefineStringToken("{currentdirectorybackground}", (int)eTokenBackgroundStr::currentdirectorybackground);
- break;
- case eViewElementsRoot::infopane:
- case eViewElementsRoot::header:
- DefineGridTokens(tk);
- tk->DefineStringToken("{tabname}", (int)eTokenGridStr::tabname);
- break;
- case eViewElementsRoot::footer:
- DefineFooterTokens(tk);
- break;
- case eViewElementsRoot::watch:
- DefineWatchTokens(tk);
- break;
- case eViewElementsRoot::message:
- tk->DefineIntToken("{displaymessage}", (int)eTokenMessageInt::displaymessage);
- tk->DefineStringToken("{message}", (int)eTokenMessageStr::message);
- break;
- case eViewElementsRoot::scrollbar:
- tk->DefineIntToken("{height}", (int)eTokenScrollbarInt::height);
- tk->DefineIntToken("{offset}", (int)eTokenScrollbarInt::offset);
- tk->DefineIntToken("{hasscrollbar}", (int)eTokenScrollbarInt::hasscrollbar);
- break;
- }
+void cPlexSdOsd::DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenContainer *tk) {
+ switch (ve) {
+ case eViewElementsRoot::background:
+ tk->DefineIntToken("{viewmode}", (int) eTokenBackgroundInt::viewmode);
+ tk->DefineIntToken("{isdirectory}", (int) eTokenBackgroundInt::isdirectory);
+ tk->DefineStringToken("{selecteditembackground}", (int) eTokenBackgroundStr::selecteditembackground);
+ tk->DefineStringToken("{currentdirectorybackground}",
+ (int) eTokenBackgroundStr::currentdirectorybackground);
+ break;
+ case eViewElementsRoot::infopane:
+ case eViewElementsRoot::header:
+ DefineGridTokens(tk);
+ tk->DefineStringToken("{tabname}", (int) eTokenGridStr::tabname);
+ break;
+ case eViewElementsRoot::footer:
+ DefineFooterTokens(tk);
+ break;
+ case eViewElementsRoot::watch:
+ DefineWatchTokens(tk);
+ break;
+ case eViewElementsRoot::message:
+ tk->DefineIntToken("{displaymessage}", (int) eTokenMessageInt::displaymessage);
+ tk->DefineStringToken("{message}", (int) eTokenMessageStr::message);
+ break;
+ case eViewElementsRoot::scrollbar:
+ tk->DefineIntToken("{height}", (int) eTokenScrollbarInt::height);
+ tk->DefineIntToken("{offset}", (int) eTokenScrollbarInt::offset);
+ tk->DefineIntToken("{hasscrollbar}", (int) eTokenScrollbarInt::hasscrollbar);
+ break;
+ }
}
-void cPlexSdOsd::DefineGridTokens(skindesignerapi::cTokenContainer* tk)
-{
- tk->DefineIntToken("{viewmode}", (int)eTokenGridInt::viewmode);
- tk->DefineIntToken("{viewgroup}", (int)eTokenGridInt::viewgroup);
- tk->DefineIntToken("{viewCount}", (int)eTokenGridInt::viewCount);
- tk->DefineIntToken("{viewoffset}", (int)eTokenGridInt::viewoffset);
- tk->DefineIntToken("{viewoffsetpercent}", (int)eTokenGridInt::viewoffsetpercent);
- tk->DefineIntToken("{duration}", (int)eTokenGridInt::duration);
- tk->DefineIntToken("{year}", (int)eTokenGridInt::year);
- tk->DefineIntToken("{hasthumb}", (int)eTokenGridInt::hasthumb);
- tk->DefineIntToken("{hasart}", (int)eTokenGridInt::hasart);
- tk->DefineIntToken("{ismovie}", (int)eTokenGridInt::ismovie);
- tk->DefineIntToken("{isepisode}", (int)eTokenGridInt::isepisode);
- tk->DefineIntToken("{isdirectory}", (int)eTokenGridInt::isdirectory);
- tk->DefineIntToken("{isshow}", (int)eTokenGridInt::isshow);
- tk->DefineIntToken("{isseason}", (int)eTokenGridInt::isseason);
- tk->DefineIntToken("{isclip}", (int)eTokenGridInt::isclip);
- tk->DefineIntToken("{originallyAvailableYear}", (int)eTokenGridInt::originallyAvailableYear);
- tk->DefineIntToken("{originallyAvailableMonth}", (int)eTokenGridInt::originallyAvailableMonth);
- tk->DefineIntToken("{originallyAvailableDay}", (int)eTokenGridInt::originallyAvailableDay);
- tk->DefineIntToken("{season}", (int)eTokenGridInt::season);
- tk->DefineIntToken("{episode}", (int)eTokenGridInt::episode);
- tk->DefineIntToken("{leafCount}", (int)eTokenGridInt::leafCount);
- tk->DefineIntToken("{viewedLeafCount}", (int)eTokenGridInt::viewedLeafCount);
- tk->DefineIntToken("{childCount}", (int)eTokenGridInt::childCount);
- tk->DefineIntToken("{rating}", (int)eTokenGridInt::rating);
- tk->DefineIntToken("{hasseriesthumb}", (int)eTokenGridInt::hasseriesthumb);
- tk->DefineIntToken("{hasbanner}", (int)eTokenGridInt::hasbanner);
- tk->DefineIntToken("{columns}", (int)eTokenGridInt::columns);
- tk->DefineIntToken("{rows}", (int)eTokenGridInt::rows);
- tk->DefineIntToken("{position}", (int)eTokenGridInt::position);
- tk->DefineIntToken("{totalcount}", (int)eTokenGridInt::totalcount);
- tk->DefineIntToken("{bitrate}", (int)eTokenGridInt::bitrate);
- tk->DefineIntToken("{width}", (int)eTokenGridInt::width);
- tk->DefineIntToken("{height}", (int)eTokenGridInt::height);
- tk->DefineIntToken("{audioChannels}", (int)eTokenGridInt::audioChannels);
- tk->DefineIntToken("{isdummy}", (int)eTokenGridInt::isdummy);
- tk->DefineIntToken("{isserver}", (int)eTokenGridInt::isserver);
- tk->DefineIntToken("{serverport}", (int)eTokenGridInt::serverport);
- tk->DefineIntToken("{extratype}", (int)eTokenGridInt::extratype);
-
- tk->DefineStringToken("{title}", (int)eTokenGridStr::title);
- tk->DefineStringToken("{orginaltitle}", (int)eTokenGridStr::orginaltitle);
- tk->DefineStringToken("{summary}", (int)eTokenGridStr::summary);
- tk->DefineStringToken("{tagline}", (int)eTokenGridStr::tagline);
- tk->DefineStringToken("{contentrating}", (int)eTokenGridStr::contentrating);
- tk->DefineStringToken("{ratingstring}", (int)eTokenGridStr::ratingstring);
- tk->DefineStringToken("{studio}", (int)eTokenGridStr::studio);
- tk->DefineStringToken("{thumb}", (int)eTokenGridStr::thumb);
- tk->DefineStringToken("{art}", (int)eTokenGridStr::art);
- tk->DefineStringToken("{seriestitle}", (int)eTokenGridStr::seriestitle);
- tk->DefineStringToken("{seriesthumb}", (int)eTokenGridStr::seriesthumb);
- tk->DefineStringToken("{banner}", (int)eTokenGridStr::banner);
- tk->DefineStringToken("{videoResolution}", (int)eTokenGridStr::videoResolution);
- tk->DefineStringToken("{aspectRatio}", (int)eTokenGridStr::aspectRatio);
- tk->DefineStringToken("{audioCodec}", (int)eTokenGridStr::audioCodec);
- tk->DefineStringToken("{videoCodec}", (int)eTokenGridStr::videoCodec);
- tk->DefineStringToken("{container}", (int)eTokenGridStr::container);
- tk->DefineStringToken("{videoFrameRate}", (int)eTokenGridStr::videoFrameRate);
- tk->DefineStringToken("{serverstartpointname}", (int)eTokenGridStr::serverstartpointname);
- tk->DefineStringToken("{serverip}", (int)eTokenGridStr::serverip);
- tk->DefineStringToken("{serverversion}", (int)eTokenGridStr::serverversion);
-
- tk->DefineLoopToken("{roles[actor]}", (int)eTokenGridActorLst::roles);
- tk->DefineLoopToken("{genres[genre]}", (int)eTokenGridGenresLst::genres);
+void cPlexSdOsd::DefineGridTokens(skindesignerapi::cTokenContainer *tk) {
+ tk->DefineIntToken("{viewmode}", (int) eTokenGridInt::viewmode);
+ tk->DefineIntToken("{viewgroup}", (int) eTokenGridInt::viewgroup);
+ tk->DefineIntToken("{viewCount}", (int) eTokenGridInt::viewCount);
+ tk->DefineIntToken("{viewoffset}", (int) eTokenGridInt::viewoffset);
+ tk->DefineIntToken("{viewoffsetpercent}", (int) eTokenGridInt::viewoffsetpercent);
+ tk->DefineIntToken("{duration}", (int) eTokenGridInt::duration);
+ tk->DefineIntToken("{year}", (int) eTokenGridInt::year);
+ tk->DefineIntToken("{hasthumb}", (int) eTokenGridInt::hasthumb);
+ tk->DefineIntToken("{hasart}", (int) eTokenGridInt::hasart);
+ tk->DefineIntToken("{ismovie}", (int) eTokenGridInt::ismovie);
+ tk->DefineIntToken("{isepisode}", (int) eTokenGridInt::isepisode);
+ tk->DefineIntToken("{isdirectory}", (int) eTokenGridInt::isdirectory);
+ tk->DefineIntToken("{isshow}", (int) eTokenGridInt::isshow);
+ tk->DefineIntToken("{isseason}", (int) eTokenGridInt::isseason);
+ tk->DefineIntToken("{isclip}", (int) eTokenGridInt::isclip);
+ tk->DefineIntToken("{originallyAvailableYear}", (int) eTokenGridInt::originallyAvailableYear);
+ tk->DefineIntToken("{originallyAvailableMonth}", (int) eTokenGridInt::originallyAvailableMonth);
+ tk->DefineIntToken("{originallyAvailableDay}", (int) eTokenGridInt::originallyAvailableDay);
+ tk->DefineIntToken("{season}", (int) eTokenGridInt::season);
+ tk->DefineIntToken("{episode}", (int) eTokenGridInt::episode);
+ tk->DefineIntToken("{leafCount}", (int) eTokenGridInt::leafCount);
+ tk->DefineIntToken("{viewedLeafCount}", (int) eTokenGridInt::viewedLeafCount);
+ tk->DefineIntToken("{childCount}", (int) eTokenGridInt::childCount);
+ tk->DefineIntToken("{rating}", (int) eTokenGridInt::rating);
+ tk->DefineIntToken("{hasseriesthumb}", (int) eTokenGridInt::hasseriesthumb);
+ tk->DefineIntToken("{hasbanner}", (int) eTokenGridInt::hasbanner);
+ tk->DefineIntToken("{columns}", (int) eTokenGridInt::columns);
+ tk->DefineIntToken("{rows}", (int) eTokenGridInt::rows);
+ tk->DefineIntToken("{position}", (int) eTokenGridInt::position);
+ tk->DefineIntToken("{totalcount}", (int) eTokenGridInt::totalcount);
+ tk->DefineIntToken("{bitrate}", (int) eTokenGridInt::bitrate);
+ tk->DefineIntToken("{width}", (int) eTokenGridInt::width);
+ tk->DefineIntToken("{height}", (int) eTokenGridInt::height);
+ tk->DefineIntToken("{audioChannels}", (int) eTokenGridInt::audioChannels);
+ tk->DefineIntToken("{isdummy}", (int) eTokenGridInt::isdummy);
+ tk->DefineIntToken("{isserver}", (int) eTokenGridInt::isserver);
+ tk->DefineIntToken("{serverport}", (int) eTokenGridInt::serverport);
+ tk->DefineIntToken("{extratype}", (int) eTokenGridInt::extratype);
+
+ tk->DefineStringToken("{title}", (int) eTokenGridStr::title);
+ tk->DefineStringToken("{orginaltitle}", (int) eTokenGridStr::orginaltitle);
+ tk->DefineStringToken("{summary}", (int) eTokenGridStr::summary);
+ tk->DefineStringToken("{tagline}", (int) eTokenGridStr::tagline);
+ tk->DefineStringToken("{contentrating}", (int) eTokenGridStr::contentrating);
+ tk->DefineStringToken("{ratingstring}", (int) eTokenGridStr::ratingstring);
+ tk->DefineStringToken("{studio}", (int) eTokenGridStr::studio);
+ tk->DefineStringToken("{thumb}", (int) eTokenGridStr::thumb);
+ tk->DefineStringToken("{art}", (int) eTokenGridStr::art);
+ tk->DefineStringToken("{seriestitle}", (int) eTokenGridStr::seriestitle);
+ tk->DefineStringToken("{seriesthumb}", (int) eTokenGridStr::seriesthumb);
+ tk->DefineStringToken("{banner}", (int) eTokenGridStr::banner);
+ tk->DefineStringToken("{videoResolution}", (int) eTokenGridStr::videoResolution);
+ tk->DefineStringToken("{aspectRatio}", (int) eTokenGridStr::aspectRatio);
+ tk->DefineStringToken("{audioCodec}", (int) eTokenGridStr::audioCodec);
+ tk->DefineStringToken("{videoCodec}", (int) eTokenGridStr::videoCodec);
+ tk->DefineStringToken("{container}", (int) eTokenGridStr::container);
+ tk->DefineStringToken("{videoFrameRate}", (int) eTokenGridStr::videoFrameRate);
+ tk->DefineStringToken("{serverstartpointname}", (int) eTokenGridStr::serverstartpointname);
+ tk->DefineStringToken("{serverip}", (int) eTokenGridStr::serverip);
+ tk->DefineStringToken("{serverversion}", (int) eTokenGridStr::serverversion);
+
+ tk->DefineLoopToken("{roles[actor]}", (int) eTokenGridActorLst::roles);
+ tk->DefineLoopToken("{genres[genre]}", (int) eTokenGridGenresLst::genres);
}
-void cPlexSdOsd::DefineFooterTokens(skindesignerapi::cTokenContainer *tk)
-{
- tk->DefineIntToken("{red1}", (int)eTokenFooterInt::red1);
- tk->DefineIntToken("{red2}", (int)eTokenFooterInt::red2);
- tk->DefineIntToken("{red3}", (int)eTokenFooterInt::red3);
- tk->DefineIntToken("{red4}", (int)eTokenFooterInt::red4);
- tk->DefineIntToken("{green1}", (int)eTokenFooterInt::green1);
- tk->DefineIntToken("{green2}", (int)eTokenFooterInt::green2);
- tk->DefineIntToken("{green3}", (int)eTokenFooterInt::green3);
- tk->DefineIntToken("{green4}", (int)eTokenFooterInt::green4);
- tk->DefineIntToken("{yellow1}", (int)eTokenFooterInt::yellow1);
- tk->DefineIntToken("{yellow2}", (int)eTokenFooterInt::yellow2);
- tk->DefineIntToken("{yellow3}", (int)eTokenFooterInt::yellow3);
- tk->DefineIntToken("{yellow4}", (int)eTokenFooterInt::yellow4);
- tk->DefineIntToken("{blue1}", (int)eTokenFooterInt::blue1);
- tk->DefineIntToken("{blue2}", (int)eTokenFooterInt::blue2);
- tk->DefineIntToken("{blue3}", (int)eTokenFooterInt::blue3);
- tk->DefineIntToken("{blue4}", (int)eTokenFooterInt::blue4);
- tk->DefineStringToken("{red}", (int)eTokenFooterStr::red);
- tk->DefineStringToken("{green}", (int)eTokenFooterStr::green);
- tk->DefineStringToken("{yellow}", (int)eTokenFooterStr::yellow);
- tk->DefineStringToken("{blue}", (int)eTokenFooterStr::blue);
+void cPlexSdOsd::DefineFooterTokens(skindesignerapi::cTokenContainer *tk) {
+ tk->DefineIntToken("{red1}", (int) eTokenFooterInt::red1);
+ tk->DefineIntToken("{red2}", (int) eTokenFooterInt::red2);
+ tk->DefineIntToken("{red3}", (int) eTokenFooterInt::red3);
+ tk->DefineIntToken("{red4}", (int) eTokenFooterInt::red4);
+ tk->DefineIntToken("{green1}", (int) eTokenFooterInt::green1);
+ tk->DefineIntToken("{green2}", (int) eTokenFooterInt::green2);
+ tk->DefineIntToken("{green3}", (int) eTokenFooterInt::green3);
+ tk->DefineIntToken("{green4}", (int) eTokenFooterInt::green4);
+ tk->DefineIntToken("{yellow1}", (int) eTokenFooterInt::yellow1);
+ tk->DefineIntToken("{yellow2}", (int) eTokenFooterInt::yellow2);
+ tk->DefineIntToken("{yellow3}", (int) eTokenFooterInt::yellow3);
+ tk->DefineIntToken("{yellow4}", (int) eTokenFooterInt::yellow4);
+ tk->DefineIntToken("{blue1}", (int) eTokenFooterInt::blue1);
+ tk->DefineIntToken("{blue2}", (int) eTokenFooterInt::blue2);
+ tk->DefineIntToken("{blue3}", (int) eTokenFooterInt::blue3);
+ tk->DefineIntToken("{blue4}", (int) eTokenFooterInt::blue4);
+ tk->DefineStringToken("{red}", (int) eTokenFooterStr::red);
+ tk->DefineStringToken("{green}", (int) eTokenFooterStr::green);
+ tk->DefineStringToken("{yellow}", (int) eTokenFooterStr::yellow);
+ tk->DefineStringToken("{blue}", (int) eTokenFooterStr::blue);
}
-void cPlexSdOsd::DefineWatchTokens(skindesignerapi::cTokenContainer *tk)
-{
- tk->DefineIntToken("{sec}", (int)eTokenTimeInt::sec);
- tk->DefineIntToken("{min}", (int)eTokenTimeInt::min);
- tk->DefineIntToken("{hour}", (int)eTokenTimeInt::hour);
- tk->DefineIntToken("{hmins}", (int)eTokenTimeInt::hmins);
- tk->DefineIntToken("{day}", (int)eTokenTimeInt::day);
- tk->DefineIntToken("{year}", (int)eTokenTimeInt::year);
- tk->DefineStringToken("{time}", (int)eTokenTimeStr::time);
- tk->DefineStringToken("{dayname}", (int)eTokenTimeStr::dayname);
- tk->DefineStringToken("{daynameshort}", (int)eTokenTimeStr::daynameshort);
- tk->DefineStringToken("{dayleadingzero}", (int)eTokenTimeStr::dayleadingzero);
- tk->DefineStringToken("{month}", (int)eTokenTimeStr::month);
- tk->DefineStringToken("{monthname}", (int)eTokenTimeStr::monthname);
- tk->DefineStringToken("{monthnameshort}", (int)eTokenTimeStr::monthnameshort);
+void cPlexSdOsd::DefineWatchTokens(skindesignerapi::cTokenContainer *tk) {
+ tk->DefineIntToken("{sec}", (int) eTokenTimeInt::sec);
+ tk->DefineIntToken("{min}", (int) eTokenTimeInt::min);
+ tk->DefineIntToken("{hour}", (int) eTokenTimeInt::hour);
+ tk->DefineIntToken("{hmins}", (int) eTokenTimeInt::hmins);
+ tk->DefineIntToken("{day}", (int) eTokenTimeInt::day);
+ tk->DefineIntToken("{year}", (int) eTokenTimeInt::year);
+ tk->DefineStringToken("{time}", (int) eTokenTimeStr::time);
+ tk->DefineStringToken("{dayname}", (int) eTokenTimeStr::dayname);
+ tk->DefineStringToken("{daynameshort}", (int) eTokenTimeStr::daynameshort);
+ tk->DefineStringToken("{dayleadingzero}", (int) eTokenTimeStr::dayleadingzero);
+ tk->DefineStringToken("{month}", (int) eTokenTimeStr::month);
+ tk->DefineStringToken("{monthname}", (int) eTokenTimeStr::monthname);
+ tk->DefineStringToken("{monthnameshort}", (int) eTokenTimeStr::monthnameshort);
}
-void cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk)
-{
- switch(ve) {
- case eViewElementsDetail::background:
- tk->DefineIntToken("{hasfanart}", (int)eTokenDetailBackgroundInt::hasfanart);
- tk->DefineIntToken("{hascover}", (int)eTokenDetailBackgroundInt::hascover);
- tk->DefineStringToken("{fanartpath}", (int)eTokenDetailBackgroundStr::fanartpath);
- tk->DefineStringToken("{coverpath}", (int)eTokenDetailBackgroundStr::coverpath);
- break;
- case eViewElementsDetail::footer:
- DefineFooterTokens(tk);
- break;
- case eViewElementsDetail::info:
- DefineGridTokens(tk);
- break;
- case eViewElementsDetail::message:
- tk->DefineIntToken("{displaymessage}", (int)eTokenMessageInt::displaymessage);
- tk->DefineStringToken("{message}", (int)eTokenMessageStr::message);
- break;
- case eViewElementsDetail::scrollbar:
- tk->DefineIntToken("{height}", (int)eTokenScrollbarInt::height);
- tk->DefineIntToken("{offset}", (int)eTokenScrollbarInt::offset);
- tk->DefineIntToken("{hasscrollbar}", (int)eTokenScrollbarInt::hasscrollbar);
- break;
- default:
- break;
- }
+void cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk) {
+ switch (ve) {
+ case eViewElementsDetail::background:
+ tk->DefineIntToken("{hasfanart}", (int) eTokenDetailBackgroundInt::hasfanart);
+ tk->DefineIntToken("{hascover}", (int) eTokenDetailBackgroundInt::hascover);
+ tk->DefineStringToken("{fanartpath}", (int) eTokenDetailBackgroundStr::fanartpath);
+ tk->DefineStringToken("{coverpath}", (int) eTokenDetailBackgroundStr::coverpath);
+ break;
+ case eViewElementsDetail::footer:
+ DefineFooterTokens(tk);
+ break;
+ case eViewElementsDetail::info:
+ DefineGridTokens(tk);
+ break;
+ case eViewElementsDetail::message:
+ tk->DefineIntToken("{displaymessage}", (int) eTokenMessageInt::displaymessage);
+ tk->DefineStringToken("{message}", (int) eTokenMessageStr::message);
+ break;
+ case eViewElementsDetail::scrollbar:
+ tk->DefineIntToken("{height}", (int) eTokenScrollbarInt::height);
+ tk->DefineIntToken("{offset}", (int) eTokenScrollbarInt::offset);
+ tk->DefineIntToken("{hasscrollbar}", (int) eTokenScrollbarInt::hasscrollbar);
+ break;
+ default:
+ break;
+ }
}
diff --git a/plexSdOsd.h b/plexSdOsd.h
index 4549400..5e299cd 100644
--- a/plexSdOsd.h
+++ b/plexSdOsd.h
@@ -22,38 +22,49 @@
#include <libskindesignerapi/osdelements.h>
#include <libskindesignerapi/skindesignerosdbase.h>
-class cPlexSdOsd : public skindesignerapi::cSkindesignerOsdObject
-{
-private:
- std::shared_ptr<cBrowserGrid> m_pBrowserGrid;
- std::shared_ptr<cDetailView> m_pDetailGrid;
- std::shared_ptr<skindesignerapi::cViewElement> m_pMessage;
- bool m_messageDisplayed;
- bool m_detailsActive;
-
- std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
- std::shared_ptr<skindesignerapi::cOsdView> m_pDetailsView;
-
- void Flush();
- void DrawMessage(std::string message);
-
- void ShowDetails(plexclient::cVideo *vid);
-
+class cPlexSdOsd : public skindesignerapi::cSkindesignerOsdObject {
+private:
+ std::shared_ptr<cBrowserGrid> m_pBrowserGrid;
+ std::shared_ptr<cDetailView> m_pDetailGrid;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pMessage;
+ bool m_messageDisplayed;
+ bool m_detailsActive;
+
+ std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
+ std::shared_ptr<skindesignerapi::cOsdView> m_pDetailsView;
+
+ void Flush();
+
+ void DrawMessage(std::string message);
+
+ void ShowDetails(plexclient::cVideo *vid);
+
public:
- cPlexSdOsd(skindesignerapi::cPluginStructure *plugStruct);
- ~cPlexSdOsd();
- virtual void Show(void);
- virtual eOSState ProcessKey(eKeys Key);
- eOSState ProcessKeyDetailView(eKeys Key);
- eOSState ProcessKeyBrowserView(eKeys Key);
-
- bool SdSupport();
- static cMutex RedrawMutex;
- static void DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenContainer *tk);
- static void DefineGridTokens(skindesignerapi::cTokenContainer *tk);
- static void DefineFooterTokens(skindesignerapi::cTokenContainer *tk);
- static void DefineWatchTokens(skindesignerapi::cTokenContainer *tk);
- static void DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk);
+ cPlexSdOsd(skindesignerapi::cPluginStructure *plugStruct);
+
+ ~cPlexSdOsd();
+
+ virtual void Show(void);
+
+ virtual eOSState ProcessKey(eKeys Key);
+
+ eOSState ProcessKeyDetailView(eKeys Key);
+
+ eOSState ProcessKeyBrowserView(eKeys Key);
+
+ bool SdSupport();
+
+ static cMutex RedrawMutex;
+
+ static void DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenContainer *tk);
+
+ static void DefineGridTokens(skindesignerapi::cTokenContainer *tk);
+
+ static void DefineFooterTokens(skindesignerapi::cTokenContainer *tk);
+
+ static void DefineWatchTokens(skindesignerapi::cTokenContainer *tk);
+
+ static void DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk);
};
#endif // CPLEXSDOSD_H
diff --git a/plexgdm.cpp b/plexgdm.cpp
index e274689..c0d2cb0 100644
--- a/plexgdm.cpp
+++ b/plexgdm.cpp
@@ -4,247 +4,239 @@
#include <ctime>
#include "Plexservice.h"
-namespace plexclient
-{
-
-plexgdm::plexgdm()
-{
- _discoverMessage = "M-SEARCH * HTTP/1.0";
- _clientHeader = "* HTTP/1.0";
- _multicastAddress = "239.0.0.250";
- _clientUpdatePort = 32412;
- _helloSent = false;
- _discoverInterval = 30 * 1000;
- _discoverTimer.Set(1);
-
- m_discoverAdress = Poco::Net::SocketAddress(_multicastAddress, 32414);
- m_clientRegisterGroup = Poco::Net::SocketAddress(_multicastAddress, 32413);
-
- m_discoveryComplete = false;
- m_registrationIsRunning = false;
- m_clientRegistered = false;
- m_discoveryInterval = 120;
- m_discoveryIsRunning = false;
-}
-
-plexgdm::~plexgdm()
-{
-}
-
-void plexgdm::clientDetails(std::string c_id,
- std::string c_name,
- std::string c_port,
- std::string c_product,
- std::string c_version)
-{
- _clientData = "Content-Type: plex/media-player\r\n"
- "Resource-Identifier: " + c_id + "\r\n"
- "Device-Class: PC\r\n"
- "Name: " + c_name + "\r\n"
- "Port: " + c_port + "\r\n"
- "Product: " + c_product + "\r\n"
- "Protocol: plex\r\n"
- "Protocol-Capabilities: navigation,playback,timeline\r\n"
- "Protocol-Version: 1\r\n"
- "Version: " + c_version + "\r\n";
- _clientId = c_id;
-}
-
-std::string plexgdm::getClientDetails()
-{
- if(_clientData.empty())
- throw "client_Data not initialized";
- return _clientData;
-}
-
-void plexgdm::Action()
-{
- if(Config::GetInstance().UseConfiguredServer) {
- // Adds a Server to vector
- GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort);
-
- if(Config::GetInstance().UsePlexAccount) {
- GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort)->SetAuthToken(Plexservice::GetMyPlexToken());
- }
- }
-
- // Get remote Resources
- Plexservice::UpdateResources();
-
- char buffer[1024];
- m_registrationIsRunning = true;
- m_discoveryIsRunning = true;
- cMutexLock lock(&m_mutex);
-
- Poco::Net::MulticastSocket update_sock(Poco::Net::SocketAddress(Poco::Net::IPAddress(), _clientUpdatePort), true);
-
- update_sock.setLoopback(true);
- update_sock.setReuseAddress(true);
- update_sock.setTimeToLive(255);
- update_sock.setBlocking(false);
-
- while(Running()) {
- try {
- if(!_helloSent) {
- // Send initial Client Registration
- std::string s = Poco::format("HELLO %s\n%s", _clientHeader, _clientData);
- update_sock.sendTo(s.c_str(), s.length(), m_clientRegisterGroup, 0);
- _helloSent = true;
- }
- if(m_registrationIsRunning) {
- Poco::Net::SocketAddress sender;
- int n = 0;
- try {
- n = update_sock.receiveFrom(buffer, sizeof(buffer), sender);
- } catch(Poco::TimeoutException& e) {
- n = 0;
- }
- if(n > 0) {
- std::string buf(buffer, n);
- if(buf.find("M-SEARCH * HTTP/1.") != std::string::npos) {
- //dsyslog("[plex]: Detected client discovery request from %s", sender.host().toString().c_str());
- int t = std::time(0);
- std::string s = Poco::format("HTTP/1.0 200 OK\r\n%sUpdated-At: %d", _clientData, t);
- update_sock.sendTo(s.c_str(), s.length(), sender, 0);
- m_clientRegistered = true;
- }
- }
- }
-
- } catch(Poco::IOException&) {
- // networkconnection is lost, reset
- _helloSent = false;
- } catch (Poco::Exception&) {
-
- }
-
- if(m_discoveryIsRunning && _discoverTimer.TimedOut()) {
- discover();
- _discoverTimer.Set(_discoverInterval);
- }
- m_waitCondition.TimedWait(m_mutex, 500);
- }
- // Client loop stopped
- try {
- // unregister from Server
- std::string s = Poco::format("BYE %s\r\n%s", _clientHeader, _clientData);
- update_sock.sendTo(s.c_str(), s.length(), m_clientRegisterGroup, 0);
- } catch (Poco::Exception) {}
-
- m_clientRegistered = false;
-}
-
-void plexgdm::discover()
-{
- try {
-
-
- char buffer[1024];
- std::map<std::string, std::string> vBuffer;
-
- Poco::Net::MulticastSocket socket(Poco::Net::SocketAddress(Poco::Net::IPAddress(), m_discoverAdress.port()), true);
- socket.setLoopback(true);
- socket.setTimeToLive(1);
- socket.setReceiveTimeout(Poco::Timespan(0, 600 * 1000)); // microseconds
- socket.joinGroup(m_discoverAdress.host()); // Throws a NotFoundException if there is no multicast network device
- socket.sendTo(_discoverMessage.c_str(), _discoverMessage.length(), m_discoverAdress, 0);
-
- try {
-
- while(true) {
- Poco::Net::SocketAddress sender;
- int n = socket.receiveFrom(buffer, sizeof(buffer), sender);
- std::string buf(buffer, n);
- if(buf.find("200 OK") != std::string::npos) {
- vBuffer[sender.host().toString()] = buf;
- }
- }
-
- } catch(Poco::TimeoutException) {}
-
- socket.close();
-
- m_discoveryComplete = true;
-
- for(std::map<std::string, std::string>::iterator it = vBuffer.begin(); it != vBuffer.end(); ++it) {
- std::string host = it->first;
- std::string data = it->second;
-
- PlexServer newServ(data, host);
- // Set token for local servers
- if(Config::GetInstance().UsePlexAccount) {
- newServ.SetAuthToken(Plexservice::GetMyPlexToken());
- }
-
- if(AddServer(newServ)) {
- isyslog("[plex] New server found via GDM: %s", host.c_str());
- }
- else if(GetServer(newServ.m_sUuid)) {
- GetServer(newServ.m_sUuid)->ParseData(data, host);
- dsyslog("[plex] Server updated via GDM: %s", host.c_str());
- }
- }
- } catch (Poco::IOException&) {
- // No Networkconnection
- } catch(Poco::NotFoundException&) {
- // there is no multicast network device
- } catch (Poco::Exception&) {}
-}
-
-void plexgdm::stopRegistration()
-{
- if(m_registrationIsRunning) {
- m_registrationIsRunning = false;
- m_waitCondition.Broadcast();
- Cancel();
- }
-}
-
-PlexServer* plexgdm::GetServer(std::string ip, int port)
-{
- for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
- if(s_it->GetHost() == ip && s_it->GetPort() == port) {
- return &(*s_it);
- }
- }
- m_vServers.push_back(PlexServer(ip, port));
- return &m_vServers[m_vServers.size()-1];
-}
+namespace plexclient {
+
+ plexgdm::plexgdm() {
+ _discoverMessage = "M-SEARCH * HTTP/1.0";
+ _clientHeader = "* HTTP/1.0";
+ _multicastAddress = "239.0.0.250";
+ _clientUpdatePort = 32412;
+ _helloSent = false;
+ _discoverInterval = 30 * 1000;
+ _discoverTimer.Set(1);
+
+ m_discoverAdress = Poco::Net::SocketAddress(_multicastAddress, 32414);
+ m_clientRegisterGroup = Poco::Net::SocketAddress(_multicastAddress, 32413);
+
+ m_discoveryComplete = false;
+ m_registrationIsRunning = false;
+ m_clientRegistered = false;
+ m_discoveryInterval = 120;
+ m_discoveryIsRunning = false;
+ }
+
+ plexgdm::~plexgdm() {
+ }
+
+ void plexgdm::clientDetails(std::string c_id,
+ std::string c_name,
+ std::string c_port,
+ std::string c_product,
+ std::string c_version) {
+ _clientData = "Content-Type: plex/media-player\r\n"
+ "Resource-Identifier: " + c_id + "\r\n"
+ "Device-Class: PC\r\n"
+ "Name: " + c_name + "\r\n"
+ "Port: " + c_port + "\r\n"
+ "Product: " + c_product + "\r\n"
+ "Protocol: plex\r\n"
+ "Protocol-Capabilities: navigation,playback,timeline\r\n"
+ "Protocol-Version: 1\r\n"
+ "Version: " + c_version + "\r\n";
+ _clientId = c_id;
+ }
+
+ std::string plexgdm::getClientDetails() {
+ if (_clientData.empty())
+ throw "client_Data not initialized";
+ return _clientData;
+ }
+
+ void plexgdm::Action() {
+ if (Config::GetInstance().UseConfiguredServer) {
+ // Adds a Server to vector
+ GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort);
+
+ if (Config::GetInstance().UsePlexAccount) {
+ GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort)->SetAuthToken(
+ Plexservice::GetMyPlexToken());
+ }
+ }
+
+ // Get remote Resources
+ Plexservice::UpdateResources();
+
+ char buffer[1024];
+ m_registrationIsRunning = true;
+ m_discoveryIsRunning = true;
+ cMutexLock lock(&m_mutex);
+
+ Poco::Net::MulticastSocket update_sock(Poco::Net::SocketAddress(Poco::Net::IPAddress(), _clientUpdatePort),
+ true);
+
+ update_sock.setLoopback(true);
+ update_sock.setReuseAddress(true);
+ update_sock.setTimeToLive(255);
+ update_sock.setBlocking(false);
+
+ while (Running()) {
+ try {
+ if (!_helloSent) {
+ // Send initial Client Registration
+ std::string s = Poco::format("HELLO %s\n%s", _clientHeader, _clientData);
+ update_sock.sendTo(s.c_str(), s.length(), m_clientRegisterGroup, 0);
+ _helloSent = true;
+ }
+ if (m_registrationIsRunning) {
+ Poco::Net::SocketAddress sender;
+ int n = 0;
+ try {
+ n = update_sock.receiveFrom(buffer, sizeof(buffer), sender);
+ } catch (Poco::TimeoutException &e) {
+ n = 0;
+ }
+ if (n > 0) {
+ std::string buf(buffer, n);
+ if (buf.find("M-SEARCH * HTTP/1.") != std::string::npos) {
+ //dsyslog("[plex]: Detected client discovery request from %s", sender.host().toString().c_str());
+ int t = std::time(0);
+ std::string s = Poco::format("HTTP/1.0 200 OK\r\n%sUpdated-At: %d", _clientData, t);
+ update_sock.sendTo(s.c_str(), s.length(), sender, 0);
+ m_clientRegistered = true;
+ }
+ }
+ }
+
+ } catch (Poco::IOException &) {
+ // networkconnection is lost, reset
+ _helloSent = false;
+ } catch (Poco::Exception &) {
+
+ }
+
+ if (m_discoveryIsRunning && _discoverTimer.TimedOut()) {
+ discover();
+ _discoverTimer.Set(_discoverInterval);
+ }
+ m_waitCondition.TimedWait(m_mutex, 500);
+ }
+ // Client loop stopped
+ try {
+ // unregister from Server
+ std::string s = Poco::format("BYE %s\r\n%s", _clientHeader, _clientData);
+ update_sock.sendTo(s.c_str(), s.length(), m_clientRegisterGroup, 0);
+ } catch (Poco::Exception) { }
+
+ m_clientRegistered = false;
+ }
+
+ void plexgdm::discover() {
+ try {
+
+
+ char buffer[1024];
+ std::map<std::string, std::string> vBuffer;
+
+ Poco::Net::MulticastSocket socket(Poco::Net::SocketAddress(Poco::Net::IPAddress(), m_discoverAdress.port()),
+ true);
+ socket.setLoopback(true);
+ socket.setTimeToLive(1);
+ socket.setReceiveTimeout(Poco::Timespan(0, 600 * 1000)); // microseconds
+ socket.joinGroup(
+ m_discoverAdress.host()); // Throws a NotFoundException if there is no multicast network device
+ socket.sendTo(_discoverMessage.c_str(), _discoverMessage.length(), m_discoverAdress, 0);
+
+ try {
+
+ while (true) {
+ Poco::Net::SocketAddress sender;
+ int n = socket.receiveFrom(buffer, sizeof(buffer), sender);
+ std::string buf(buffer, n);
+ if (buf.find("200 OK") != std::string::npos) {
+ vBuffer[sender.host().toString()] = buf;
+ }
+ }
+
+ } catch (Poco::TimeoutException) { }
+
+ socket.close();
+
+ m_discoveryComplete = true;
+
+ for (std::map<std::string, std::string>::iterator it = vBuffer.begin(); it != vBuffer.end(); ++it) {
+ std::string host = it->first;
+ std::string data = it->second;
+
+ PlexServer newServ(data, host);
+ // Set token for local servers
+ if (Config::GetInstance().UsePlexAccount) {
+ newServ.SetAuthToken(Plexservice::GetMyPlexToken());
+ }
+
+ if (AddServer(newServ)) {
+ isyslog("[plex] New server found via GDM: %s", host.c_str());
+ }
+ else if (GetServer(newServ.m_sUuid)) {
+ GetServer(newServ.m_sUuid)->ParseData(data, host);
+ dsyslog("[plex] Server updated via GDM: %s", host.c_str());
+ }
+ }
+ } catch (Poco::IOException &) {
+ // No Networkconnection
+ } catch (Poco::NotFoundException &) {
+ // there is no multicast network device
+ } catch (Poco::Exception &) { }
+ }
+
+ void plexgdm::stopRegistration() {
+ if (m_registrationIsRunning) {
+ m_registrationIsRunning = false;
+ m_waitCondition.Broadcast();
+ Cancel();
+ }
+ }
+
+ PlexServer *plexgdm::GetServer(std::string ip, int port) {
+ for (std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
+ if (s_it->GetHost() == ip && s_it->GetPort() == port) {
+ return &(*s_it);
+ }
+ }
+ m_vServers.push_back(PlexServer(ip, port));
+ return &m_vServers[m_vServers.size() - 1];
+ }
/*
* Returns the first owned online server, if there is no owned server it will return the first remote server, or NULL
*/
-PlexServer* plexgdm::GetFirstServer()
-{
- for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
- if(s_it->IsOwned() && !s_it->Offline) {
- return &(*s_it);
- }
- }
- if (m_vServers.size() > 0) return &m_vServers[0];
- return NULL;
-}
-
-PlexServer* plexgdm::GetServer(std::string uuid)
-{
- for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
- if(s_it->GetUuid() == uuid ){
- return &(*s_it);
- }
- }
- return NULL;
-}
-
-bool plexgdm::AddServer(PlexServer server)
-{
- for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
- if(s_it->GetUuid() == server.GetUuid() ){
- return false;
- }
- }
- m_vServers.push_back(server);
- isyslog("[plex] New Server Added: %s", server.GetUri().c_str());
- return true;
-}
+ PlexServer *plexgdm::GetFirstServer() {
+ for (std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
+ if (s_it->IsOwned() && !s_it->Offline) {
+ return &(*s_it);
+ }
+ }
+ if (m_vServers.size() > 0) return &m_vServers[0];
+ return NULL;
+ }
+
+ PlexServer *plexgdm::GetServer(std::string uuid) {
+ for (std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
+ if (s_it->GetUuid() == uuid) {
+ return &(*s_it);
+ }
+ }
+ return NULL;
+ }
+
+ bool plexgdm::AddServer(PlexServer server) {
+ for (std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) {
+ if (s_it->GetUuid() == server.GetUuid()) {
+ return false;
+ }
+ }
+ m_vServers.push_back(server);
+ isyslog("[plex] New Server Added: %s", server.GetUri().c_str());
+ return true;
+ }
} // namespace
diff --git a/plexgdm.h b/plexgdm.h
index 0e6a329..8db4dac 100644
--- a/plexgdm.h
+++ b/plexgdm.h
@@ -19,62 +19,70 @@
#include "PlexServer.h"
-namespace plexclient
-{
-
-class plexgdm : public cThread
-{
-public:
- static plexgdm& GetInstance() {
- static plexgdm instance;
- return instance;
- }
- ~plexgdm();
- void clientDetails(std::string c_id, std::string c_name, std::string c_port, std::string c_product, std::string c_version);
- std::string getClientDetails();
- PlexServer* GetServer(std::string ip, int port);
- PlexServer* GetServer(std::string uuid);
- bool AddServer(PlexServer server);
- PlexServer* GetFirstServer();
- void discover();
-
- void Action(void);
-
- void stopRegistration();
-
- std::vector<PlexServer> &GetPlexservers() {
- return m_vServers;
- }
-
-protected:
-
-
-private:
- plexgdm();
- cMutex m_mutex;
- cCondVar m_waitCondition;
- int _discoverInterval;
- cTimeMs _discoverTimer;
- bool _helloSent;
-
- Poco::Net::SocketAddress m_discoverAdress;
- Poco::Net::SocketAddress m_clientRegisterGroup;
-
- volatile int m_discoveryInterval;
-
- volatile bool m_discoveryComplete;
- volatile bool m_clientRegistered;
- volatile bool m_discoveryIsRunning;
- volatile bool m_registrationIsRunning;
-
- std::string _discoverMessage;
- std::string _clientHeader;
- std::string _clientData;
- std::string _clientId;
- std::string _multicastAddress;
- int _clientUpdatePort;
- std::vector<PlexServer> m_vServers;
-};
+namespace plexclient {
+
+ class plexgdm : public cThread {
+ public:
+ static plexgdm &GetInstance() {
+ static plexgdm instance;
+ return instance;
+ }
+
+ ~plexgdm();
+
+ void clientDetails(std::string c_id, std::string c_name, std::string c_port, std::string c_product,
+ std::string c_version);
+
+ std::string getClientDetails();
+
+ PlexServer *GetServer(std::string ip, int port);
+
+ PlexServer *GetServer(std::string uuid);
+
+ bool AddServer(PlexServer server);
+
+ PlexServer *GetFirstServer();
+
+ void discover();
+
+ void Action(void);
+
+ void stopRegistration();
+
+ std::vector<PlexServer> &GetPlexservers() {
+ return m_vServers;
+ }
+
+ protected:
+
+
+ private:
+ plexgdm();
+
+ cMutex m_mutex;
+ cCondVar m_waitCondition;
+ int _discoverInterval;
+ cTimeMs _discoverTimer;
+ bool _helloSent;
+
+ Poco::Net::SocketAddress m_discoverAdress;
+ Poco::Net::SocketAddress m_clientRegisterGroup;
+
+ volatile int m_discoveryInterval;
+
+ volatile bool m_discoveryComplete;
+ volatile bool m_clientRegistered;
+ volatile bool m_discoveryIsRunning;
+ volatile bool m_registrationIsRunning;
+
+ std::string _discoverMessage;
+ std::string _clientHeader;
+ std::string _clientData;
+ std::string _clientId;
+ std::string _multicastAddress;
+ int _clientUpdatePort;
+ std::vector<PlexServer> m_vServers;
+ };
}
#endif // PLEXGDM_H
diff --git a/services.h b/services.h
index c26ffba..3c2a59a 100644
--- a/services.h
+++ b/services.h
@@ -4,20 +4,17 @@
#define MPV_SEEK "Mpv_Seek"
// play the given Filename, this can be a media file or a playlist
-typedef struct
-{
- char *Filename;
+typedef struct {
+ char *Filename;
} Mpv_PlayFile;
// Overrides the displayed title in replay info
-typedef struct
-{
- char *Title;
+typedef struct {
+ char *Title;
} Mpv_SetTitle;
-typedef struct
-{
- int SeekAbsolute;
- int SeekRelative;
+typedef struct {
+ int SeekAbsolute;
+ int SeekRelative;
} Mpv_Seek; \ No newline at end of file
diff --git a/tokendefinitions.h b/tokendefinitions.h
index e4e9d0a..dffdc46 100644
--- a/tokendefinitions.h
+++ b/tokendefinitions.h
@@ -2,198 +2,198 @@
#define __TOKENDEFINITIONS_H
enum class eViews {
- rootView,
- detailView
+ rootView,
+ detailView
};
enum class eViewElementsDetail {
- background,
- footer,
- info,
- message,
- scrollbar,
- watch
+ background,
+ footer,
+ info,
+ message,
+ scrollbar,
+ watch
};
enum class eViewElementsRoot {
- background,
- header,
- footer,
- infopane,
- watch,
- message,
- scrollbar
+ background,
+ header,
+ footer,
+ infopane,
+ watch,
+ message,
+ scrollbar
};
enum class eViewGrids {
- cover,
- detail,
- list,
+ cover,
+ detail,
+ list,
};
enum class eViewDetailViewGrids {
- extras
+ extras
};
enum class eTokenGridInt {
- viewmode = 0,
- viewgroup,
- viewCount,
- viewoffset,
- viewoffsetpercent,
- duration,
- year,
- hasthumb,
- hasart,
- ismovie,
- isepisode,
- isdirectory,
- isshow,
- isseason,
- isclip,
- originallyAvailableYear,
- originallyAvailableMonth,
- originallyAvailableDay,
- season,
- episode,
- leafCount,
- viewedLeafCount,
- childCount,
- rating,
- hasseriesthumb,
- hasbanner,
- columns,
- rows,
- position,
- totalcount,
- bitrate,
- width,
- height,
- audioChannels,
- isdummy,
- isserver,
- serverport,
- extratype
+ viewmode = 0,
+ viewgroup,
+ viewCount,
+ viewoffset,
+ viewoffsetpercent,
+ duration,
+ year,
+ hasthumb,
+ hasart,
+ ismovie,
+ isepisode,
+ isdirectory,
+ isshow,
+ isseason,
+ isclip,
+ originallyAvailableYear,
+ originallyAvailableMonth,
+ originallyAvailableDay,
+ season,
+ episode,
+ leafCount,
+ viewedLeafCount,
+ childCount,
+ rating,
+ hasseriesthumb,
+ hasbanner,
+ columns,
+ rows,
+ position,
+ totalcount,
+ bitrate,
+ width,
+ height,
+ audioChannels,
+ isdummy,
+ isserver,
+ serverport,
+ extratype
};
enum class eTokenGridStr {
- title = 0,
- orginaltitle,
- summary,
- tagline,
- contentrating,
- ratingstring,
- studio,
- thumb,
- art,
- seriestitle,
- seriesthumb,
- banner,
- videoResolution,
- aspectRatio,
- audioCodec,
- videoCodec,
- container,
- videoFrameRate,
- serverstartpointname,
- serverip,
- serverversion,
- tabname
+ title = 0,
+ orginaltitle,
+ summary,
+ tagline,
+ contentrating,
+ ratingstring,
+ studio,
+ thumb,
+ art,
+ seriestitle,
+ seriesthumb,
+ banner,
+ videoResolution,
+ aspectRatio,
+ audioCodec,
+ videoCodec,
+ container,
+ videoFrameRate,
+ serverstartpointname,
+ serverip,
+ serverversion,
+ tabname
};
enum class eTokenGridActorLst {
- roles = 0
+ roles = 0
};
enum class eTokenGridGenresLst {
- genres = 0
+ genres = 0
};
-
+
enum class eTokenMessageInt {
- displaymessage = 0
+ displaymessage = 0
};
enum class eTokenMessageStr {
- message = 0
+ message = 0
};
enum class eTokenScrollbarInt {
- height = 0,
- offset,
- hasscrollbar
+ height = 0,
+ offset,
+ hasscrollbar
};
enum class eTokenBackgroundInt {
- viewmode = 0,
- isdirectory
+ viewmode = 0,
+ isdirectory
};
enum class eTokenBackgroundStr {
- selecteditembackground = 0,
- currentdirectorybackground
+ selecteditembackground = 0,
+ currentdirectorybackground
};
enum class eTokenDetailBackgroundInt {
- hasfanart = 0,
- hascover
+ hasfanart = 0,
+ hascover
};
enum class eTokenDetailBackgroundStr {
- fanartpath = 0,
- coverpath
+ fanartpath = 0,
+ coverpath
};
enum class eTokenTimeInt {
- sec = 0,
- min,
- hour,
- hmins,
- day,
- year
+ sec = 0,
+ min,
+ hour,
+ hmins,
+ day,
+ year
};
enum class eTokenTimeStr {
- time = 0,
- dayname,
- daynameshort,
- dayleadingzero,
- month,
- monthname,
- monthnameshort
+ time = 0,
+ dayname,
+ daynameshort,
+ dayleadingzero,
+ month,
+ monthname,
+ monthnameshort
};
enum class eTokenFooterInt {
- red1 = 0,
- red2,
- red3,
- red4,
- green1,
- green2,
- green3,
- green4,
- yellow1,
- yellow2,
- yellow3,
- yellow4,
- blue1,
- blue2,
- blue3,
- blue4
+ red1 = 0,
+ red2,
+ red3,
+ red4,
+ green1,
+ green2,
+ green3,
+ green4,
+ yellow1,
+ yellow2,
+ yellow3,
+ yellow4,
+ blue1,
+ blue2,
+ blue3,
+ blue4
};
enum class eTokenFooterStr {
- red = 0,
- green,
- yellow,
- blue
+ red = 0,
+ green,
+ yellow,
+ blue
};
enum class eTokenProgressbarInt {
-
+
};
enum class eTokenProgressbarStr {
-
+
};
/*<TranscodeSession key="jhul52ltx5lpiudi"
@@ -215,7 +215,7 @@ enum class eTokenProgressbarStr {
* height="808" />
*/
enum class eTokenTranscodeinfoStr {
-
+
};
#endif //__TOKENDEFINITIONS_H \ No newline at end of file
diff --git a/user.cpp b/user.cpp
index ea2880b..d3457b8 100644
--- a/user.cpp
+++ b/user.cpp
@@ -1,31 +1,29 @@
#include "user.h"
-namespace plexclient
-{
+namespace plexclient {
-user::user(std::istream *response)
-{
- try {
- InputSource src(*response);
- DOMParser parser;
- Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
+ user::user(std::istream *response) {
+ try {
+ InputSource src(*response);
+ DOMParser parser;
+ Poco::XML::AutoPtr<Document> pDoc = parser.parse(&src);
- NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
- Node* pNode = it.nextNode();
+ NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ALL);
+ Node *pNode = it.nextNode();
- while(pNode) {
- if(Poco::icompare(pNode->nodeName(),"authentication-token") == 0) {
- pNode = it.nextNode();
- authenticationToken = pNode->nodeValue();
- break;
- }
- pNode = it.nextNode();
- }
+ while (pNode) {
+ if (Poco::icompare(pNode->nodeName(), "authentication-token") == 0) {
+ pNode = it.nextNode();
+ authenticationToken = pNode->nodeValue();
+ break;
+ }
+ pNode = it.nextNode();
+ }
- } catch(Exception &exc) {
- std::cerr << exc.displayText() << std::endl;
- }
+ } catch (Exception &exc) {
+ std::cerr << exc.displayText() << std::endl;
+ }
-}
+ }
}
diff --git a/user.h b/user.h
index 4cca6cf..01862b7 100644
--- a/user.h
+++ b/user.h
@@ -20,20 +20,18 @@ using Poco::XML::Node;
using Poco::XML::AutoPtr;
using Poco::Exception;
-namespace plexclient
-{
+namespace plexclient {
-class user
-{
-public:
- user(std::istream *response);
+ class user {
+ public:
+ user(std::istream *response);
- std::string authenticationToken;
+ std::string authenticationToken;
-protected:
+ protected:
-private:
-};
+ private:
+ };
}
diff --git a/viewGridNavigator.cpp b/viewGridNavigator.cpp
index 804e39d..8bd5b5b 100644
--- a/viewGridNavigator.cpp
+++ b/viewGridNavigator.cpp
@@ -6,272 +6,258 @@
unsigned int cGridElement::AbsoluteGridIdCounter = 0;
-cGridElement::cGridElement()
-{
- m_iGridId = AbsoluteGridIdCounter++;
- Position = -1;
- m_bInit = true;
+cGridElement::cGridElement() {
+ m_iGridId = AbsoluteGridIdCounter++;
+ Position = -1;
+ m_bInit = true;
}
-cViewGridNavigator::cViewGridNavigator(std::shared_ptr<skindesignerapi::cOsdView> rootView)
-{
- m_columns = 2;
- m_rows = 2;
- m_startIndex = 0;
- m_endIndex = 0;
- m_newDimensions = true;
- m_setIterator = true;
- m_bEnableRedraw = false;
-
- m_pGrid = NULL;
- m_pRootView = rootView;
+cViewGridNavigator::cViewGridNavigator(std::shared_ptr<skindesignerapi::cOsdView> rootView) {
+ m_columns = 2;
+ m_rows = 2;
+ m_startIndex = 0;
+ m_endIndex = 0;
+ m_newDimensions = true;
+ m_setIterator = true;
+ m_bEnableRedraw = false;
+
+ m_pGrid = NULL;
+ m_pRootView = rootView;
}
-void cViewGridNavigator::SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid> grid)
-{
- if (grid) {
- if(m_pGrid) m_pGrid->Clear();
- m_pGrid = std::shared_ptr<skindesignerapi::cViewGrid>(grid);
- }
+void cViewGridNavigator::SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid> grid) {
+ if (grid) {
+ if (m_pGrid) m_pGrid->Clear();
+ m_pGrid = std::shared_ptr<skindesignerapi::cViewGrid>(grid);
+ }
}
-void cViewGridNavigator::ReDraw(cGridElement* element)
-{
- if(m_bHidden || !m_bEnableRedraw) return;
- if(element) {
- cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
- if (!element->IsVisible()) {
- return;
- }
- double x, y;
- element->GetPosition(x, y);
- element->AddTokens(m_pGrid);
- m_pGrid->AddIntToken((int)eTokenGridInt::columns, m_columns);
- m_pGrid->AddIntToken((int)eTokenGridInt::rows, m_rows);
- double width = 1.0 / m_columns;
- double height = 1.0 / m_rows;
- m_pGrid->SetGrid(element->GridElementId(), x, y, width, height);
- Flush();
- }
+void cViewGridNavigator::ReDraw(cGridElement *element) {
+ if (m_bHidden || !m_bEnableRedraw) return;
+ if (element) {
+ cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
+ if (!element->IsVisible()) {
+ return;
+ }
+ double x, y;
+ element->GetPosition(x, y);
+ element->AddTokens(m_pGrid);
+ m_pGrid->AddIntToken((int) eTokenGridInt::columns, m_columns);
+ m_pGrid->AddIntToken((int) eTokenGridInt::rows, m_rows);
+ double width = 1.0 / m_columns;
+ double height = 1.0 / m_rows;
+ m_pGrid->SetGrid(element->GridElementId(), x, y, width, height);
+ Flush();
+ }
}
-void cViewGridNavigator::FilterElements(int scrollOffset)
-{
- if(m_vElements.size() == 0) return;
-
- m_startIndex += scrollOffset;
- if(m_startIndex < 0) m_startIndex = 0;
-
- m_endIndex = m_startIndex + (m_rows * m_columns);
- if(m_endIndex > (int)m_vElements.size()) m_endIndex = m_vElements.size();
-
- if(scrollOffset > 0 && m_startIndex >= m_endIndex) {
- // allign elements
- int delta = m_vElements.size() % m_columns;
- delta = m_rows * m_columns - m_columns + delta;
- m_startIndex = m_endIndex - delta;
- }
-
- int i = 0;
- int pos = 0;
- m_bEnableRedraw = false;
- for(auto it = m_vElements.begin(); it != m_vElements.end(); ++it) {
-
- if(i >= m_startIndex && i < m_endIndex) {
- cGridElement *elem = *it;
- elem->Position = pos++;
- SetGridElementData(elem);
-
- if(m_setIterator) {
- m_activeElementIter = it;
- m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), true);
- m_setIterator = false;
- }
- } else {
- if((*it)->Position > -1) m_pGrid->Delete((*it)->GridElementId());
- (*it)->Dirty();
- (*it)->Position = -1;
- (*it)->SetPosition(-1,-1);
- }
- i++;
- }
- m_bEnableRedraw = true;
- m_newDimensions = false;
+void cViewGridNavigator::FilterElements(int scrollOffset) {
+ if (m_vElements.size() == 0) return;
+
+ m_startIndex += scrollOffset;
+ if (m_startIndex < 0) m_startIndex = 0;
+
+ m_endIndex = m_startIndex + (m_rows * m_columns);
+ if (m_endIndex > (int) m_vElements.size()) m_endIndex = m_vElements.size();
+
+ if (scrollOffset > 0 && m_startIndex >= m_endIndex) {
+ // allign elements
+ int delta = m_vElements.size() % m_columns;
+ delta = m_rows * m_columns - m_columns + delta;
+ m_startIndex = m_endIndex - delta;
+ }
+
+ int i = 0;
+ int pos = 0;
+ m_bEnableRedraw = false;
+ for (auto it = m_vElements.begin(); it != m_vElements.end(); ++it) {
+
+ if (i >= m_startIndex && i < m_endIndex) {
+ cGridElement *elem = *it;
+ elem->Position = pos++;
+ SetGridElementData(elem);
+
+ if (m_setIterator) {
+ m_activeElementIter = it;
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), true);
+ m_setIterator = false;
+ }
+ } else {
+ if ((*it)->Position > -1) m_pGrid->Delete((*it)->GridElementId());
+ (*it)->Dirty();
+ (*it)->Position = -1;
+ (*it)->SetPosition(-1, -1);
+ }
+ i++;
+ }
+ m_bEnableRedraw = true;
+ m_newDimensions = false;
}
-void cViewGridNavigator::SetGridElementData(cGridElement *obj)
-{
- // calculate position
- double row, column, x, y, height, width;
-
- row = floor(obj->Position / m_columns);
- column = obj->Position - (row * m_columns);
- width = 1.0 / m_columns;
- height = 1.0 / m_rows;
- x = width * column;
- y= height * row;
-
- cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
- if(obj->IsNew() || m_newDimensions) {
- // fill data
- obj->SetPosition(x, y);
- obj->AddTokens(m_pGrid, true, std::bind(&cViewGridNavigator::ReDraw, this, std::placeholders::_1));
- // set GridDimensions
- m_pGrid->AddIntToken((int)eTokenGridInt::columns, m_columns);
- m_pGrid->AddIntToken((int)eTokenGridInt::rows, m_rows);
- m_pGrid->AddIntToken((int)eTokenGridInt::position, obj->AbsolutePosition);
- m_pGrid->AddIntToken((int)eTokenGridInt::totalcount, m_vElements.size());
- m_pGrid->SetGrid(obj->GridElementId(), x, y, width, height);
- obj->InitFinished();
- } else {
- obj->SetPosition(x, y);
- m_pGrid->MoveGrid(obj->GridElementId(), x, y, width, height);
- }
+void cViewGridNavigator::SetGridElementData(cGridElement *obj) {
+ // calculate position
+ double row, column, x, y, height, width;
+
+ row = floor(obj->Position / m_columns);
+ column = obj->Position - (row * m_columns);
+ width = 1.0 / m_columns;
+ height = 1.0 / m_rows;
+ x = width * column;
+ y = height * row;
+
+ cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex);
+ if (obj->IsNew() || m_newDimensions) {
+ // fill data
+ obj->SetPosition(x, y);
+ obj->AddTokens(m_pGrid, true, std::bind(&cViewGridNavigator::ReDraw, this, std::placeholders::_1));
+ // set GridDimensions
+ m_pGrid->AddIntToken((int) eTokenGridInt::columns, m_columns);
+ m_pGrid->AddIntToken((int) eTokenGridInt::rows, m_rows);
+ m_pGrid->AddIntToken((int) eTokenGridInt::position, obj->AbsolutePosition);
+ m_pGrid->AddIntToken((int) eTokenGridInt::totalcount, m_vElements.size());
+ m_pGrid->SetGrid(obj->GridElementId(), x, y, width, height);
+ obj->InitFinished();
+ } else {
+ obj->SetPosition(x, y);
+ m_pGrid->MoveGrid(obj->GridElementId(), x, y, width, height);
+ }
}
-cGridElement* cViewGridNavigator::SelectedObject()
-{
- if(!m_setIterator)
- return *m_activeElementIter;
- return NULL;
+cGridElement *cViewGridNavigator::SelectedObject() {
+ if (!m_setIterator)
+ return *m_activeElementIter;
+ return NULL;
}
-void cViewGridNavigator::SetGridDimensions(int rows, int columns)
-{
- m_rows = rows;
- m_columns = columns;
- m_newDimensions = true;
+void cViewGridNavigator::SetGridDimensions(int rows, int columns) {
+ m_rows = rows;
+ m_columns = columns;
+ m_newDimensions = true;
}
-bool cViewGridNavigator::NavigateDown()
-{
- if (m_setIterator ) return false;
- auto next = m_activeElementIter + m_columns;
-
- bool scrollallaround = false;
- if (next >= m_vElements.end() && Config::GetInstance().ScrollAllAround) {
- next = m_vElements.begin();
- scrollallaround = true;
- } else if(next >= m_vElements.end()) {
- next = m_activeElementIter; // stay at current element //m_vElements.end()-1;
- return false;
- }
-
- // scroll down?
- if(!(*next)->IsVisible()) {
- int scrolloffset = m_columns;
- if(Config::GetInstance().ScrollByPage) {
- scrolloffset = m_columns*m_rows;
- }
- if(scrollallaround)
- scrolloffset = -((*m_activeElementIter)->AbsolutePosition);
-
- FilterElements(scrolloffset);
- }
-
- m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
- m_pGrid->SetCurrent((*next)->GridElementId(), true);
- m_activeElementIter = next;
- return true;
+bool cViewGridNavigator::NavigateDown() {
+ if (m_setIterator) return false;
+ auto next = m_activeElementIter + m_columns;
+
+ bool scrollallaround = false;
+ if (next >= m_vElements.end() && Config::GetInstance().ScrollAllAround) {
+ next = m_vElements.begin();
+ scrollallaround = true;
+ } else if (next >= m_vElements.end()) {
+ next = m_activeElementIter; // stay at current element //m_vElements.end()-1;
+ return false;
+ }
+
+ // scroll down?
+ if (!(*next)->IsVisible()) {
+ int scrolloffset = m_columns;
+ if (Config::GetInstance().ScrollByPage) {
+ scrolloffset = m_columns * m_rows;
+ }
+ if (scrollallaround)
+ scrolloffset = -((*m_activeElementIter)->AbsolutePosition);
+
+ FilterElements(scrolloffset);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+ return true;
}
-bool cViewGridNavigator::NavigateUp()
-{
- if (m_setIterator) return false;
- auto next = m_activeElementIter - m_columns;
-
- bool scrollallaround = false;
- if (next < m_vElements.begin() && Config::GetInstance().ScrollAllAround) {
- next = m_vElements.end() - 1;
- scrollallaround = true;
- } else if(next < m_vElements.begin()) {
- next = m_activeElementIter; // stay at current element //m_vElements.end()-1;
- return false;
- }
-
- //scroll up?
- if(!(*next)->IsVisible()) {
- int scrolloffset = -m_columns;
- if(Config::GetInstance().ScrollByPage) {
- scrolloffset = -m_columns*m_rows;
- }
- if(scrollallaround)
- scrolloffset = m_vElements.size();
-
- FilterElements(scrolloffset);
- }
-
- m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
- m_pGrid->SetCurrent((*next)->GridElementId(), true);
- m_activeElementIter = next;
- return true;
+bool cViewGridNavigator::NavigateUp() {
+ if (m_setIterator) return false;
+ auto next = m_activeElementIter - m_columns;
+
+ bool scrollallaround = false;
+ if (next < m_vElements.begin() && Config::GetInstance().ScrollAllAround) {
+ next = m_vElements.end() - 1;
+ scrollallaround = true;
+ } else if (next < m_vElements.begin()) {
+ next = m_activeElementIter; // stay at current element //m_vElements.end()-1;
+ return false;
+ }
+
+ //scroll up?
+ if (!(*next)->IsVisible()) {
+ int scrolloffset = -m_columns;
+ if (Config::GetInstance().ScrollByPage) {
+ scrolloffset = -m_columns * m_rows;
+ }
+ if (scrollallaround)
+ scrolloffset = m_vElements.size();
+
+ FilterElements(scrolloffset);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+ return true;
}
-bool cViewGridNavigator::NavigateLeft()
-{
- if (m_setIterator || m_activeElementIter == m_vElements.begin()) return false;
- auto next = m_activeElementIter - 1;
+bool cViewGridNavigator::NavigateLeft() {
+ if (m_setIterator || m_activeElementIter == m_vElements.begin()) return false;
+ auto next = m_activeElementIter - 1;
- if (m_columns == 1) {
- next = m_activeElementIter - m_rows;
- FilterElements(-m_rows);
- }
+ if (m_columns == 1) {
+ next = m_activeElementIter - m_rows;
+ FilterElements(-m_rows);
+ }
- if(next < m_vElements.begin()) next = m_vElements.begin();
+ if (next < m_vElements.begin()) next = m_vElements.begin();
- if(!(*next)->IsVisible()) {
- auto temp = m_activeElementIter;
- if(Config::GetInstance().ScrollByPage)
- FilterElements(-m_columns*m_rows);
- else
- FilterElements(-m_columns);
+ if (!(*next)->IsVisible()) {
+ auto temp = m_activeElementIter;
+ if (Config::GetInstance().ScrollByPage)
+ FilterElements(-m_columns * m_rows);
+ else
+ FilterElements(-m_columns);
- m_activeElementIter = temp;
- }
+ m_activeElementIter = temp;
+ }
- m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
- m_pGrid->SetCurrent((*next)->GridElementId(), true);
- m_activeElementIter = next;
- return true;
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+ return true;
}
-bool cViewGridNavigator::NavigateRight()
-{
- if (m_setIterator || m_activeElementIter == m_vElements.end() - 1) return false;
- auto next = m_activeElementIter + 1;
-
- if (m_columns == 1) {
- next = m_activeElementIter + m_rows;
- FilterElements(m_rows);
- }
-
- if(next >= m_vElements.end()) next = m_vElements.end()-1;
-
- if(!(*next)->IsVisible()) {
- if(Config::GetInstance().ScrollByPage)
- FilterElements(m_columns*m_rows);
- else
- FilterElements(m_columns);
- }
-
- m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
- m_pGrid->SetCurrent((*next)->GridElementId(), true);
- m_activeElementIter = next;
- return true;
+bool cViewGridNavigator::NavigateRight() {
+ if (m_setIterator || m_activeElementIter == m_vElements.end() - 1) return false;
+ auto next = m_activeElementIter + 1;
+
+ if (m_columns == 1) {
+ next = m_activeElementIter + m_rows;
+ FilterElements(m_rows);
+ }
+
+ if (next >= m_vElements.end()) next = m_vElements.end() - 1;
+
+ if (!(*next)->IsVisible()) {
+ if (Config::GetInstance().ScrollByPage)
+ FilterElements(m_columns * m_rows);
+ else
+ FilterElements(m_columns);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+ return true;
}
-void cViewGridNavigator::Deactivate(bool hide)
-{
- if (m_pRootView) {
- m_pRootView->Deactivate(hide);
- m_bHidden = hide;
- }
+void cViewGridNavigator::Deactivate(bool hide) {
+ if (m_pRootView) {
+ m_pRootView->Deactivate(hide);
+ m_bHidden = hide;
+ }
}
-void cViewGridNavigator::Activate()
-{
- if (m_pRootView) {
- m_pRootView->Activate();
- m_bHidden = false;
- }
+void cViewGridNavigator::Activate() {
+ if (m_pRootView) {
+ m_pRootView->Activate();
+ m_bHidden = false;
+ }
}
diff --git a/viewGridNavigator.h b/viewGridNavigator.h
index 4482d39..8cfd259 100644
--- a/viewGridNavigator.h
+++ b/viewGridNavigator.h
@@ -6,69 +6,100 @@
#include <functional>
#include <libskindesignerapi/osdelements.h>
-class cGridElement
-{
+class cGridElement {
private:
- bool m_bInit;
- double m_posX;
- double m_posY;
- static unsigned int AbsoluteGridIdCounter;
+ bool m_bInit;
+ double m_posX;
+ double m_posY;
+ static unsigned int AbsoluteGridIdCounter;
protected:
- unsigned int m_iGridId;
+ unsigned int m_iGridId;
public:
- cGridElement();
-
- bool IsNew() { return m_bInit; };
+ cGridElement();
+
+ bool IsNew() { return m_bInit; };
+
void Dirty() { m_bInit = true; };
+
void InitFinished() { m_bInit = false; };
- unsigned int GridElementId() { return m_iGridId; }
- bool IsVisible() { return Position > -1; }
- void SetPosition(double x, double y) { m_posX = x; m_posY = y; };
- void GetPosition(double &x, double &y) { x = m_posX; y = m_posY; };
- virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> osdElem, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL) = 0;
- int Position;
- int AbsolutePosition;
+
+ unsigned int GridElementId() { return m_iGridId; }
+
+ bool IsVisible() { return Position > -1; }
+
+ void SetPosition(double x, double y) {
+ m_posX = x;
+ m_posY = y;
+ };
+
+ void GetPosition(double &x, double &y) {
+ x = m_posX;
+ y = m_posY;
+ };
+
+ virtual void AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> osdElem, bool clear = true,
+ std::function<void(cGridElement *)> OnCached = NULL) = 0;
+
+ int Position;
+ int AbsolutePosition;
};
-class cViewGridNavigator
-{
+class cViewGridNavigator {
protected:
- int m_rows;
- int m_columns;
- bool m_bHidden;
- bool m_bEnableRedraw;
-
- std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
- std::shared_ptr<skindesignerapi::cViewGrid> m_pGrid;
-
- bool m_newDimensions;
- bool m_setIterator;
- std::vector<cGridElement*> m_vElements;
- std::vector<cGridElement*>::iterator m_activeElementIter;
- int m_startIndex;
- int m_endIndex;
-
- void FilterElements(int scrollOffset);
- void SetGridElementData(cGridElement *obj);
- void SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid> grid);
-
+ int m_rows;
+ int m_columns;
+ bool m_bHidden;
+ bool m_bEnableRedraw;
+
+ std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
+ std::shared_ptr<skindesignerapi::cViewGrid> m_pGrid;
+
+ bool m_newDimensions;
+ bool m_setIterator;
+ std::vector<cGridElement *> m_vElements;
+ std::vector<cGridElement *>::iterator m_activeElementIter;
+ int m_startIndex;
+ int m_endIndex;
+
+ void FilterElements(int scrollOffset);
+
+ void SetGridElementData(cGridElement *obj);
+
+ void SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid> grid);
+
public:
- cViewGridNavigator(std::shared_ptr<skindesignerapi::cOsdView> rootView);
- void SetGridDimensions(int rows, int columns);
- virtual void Flush() { m_pGrid->Display(); m_pRootView->Display(); };
- virtual void Clear() = 0;
- virtual bool NavigateLeft();
- virtual bool NavigateRight();
- virtual bool NavigateUp();
- virtual bool NavigateDown();
- virtual eOSState NavigateSelect() = 0;
- virtual eOSState NavigateBack() = 0;
- virtual void ReDraw(cGridElement* element);
- cGridElement* SelectedObject();
- virtual void Deactivate(bool hide);
- virtual void Activate();
+ cViewGridNavigator(std::shared_ptr<skindesignerapi::cOsdView> rootView);
+
+ void SetGridDimensions(int rows, int columns);
+
+ virtual void Flush() {
+ m_pGrid->Display();
+ m_pRootView->Display();
+ };
+
+ virtual void Clear() = 0;
+
+ virtual bool NavigateLeft();
+
+ virtual bool NavigateRight();
+
+ virtual bool NavigateUp();
+
+ virtual bool NavigateDown();
+
+ virtual eOSState NavigateSelect() = 0;
+
+ virtual eOSState NavigateBack() = 0;
+
+ virtual void ReDraw(cGridElement *element);
+
+ cGridElement *SelectedObject();
+
+ virtual void Deactivate(bool hide);
+
+ virtual void Activate();
};
#endif // cViewGridNAVIGATOR_H
diff --git a/viewHeader.cpp b/viewHeader.cpp
index 5d7c4ec..43d067e 100644
--- a/viewHeader.cpp
+++ b/viewHeader.cpp
@@ -1,54 +1,49 @@
#include "viewHeader.h"
#include "tokendefinitions.h"
-cViewHeader::cViewHeader(skindesignerapi::cViewElement* viewElem)
-{
- m_pViewElem = std::shared_ptr<skindesignerapi::cViewElement>(viewElem);
- m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+cViewHeader::cViewHeader(skindesignerapi::cViewElement *viewElem) {
+ m_pViewElem = std::shared_ptr<skindesignerapi::cViewElement>(viewElem);
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
}
-cViewHeader::~cViewHeader()
-{
+cViewHeader::~cViewHeader() {
}
-void cViewHeader::Draw(cGridElement* elem)
-{
- m_pViewElem->Clear();
- m_pViewElem->ClearTokens();
-
- elem->AddTokens(m_pViewElem, false);
-
- m_pViewElem->Display();
+void cViewHeader::Draw(cGridElement *elem) {
+ m_pViewElem->Clear();
+ m_pViewElem->ClearTokens();
+
+ elem->AddTokens(m_pViewElem, false);
+
+ m_pViewElem->Display();
}
-ePlexMenuTab cViewHeader::NextTab()
-{
- switch(m_eCurrentTab) {
- case ePlexMenuTab::pmtOnDeck:
- m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
- break;
- case ePlexMenuTab::pmtRecentlyAdded:
- m_eCurrentTab = ePlexMenuTab::pmtLibrary;
- break;
- case ePlexMenuTab::pmtLibrary:
- m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
- break;
- }
- return m_eCurrentTab;
+ePlexMenuTab cViewHeader::NextTab() {
+ switch (m_eCurrentTab) {
+ case ePlexMenuTab::pmtOnDeck:
+ m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
+ break;
+ case ePlexMenuTab::pmtRecentlyAdded:
+ m_eCurrentTab = ePlexMenuTab::pmtLibrary;
+ break;
+ case ePlexMenuTab::pmtLibrary:
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+ break;
+ }
+ return m_eCurrentTab;
}
-ePlexMenuTab cViewHeader::PrevTab()
-{
- switch(m_eCurrentTab) {
- case ePlexMenuTab::pmtOnDeck:
- m_eCurrentTab = ePlexMenuTab::pmtLibrary;
- break;
- case ePlexMenuTab::pmtRecentlyAdded:
- m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
- break;
- case ePlexMenuTab::pmtLibrary:
- m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
- break;
- }
- return m_eCurrentTab;
+ePlexMenuTab cViewHeader::PrevTab() {
+ switch (m_eCurrentTab) {
+ case ePlexMenuTab::pmtOnDeck:
+ m_eCurrentTab = ePlexMenuTab::pmtLibrary;
+ break;
+ case ePlexMenuTab::pmtRecentlyAdded:
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+ break;
+ case ePlexMenuTab::pmtLibrary:
+ m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
+ break;
+ }
+ return m_eCurrentTab;
}
diff --git a/viewHeader.h b/viewHeader.h
index 997f741..eac40bf 100644
--- a/viewHeader.h
+++ b/viewHeader.h
@@ -6,24 +6,28 @@
#include "viewGridNavigator.h"
enum ePlexMenuTab {
- pmtOnDeck,
- pmtRecentlyAdded,
- pmtLibrary
+ pmtOnDeck,
+ pmtRecentlyAdded,
+ pmtLibrary
};
-class cViewHeader
-{
+class cViewHeader {
private:
- ePlexMenuTab m_eCurrentTab;
- std::shared_ptr<skindesignerapi::cViewElement> m_pViewElem;
-
+ ePlexMenuTab m_eCurrentTab;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pViewElem;
+
public:
- cViewHeader(skindesignerapi::cViewElement* viewElem);
- ~cViewHeader();
- void Draw(cGridElement* elem);
- ePlexMenuTab NextTab();
- ePlexMenuTab PrevTab();
- ePlexMenuTab CurrentTab() { return m_eCurrentTab; }
+ cViewHeader(skindesignerapi::cViewElement *viewElem);
+
+ ~cViewHeader();
+
+ void Draw(cGridElement *elem);
+
+ ePlexMenuTab NextTab();
+
+ ePlexMenuTab PrevTab();
+
+ ePlexMenuTab CurrentTab() { return m_eCurrentTab; }
};
#endif // CVIEWHEADER_H