summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchriszero <zerov83@gmail.com>2015-02-14 18:53:11 +0100
committerchriszero <zerov83@gmail.com>2015-02-14 18:53:11 +0100
commite412257abf8de4576a180351d24ff07589fa630c (patch)
treeed020de5c8257545eca66e96997984731ac60379
parent20fefdd3f341d6e7f6b15e4926bf5569aa1943d5 (diff)
downloadvdr-plugin-plex-e412257abf8de4576a180351d24ff07589fa630c.tar.gz
vdr-plugin-plex-e412257abf8de4576a180351d24ff07589fa630c.tar.bz2
Various Fixes0.1.0
Bump Version to frist beta.
-rw-r--r--Config.h11
-rw-r--r--Directory.cpp19
-rw-r--r--Directory.h17
-rw-r--r--Makefile38
-rw-r--r--MediaContainer.cpp12
-rw-r--r--MediaContainer.h8
-rw-r--r--PVideo.cpp24
-rw-r--r--PVideo.h8
-rw-r--r--PlexHTTPRequestHandler.cpp2
-rw-r--r--PlexHelper.cpp21
-rw-r--r--PlexHelper.h7
-rw-r--r--PlexReqHandlerFactory.cpp4
-rw-r--r--Plexservice.cpp129
-rw-r--r--Plexservice.h17
-rw-r--r--SubscriptionManager.cpp30
-rw-r--r--XmlObject.cpp10
-rw-r--r--XmlObject.h4
-rw-r--r--hlsPlayerControl.cpp42
-rw-r--r--misc.h157
-rw-r--r--plex.cpp59
-rw-r--r--plex.h143
-rw-r--r--plexgdm.cpp4
22 files changed, 187 insertions, 579 deletions
diff --git a/Config.h b/Config.h
index 0a43600..a424305 100644
--- a/Config.h
+++ b/Config.h
@@ -13,17 +13,6 @@
#include <vdr/osd.h>
#include <vdr/menuitems.h>
-
-
-/// vdr-plugin version number.
-/// Makefile extracts the version number for generating the file name
-/// for the distribution archive.
-static const char *const VERSION = "0.0.1"
-#ifdef GIT_REV
- "-GIT" GIT_REV
-#endif
- ;
-
#define STRING_SIZE 256
class Config
diff --git a/Directory.cpp b/Directory.cpp
index c54580f..46f2d54 100644
--- a/Directory.cpp
+++ b/Directory.cpp
@@ -1,19 +1,24 @@
#include "Directory.h"
+#include <Poco/Format.h>
namespace plexclient
{
-Directory::Directory(Poco::XML::Node* pNode)
+Directory::Directory(Poco::XML::Node* pNode, MediaContainer* parent)
{
if(Poco::icompare(pNode->nodeName(), "Directory") == 0) {
-
+ m_pParent = parent;
Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
+ m_iIndex = GetNodeValueAsInt(pAttribs->getNamedItem("index"));
+ 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_sComposite = GetNodeValue(pAttribs->getNamedItem("composite"));
m_sLanguage = GetNodeValue(pAttribs->getNamedItem("language"));
m_sUuid = GetNodeValue(pAttribs->getNamedItem("uuid"));
@@ -25,10 +30,14 @@ Directory::Directory(Poco::XML::Node* pNode)
}
}
-Directory::~Directory()
+std::string Directory::GetTitle()
{
+ switch(m_eType) {
+ case SEASON:
+ return Poco::format("%s - Staffel %d", m_pParent->m_sTitle2, m_iIndex);
+ default:
+ return m_sTitle;
+ }
}
-
}
-
diff --git a/Directory.h b/Directory.h
index fb54bc5..8638565 100644
--- a/Directory.h
+++ b/Directory.h
@@ -12,6 +12,7 @@
#include <Poco/String.h>
#include "XmlObject.h"
+#include "MediaContainer.h"
using Poco::XML::DOMParser;
using Poco::XML::Document;
@@ -23,16 +24,20 @@ using Poco::Exception;
namespace plexclient
{
-
+class MediaContainer;
+
class Directory: XmlObject
-{
+{
public:
- Directory(Poco::XML::Node* pNode);
- ~Directory();
+ Directory(Poco::XML::Node* pNode, MediaContainer* parent);
public:
bool m_bAllowSync;
+ int m_iIndex;
+ int m_iYear;
std::string m_sTitle;
+ std::string m_sTitle1;
+ std::string m_sTitle2;
std::string m_sComposite;
std::string m_sLanguage;
std::string m_sUuid;
@@ -42,7 +47,9 @@ public:
Poco::Timestamp m_tCreatedAt;
std::string m_sKey;
MediaType m_eType;
-
+ MediaContainer* m_pParent;
+
+ std::string GetTitle();
};
}
diff --git a/Makefile b/Makefile
index 30abf93..95eab3c 100644
--- a/Makefile
+++ b/Makefile
@@ -8,52 +8,20 @@
# By default the main source file also carries this name.
PLUGIN = plex
+VERSION := $(shell git describe --tags master)
LIBS += -lPocoUtil -lPocoNet -lPocoNetSSL -lPocoXML -lPocoFoundation -lpcrecpp
### Configuration (edit this for your needs)
- # support avfs a virtual file system
-# FIXME: AVFS isn't working, corrupts memory
-#AVFS ?= $(shell test -x /usr/bin/avfs-config && echo 1)
- # use ffmpeg libswscale
-#SWSCALE ?= $(shell pkg-config --exists libswscale && echo 1)
- # support png images
-#PNG ?= $(shell pkg-config --exists libpng && echo 1)
- # support jpg images
-#JPG ?= $(shell test -r /usr/include/jpeglib.h && echo 1)
-
CONFIG := #-DDEBUG # uncomment to build DEBUG
-ifeq ($(AVFS),1)
-CONFIG += -DUSE_AVFS
-_CFLAGS += $(shell /usr/bin/avfs-config --cflags)
-LIBS += $(shell /usr/bin/avfs-config --libs)
-endif
-ifeq ($(SWSCALE),1)
-CONFIG += -DUSE_SWSCALE
-_CFLAGS += $(shell pkg-config --cflags libswscale)
-LIBS += $(shell pkg-config --libs libswscale)
-endif
-ifeq ($(PNG),1)
-CONFIG += -DUSE_PNG
-_CFLAGS += $(shell pkg-config --cflags libpng)
-LIBS += $(shell pkg-config --libs libpng)
-endif
-ifeq ($(JPG),1)
-CONFIG += -DUSE_JPG
-_CFLAGS += -I/usr/include
-LIBS += -Ljpeg
-
-endif
-
-_CFLAGS += $(shell pkg-config --cflags xcb xcb-image xcb-keysyms xcb-icccm)
-#LIBS += -lrt $(shell pkg-config --libs xcb xcb-image xcb-keysyms xcb-icccm)
+_CFLAGS += $(shell pkg-config --cflags libpcrecpp)
### The version number of this plugin (taken from the main source file):
-VERSION = $(shell grep 'static const char \*const VERSION *=' $(PLUGIN).cpp | awk '{ print $$7 }' | sed -e 's/[";]//g')
+VERSION = $(shell grep 'static const char \*const VERSION *=' $(PLUGIN).h | awk '{ print $$7 }' | sed -e 's/[";]//g')
GIT_REV = $(shell git describe --always 2>/dev/null)
### The directory environment:
diff --git a/MediaContainer.cpp b/MediaContainer.cpp
index fa3c24a..6fa92f6 100644
--- a/MediaContainer.cpp
+++ b/MediaContainer.cpp
@@ -11,13 +11,14 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer Server)
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("title1"));
+
+ m_sTitle = GetNodeValue(pAttribs->getNamedItem("title"));
+ m_sTitle1 = GetNodeValue(pAttribs->getNamedItem("title1"));
m_sTitle2 = GetNodeValue(pAttribs->getNamedItem("title2"));
+ m_iParentIndex = GetNodeValueAsInt(pAttribs->getNamedItem("parentIndex"));
m_sThumb = GetNodeValue(pAttribs->getNamedItem("thumb"));
m_sViewGroup = GetNodeValue(pAttribs->getNamedItem("viewGroup"));
m_sLibrarySectionTitle = GetNodeValue(pAttribs->getNamedItem("librarySectionTitle"));
@@ -27,12 +28,13 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer Server)
m_iSize = GetNodeValueAsInt(pAttribs->getNamedItem("size"));
m_bAllowSync = GetNodeValueAsBool(pAttribs->getNamedItem("allowSync"));
m_sArt = GetNodeValue(pAttribs->getNamedItem("art"));
+ m_sSummary = GetNodeValue(pAttribs->getNamedItem("summary"));
pAttribs->release();
} else if(Poco::icompare(pNode->nodeName(), "Directory") == 0) {
- m_vDirectories.push_back(Directory(pNode));
+ m_vDirectories.push_back(Directory(pNode, this));
} else if(Poco::icompare(pNode->nodeName(), "Video") == 0) {
- m_vVideos.push_back(Video(pNode, Server));
+ m_vVideos.push_back(Video(pNode, Server, this));
}
pNode = it.nextNode();
diff --git a/MediaContainer.h b/MediaContainer.h
index e3ad6b7..967700f 100644
--- a/MediaContainer.h
+++ b/MediaContainer.h
@@ -30,7 +30,9 @@ using Poco::Exception;
namespace plexclient
{
-
+class Video;
+class Directory;
+
class MediaContainer: XmlObject
{
public:
@@ -47,6 +49,7 @@ public:
std::string m_sArt;
std::string m_sThumb;
std::string m_sTitle;
+ std::string m_sTitle1;
std::string m_sTitle2;
std::string m_sViewGroup;
int m_iLibrarySectionID;
@@ -54,7 +57,8 @@ public:
std::string m_sLibrarySectionUUID;
std::string m_sMediaTagPrefix;
int m_iSize;
-
+ std::string m_sSummary;
+ int m_iParentIndex;
};
}
diff --git a/PVideo.cpp b/PVideo.cpp
index b186da8..881ffe4 100644
--- a/PVideo.cpp
+++ b/PVideo.cpp
@@ -1,9 +1,10 @@
#include "PVideo.h"
+#include <Poco/Format.h>
namespace plexclient
{
-Video::Video(Poco::XML::Node* pNode, PlexServer Server)
+Video::Video(Poco::XML::Node* pNode, PlexServer Server, MediaContainer* parent)
{
m_iMyPlayOffset = 0;
m_Server = Server;
@@ -16,6 +17,8 @@ Video::Video(Poco::XML::Node* pNode, PlexServer Server)
Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes();
m_iRatingKey = GetNodeValueAsInt(pAttribs->getNamedItem("ratingKey"));
+ 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"));
@@ -51,6 +54,25 @@ Video::Video(Poco::XML::Node* pNode, PlexServer Server)
}
pChildNode = it.nextNode();
}
+ if (m_iParentIndex < 0) {
+ m_iParentIndex = parent->m_iParentIndex;
+ }
}
+std::string Video::GetTitle()
+{
+ std::string res = m_sTitle;
+ switch(m_tType) {
+ case MOVIE:
+ res = Poco::format("%s (%d)", m_sTitle, m_iYear);
+ break;
+ case EPISODE:
+ res = Poco::format("%02dx%02d - %s", m_iParentIndex, m_iIndex, m_sTitle);
+ break;
+ default:
+ break;
+ }
+ return res;
}
+
+} // Namespace
diff --git a/PVideo.h b/PVideo.h
index b78f57a..6c25011 100644
--- a/PVideo.h
+++ b/PVideo.h
@@ -16,6 +16,7 @@
#include <iostream>
#include "XmlObject.h"
+#include "MediaContainer.h"
#include "Media.h"
#include "PlexServer.h"
@@ -29,11 +30,12 @@ using Poco::Exception;
namespace plexclient
{
+class MediaContainer;
class Video: XmlObject
{
public:
- Video(Poco::XML::Node* pNode, PlexServer Server);
+ Video(Poco::XML::Node* pNode, PlexServer Server, MediaContainer* parent);
Video() {};
public:
@@ -63,6 +65,10 @@ public:
Media m_Media;
PlexServer m_Server;
int m_iMyPlayOffset;
+ int m_iIndex;
+ int m_iParentIndex;
+
+ std::string GetTitle();
};
}
diff --git a/PlexHTTPRequestHandler.cpp b/PlexHTTPRequestHandler.cpp
index 86ac3cd..552239a 100644
--- a/PlexHTTPRequestHandler.cpp
+++ b/PlexHTTPRequestHandler.cpp
@@ -235,7 +235,7 @@ void PlayerRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request,
if(query.find("offset") != query.end()) {
Cont.m_vVideos[0].m_iMyPlayOffset = atoi(query["offset"].c_str()) / 1000;
}
- //Poco::
+
ActionManager::GetInstance().AddAction(Cont.m_vVideos[0]);
} else if(request.getURI().find("/playback/play") != std::string::npos) {
cRemote::Put(kPlay);
diff --git a/PlexHelper.cpp b/PlexHelper.cpp
index b1421c5..61643d7 100644
--- a/PlexHelper.cpp
+++ b/PlexHelper.cpp
@@ -1,16 +1,25 @@
#include "PlexHelper.h"
+#include "Config.h"
+#include "plex.h"
namespace plexclient
{
-PlexHelper::PlexHelper()
+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");
-PlexHelper::~PlexHelper()
-{
+ //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 e42fc1d..0df6eaf 100644
--- a/PlexHelper.h
+++ b/PlexHelper.h
@@ -1,14 +1,17 @@
#ifndef PLEXHELPER_H
#define PLEXHELPER_H
+#include <Poco/Net/HTTPRequest.h>
+
namespace plexclient
{
class PlexHelper
{
public:
- PlexHelper();
- ~PlexHelper();
+ static void AddHttpHeader(Poco::Net::HTTPRequest& request);
+private:
+ PlexHelper() {};
};
diff --git a/PlexReqHandlerFactory.cpp b/PlexReqHandlerFactory.cpp
index ec33a12..dacdff7 100644
--- a/PlexReqHandlerFactory.cpp
+++ b/PlexReqHandlerFactory.cpp
@@ -12,7 +12,7 @@ PlexReqHandlerFactory::~PlexReqHandlerFactory()
}
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) {
@@ -23,7 +23,7 @@ Poco::Net::HTTPRequestHandler* PlexReqHandlerFactory::createRequestHandler(const
else {
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();
diff --git a/Plexservice.cpp b/Plexservice.cpp
index 776f9fc..7a1633e 100644
--- a/Plexservice.cpp
+++ b/Plexservice.cpp
@@ -1,12 +1,13 @@
#include "Plexservice.h"
+#include "PlexHelper.h"
+
namespace plexclient
{
Plexservice::Plexservice(PlexServer *server)
{
pServer = server;
- USERAGENT = "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";
}
Plexservice::~Plexservice()
@@ -56,13 +57,7 @@ std::string Plexservice::GetMyPlexToken()
Poco::Net::HTTPSClientSession plexSession("plex.tv", 443, context);
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/users/sign_in.xml", Poco::Net::HTTPMessage::HTTP_1_1);
- request.add("X-Plex-Platform", "VDR");
- request.add("X-Plex-Platform-Version", "2.0.4");
- request.add("X-Plex-Provides", "player");
- request.add("X-Plex-Product", "plex for vdr");
- request.add("X-Plex-Version", "0.0.1a");
- request.add("X-Plex-Device", "Linux");
- request.add("X-Plex-Client-Identifier", "plex for vdr");
+ PlexHelper::AddHttpHeader(request);
request.add("Authorization", Poco::format("Basic %s", m_sToken));
plexSession.sendRequest(request);
@@ -103,18 +98,6 @@ void Plexservice::Authenticate()
esyslog("[plex]Exception in %s s%", __func__, exc.displayText().c_str() );
}
}
-/*
-void Plexservice::DiscoverAllServers()
-{
- // try automatic discovery via multicast
- plexgdm gdmClient = plexgdm();
- gdmClient.discover();
- pServer = gdmClient.GetPServer();
- if (pServer == 0) {
- perror("No Plexserver found");
- }
-}
- */
PlexServer* Plexservice::GetServer()
{
@@ -129,7 +112,7 @@ MediaContainer* Plexservice::GetAllSections()
MediaContainer* Plexservice::GetSection(std::string section)
{
std::string token = GetMyPlexToken();
- if(GetHttpSession(true)) {
+ if(GetHttpSession()) {
Poco::Net::HTTPRequest *pRequest;
if(section[0]=='/') { // Full URI?
@@ -162,41 +145,16 @@ Poco::Net::HTTPRequest* Plexservice::CreateRequest(std::string path)
Poco::Net::HTTPRequest *pRequest = new Poco::Net::HTTPRequest(Poco::Net::HTTPRequest::HTTP_GET,
path, Poco::Net::HTTPMessage::HTTP_1_1);
- pRequest->add("User-Agent", USERAGENT);
-
- //pRequest->add("X-Plex-Client-Capabilities", "protocols=shoutcast,http-video;videoDecoders=h264{profile:high&resolution:1080&level:51};audioDecoders=mp3,aac");
- pRequest->add("X-Plex-Client-Identifier", Config::GetInstance().GetUUID());
- pRequest->add("X-Plex-Device", "PC");
- pRequest->add("X-Plex-Device-Name", Config::GetInstance().GetHostname());
- pRequest->add("X-Plex-Language", Config::GetInstance().GetLanguage());
- pRequest->add("X-Plex-Model", "Linux");
- pRequest->add("X-Plex-Platform", "VDR");
- pRequest->add("X-Plex-Product", "plex for vdr");
- pRequest->add("X-Plex-Provides", "player");
- pRequest->add("X-Plex-Version", "0.0.1a");
+ PlexHelper::AddHttpHeader(*pRequest);
return pRequest;
}
MediaContainer Plexservice::GetMediaContainer(std::string fullUrl)
{
-
Poco::URI fileuri(fullUrl);
-
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.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");
-
- //pRequest->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", "0.0.1a");
+ PlexHelper::AddHttpHeader(request);
Poco::Net::HTTPClientSession session(fileuri.getHost(), fileuri.getPort());
@@ -209,81 +167,6 @@ MediaContainer Plexservice::GetMediaContainer(std::string fullUrl)
return allsections;
}
-#ifdef CRYPTOPP
-std::string Plexservice::computeHMAC(std::string message)
-{
- using CryptoPP::Exception;
- using CryptoPP::HMAC;
- using CryptoPP::SHA256;
- using CryptoPP::Base64Encoder;
- using CryptoPP::Base64Decoder;
- using CryptoPP::StringSink;
- using CryptoPP::ArraySink;
- using CryptoPP::StringSource;
- using CryptoPP::HashFilter;
-
- const std::string transcode_private = "k3U6GLkZOoNIoSgjDshPErvqMIFdE0xMTx8kgsrhnC0=";
-
- std::string encoded;
- byte key[32];
-
- StringSource(transcode_private, true,
- new Base64Decoder(
- new ArraySink(key, 32)
- ) // Base64Encoder
- ); // StringSource
-
- try {
- HMAC<SHA256> hmac((byte*)key, sizeof(key));
-
- StringSource(message, true,
- new HashFilter(hmac,
- new Base64Encoder(
- new StringSink(encoded),
- false
- ) // Base64Encoder
- ) // HashFilter
- ); // StringSource
- } catch(const CryptoPP::Exception& e) {
- std::cerr << e.what() << std::endl;
- }
- return encoded;
-}
-
-std::string Plexservice::GetTranscodeUrl(Video* video)
-{
- const std::string transcodeURL = "/video/:/transcode/segmented/start.m3u8?";
- const std::string transcode_public = "KQMIY6GATPC63AIMC4R2";
-
- std::stringstream params;
- params << "identifier=com.plexapp.plugins.library";
- params << "&url=" << encode(pServer->GetUri() + video->m_pMedia->m_sPartKey);
- params << "&quality=8";
- params << "&ratingKey=" << video->m_iRatingKey;
- params << "&3g=0";
- params << "&offset=0";
- params << "&directStream=1";
- params << "&maxVideoBitrate=30000";
-
- int time = std::time(0);
- std::string message = Poco::format("%s@%d", transcodeURL + params.str(), time);
-
- std::string b64hmacMessage = computeHMAC(message);
-
- std::stringstream plexAccess;
- plexAccess << "&X-Plex-Access-Key=" << encode(transcode_public);
- plexAccess << "&X-Plex-Access-Time=" << Poco::format("%d", time);
- plexAccess << "&X-Plex-Access-Code=" << encode(b64hmacMessage);
- plexAccess << "&X-Plex-Client-Capabilities=";
- plexAccess << encode("protocols=http-live-streaming,http-streaming-video-720p,http-streaming-video-1080p;");
- plexAccess << encode("videoDecoders=h264{profile:high&resolution:1080&level:51};");
- plexAccess << encode("audioDecoders=aac,ac3{channels:6}");
-
- std::string fullQuery = params.str() + plexAccess.str();
- return pServer->GetUri() + transcodeURL + fullQuery;
-}
-#endif
-
std::string Plexservice::encode(std::string message)
{
std::string temp;
diff --git a/Plexservice.h b/Plexservice.h
index 02961d3..cccf17b 100644
--- a/Plexservice.h
+++ b/Plexservice.h
@@ -33,15 +33,6 @@
#include "user.h"
#include "MediaContainer.h"
-#ifdef CRYPTOPP
-#include <cryptopp/cryptlib.h>
-#include <cryptopp/hmac.h>
-#include <cryptopp/sha.h>
-#include <cryptopp/base64.h>
-#include <cryptopp/filters.h>
-#include <cryptopp/hex.h>
-#endif
-
namespace plexclient
{
@@ -76,14 +67,6 @@ private:
Poco::Net::HTTPClientSession* GetHttpSession(bool createNew = false);
Poco::Net::HTTPRequest* CreateRequest(std::string path);
-
-#ifdef CRYPTOPP
-protected:
- std::string computeHMAC(std::string message);
-public:
- std::string GetTranscodeUrl(Video* video);
-#endif
-
};
}
diff --git a/SubscriptionManager.cpp b/SubscriptionManager.cpp
index d312803..47bd6f2 100644
--- a/SubscriptionManager.cpp
+++ b/SubscriptionManager.cpp
@@ -11,6 +11,7 @@
#include "Plexservice.h"
#include "plexgdm.h"
+#include "PlexHelper.h"
namespace plexclient
{
@@ -77,17 +78,8 @@ void SubscriptionManager::NotifyServer()
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, uri.str(), 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-vdr");
- Request.add("X-Plex-Provides", "player");
- Request.add("X-Plex-Version", "0.0.1a");
-
+ PlexHelper::AddHttpHeader(Request);
+
Poco::Net::HTTPClientSession session(server, port);
session.sendRequest(Request);
@@ -99,9 +91,7 @@ void SubscriptionManager::NotifyServer()
} else {
m_bStoppedSent = false;
}
- } catch (Poco::Exception& e) {
- std::cout << e.displayText() << std::endl;
- }
+ } catch (Poco::Exception& e) {}
}
@@ -214,17 +204,7 @@ void Subscriber::SendUpdate(std::string msg, bool isNav)
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
"/:/timeline", 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-vdr");
- Request.add("X-Plex-Provides", "player");
- Request.add("X-Plex-Version", "0.0.1a");
+ PlexHelper::AddHttpHeader(Request);
Poco::Net::HTTPClientSession session(m_sHost, m_iPort);
diff --git a/XmlObject.cpp b/XmlObject.cpp
index 09db02d..d588c5f 100644
--- a/XmlObject.cpp
+++ b/XmlObject.cpp
@@ -14,7 +14,7 @@ std::string XmlObject::GetNodeValue(Poco::XML::Node* pNode)
int XmlObject::GetNodeValueAsInt(Poco::XML::Node* pNode)
{
- int value = 0;
+ int value = -1;
if(pNode != 0) {
try {
value = atoi(pNode->getNodeValue().c_str());
@@ -25,7 +25,7 @@ int XmlObject::GetNodeValueAsInt(Poco::XML::Node* pNode)
long XmlObject::GetNodeValueAsLong(Poco::XML::Node* pNode)
{
- long value = 0;
+ long value = -1;
if(pNode != 0) {
try {
value = atol(pNode->getNodeValue().c_str());
@@ -36,7 +36,7 @@ long XmlObject::GetNodeValueAsLong(Poco::XML::Node* pNode)
double XmlObject::GetNodeValueAsDouble(Poco::XML::Node* pNode)
{
- double value = 0;
+ double value = -1;
if(pNode != 0) {
try {
value = atod(pNode->getNodeValue().c_str());
@@ -81,7 +81,9 @@ MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node* pNode)
} else if (Poco::icompare(sType, "show") == 0) {
type = SHOW;
} else if (Poco::icompare(sType, "season") == 0) {
- type = SHOW;
+ type = SEASON;
+ } else if (Poco::icompare(sType, "episode") == 0) {
+ type = EPISODE;
}
}
return type;
diff --git a/XmlObject.h b/XmlObject.h
index 16b63b7..5b8b2ca 100644
--- a/XmlObject.h
+++ b/XmlObject.h
@@ -11,13 +11,13 @@
namespace plexclient
{
-enum MediaType {UNDEF = 0, PHOTO, MOVIE, MUSIC, SHOW, SEASON};
+enum MediaType {UNDEF = 0, PHOTO, MOVIE, MUSIC, SHOW, SEASON, EPISODE};
enum StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3};
class XmlObject
{
public:
-
+
protected:
static std::string GetNodeValue(Poco::XML::Node* pNode);
static int GetNodeValueAsInt(Poco::XML::Node* pNode);
diff --git a/hlsPlayerControl.cpp b/hlsPlayerControl.cpp
index b9e15d3..1f19336 100644
--- a/hlsPlayerControl.cpp
+++ b/hlsPlayerControl.cpp
@@ -46,10 +46,10 @@ cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer* Player, plexclient::Video Video
cHlsPlayerControl::~cHlsPlayerControl()
{
dsyslog("[plex]: '%s'", __FUNCTION__);
+ cStatus::MsgReplaying(this, NULL, NULL, false);
Hide();
delete player;
player = NULL;
- cStatus::MsgReplaying(this, NULL, NULL, false);
}
cString cHlsPlayerControl::GetHeader(void)
@@ -74,7 +74,7 @@ void cHlsPlayerControl::Hide(void)
void cHlsPlayerControl::Show(void)
{
- ShowTimed();
+ ShowTimed(3);
}
eOSState cHlsPlayerControl::ProcessKey(eKeys Key)
@@ -111,32 +111,15 @@ eOSState cHlsPlayerControl::ProcessKey(eKeys Key)
case kDown:
Pause();
break;
- case kFastRew|k_Release:
- case kLeft|k_Release:
- //if (Setup.MultiSpeedMode) break;
- case kFastRew:
- case kLeft:
- //Backward();
- break;
- case kFastFwd|k_Release:
- case kRight|k_Release:
- //if (Setup.MultiSpeedMode) break;
- case kFastFwd:
- case kRight:
- //Forward();
- break;
- case kRed:
- //TimeSearch();
- break;
case kGreen|k_Repeat:
case kGreen:
- Hide();
- player->JumpRelative(-600);
+ //Hide();
+ player->JumpRelative(-300);
break;
case kYellow|k_Repeat:
case kYellow:
- Hide();
- player->JumpRelative(600);
+ //Hide();
+ player->JumpRelative(300);
break;
case kStop:
case kBlue:
@@ -241,7 +224,7 @@ bool cHlsPlayerControl::ShowProgress(bool Initial)
if (GetIndex(Current, Total)) {
if (!visible) {
displayReplay = Skins.Current()->DisplayReplay(modeOnly);
- //displayReplay->SetMarks(player->Marks());
+ displayReplay->SetButtons(NULL,"-10m","+10m",tr("Stop"));
SetNeedsFastResponse(true);
visible = true;
}
@@ -265,16 +248,7 @@ bool cHlsPlayerControl::ShowProgress(bool Initial)
if (!Initial)
displayReplay->Flush();
displayReplay->SetCurrent(IndexToHMSF(Current, false, FramesPerSecond()));
-
- cString Title;
- //cString Pos = player ? player->PosStr() : cString(NULL);
- //if (*Pos && strlen(Pos) > 1) {
- // Title = cString::sprintf("%s (%s)", m_title.c_str(), *Pos);
- //} else {
- Title = m_title.c_str();
- //}
- displayReplay->SetTitle(Title);
-
+ displayReplay->SetTitle(m_title.c_str());
displayReplay->Flush();
lastCurrent = Current;
}
diff --git a/misc.h b/misc.h
deleted file mode 100644
index bb8fc6d..0000000
--- a/misc.h
+++ /dev/null
@@ -1,157 +0,0 @@
-///
-/// @file misc.h @brief Misc function header file
-///
-/// Copyright (c) 2009 - 2012 by Lutz Sammer. All Rights Reserved.
-///
-/// Contributor(s):
-/// Copied from vdr-softhddevice.
-///
-/// License: AGPLv3
-///
-/// This program is free software: you can redistribute it and/or modify
-/// it under the terms of the GNU Affero General Public License as
-/// published by the Free Software Foundation, either version 3 of the
-/// License.
-///
-/// This program is distributed in the hope that it will be useful,
-/// but WITHOUT ANY WARRANTY; without even the implied warranty of
-/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-/// GNU Affero General Public License for more details.
-///
-/// $Id: 3ced30cd6fa89227270c2f769654c65c62d3ef85 $
-//////////////////////////////////////////////////////////////////////////////
-
-/// @addtogroup misc
-/// @{
-
-#include <syslog.h>
-#include <stdarg.h>
-#include <time.h> // clock_gettime
-
-//////////////////////////////////////////////////////////////////////////////
-// Defines
-//////////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////////
-// Declares
-//////////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////////
-// Variables
-//////////////////////////////////////////////////////////////////////////////
-
-extern int SysLogLevel; ///< how much information wanted
-
-//////////////////////////////////////////////////////////////////////////////
-// Prototypes
-//////////////////////////////////////////////////////////////////////////////
-
-static inline void Syslog(const int, const char *format, ...)
- __attribute__ ((format(printf, 2, 3)));
-
-//////////////////////////////////////////////////////////////////////////////
-// Inlines
-//////////////////////////////////////////////////////////////////////////////
-
-#ifdef DEBUG
-#define DebugLevel 4 /// private debug level
-#else
-#define DebugLevel 0 /// private debug level
-#endif
-
-/**
-** Syslog output function.
-**
-** - 0 fatal errors and errors
-** - 1 warnings
-** - 2 info
-** - 3 important debug and fixme's
-*/
-static inline void Syslog(const int level, const char *format, ...)
-{
- if (SysLogLevel > level || DebugLevel > level) {
- va_list ap;
-
- va_start(ap, format);
- vsyslog(LOG_ERR, format, ap);
- va_end(ap);
- }
-}
-
-/**
-** Show error.
-*/
-#define Error(fmt...) Syslog(0, fmt)
-
-/**
-** Show fatal error.
-*/
-#define Fatal(fmt...) do { Error(fmt); abort(); } while (0)
-
-/**
-** Show warning.
-*/
-#define Warning(fmt...) Syslog(1, fmt)
-
-/**
-** Show info.
-*/
-#define Info(fmt...) Syslog(2, fmt)
-
-/**
-** Show debug.
-*/
-#ifdef DEBUG
-#define Debug(level, fmt...) Syslog(level, fmt)
-#else
-#define Debug(level, fmt...) /* disabled */
-#endif
-
-#ifndef AV_NOPTS_VALUE
-#define AV_NOPTS_VALUE INT64_C(0x8000000000000000)
-#endif
-
-/**
-** Nice time-stamp string.
-**
-** @param ts dvb time stamp
-*/
-static inline const char *Timestamp2String(int64_t ts)
-{
- static char buf[4][16];
- static int idx;
-
- if (ts == (int64_t) AV_NOPTS_VALUE) {
- return "--:--:--.---";
- }
- idx = (idx + 1) % 3;
- snprintf(buf[idx], sizeof(buf[idx]), "%2d:%02d:%02d.%03d",
- (int)(ts / (90 * 3600000)), (int)((ts / (90 * 60000)) % 60),
- (int)((ts / (90 * 1000)) % 60), (int)((ts / 90) % 1000));
-
- return buf[idx];
-}
-
-/**
-** Get ticks in ms.
-**
-** @returns ticks in ms,
-*/
-static inline uint32_t GetMsTicks(void)
-{
-#ifdef CLOCK_MONOTONIC
- struct timespec tspec;
-
- clock_gettime(CLOCK_MONOTONIC, &tspec);
- return (tspec.tv_sec * 1000) + (tspec.tv_nsec / (1000 * 1000));
-#else
- struct timeval tval;
-
- if (gettimeofday(&tval, NULL) < 0) {
- return 0;
- }
- return (tval.tv_sec * 1000) + (tval.tv_usec / 1000);
-#endif
-}
-
-/// @}
diff --git a/plex.cpp b/plex.cpp
index 524fd22..49dfc42 100644
--- a/plex.cpp
+++ b/plex.cpp
@@ -2,14 +2,6 @@
#include "SubscriptionManager.h"
#include "plex.h"
-static const char *DESCRIPTION = "Plex for VDR Plugin";
-static const char *MAINMENUENTRY = "Plex for VDR";
-
-//////////////////////////////////////////////////////////////////////////////
-
-//static char ConfigHideMainMenuEntry; ///< hide main menu entry
-//char ConfigDisableRemote; ///< disable remote during external play
-
/**
** Play a file.
**
@@ -34,11 +26,11 @@ static plexclient::PlexServer* pPlexServer;
cPlexBrowser::cPlexBrowser(const char *title, plexclient::PlexServer* pServ) :cOsdMenu(title)
{
-
dsyslog("[plex]%s:\n", __FUNCTION__);
pService = new plexclient::Plexservice(pServ);
pService->Authenticate();
pCont = pService->GetAllSections();
+ SetMenuCategory(mcRecording);
CreateMenu();
}
@@ -56,21 +48,20 @@ void cPlexBrowser::CreateMenu()
for(std::vector<plexclient::Directory>::iterator it = pCont->m_vDirectories.begin(); it != pCont->m_vDirectories.end(); ++it) {
plexclient::Directory *pDir = &(*it);
- Add(new cPlexOsdItem( pDir->m_sTitle.c_str(), pDir) );
+ Add(new cPlexOsdItem( pDir->GetTitle().c_str(), pDir) );
}
}
if(pCont && pCont->m_vVideos.size() > 0) {
for(std::vector<plexclient::Video>::iterator it = pCont->m_vVideos.begin(); it != pCont->m_vVideos.end(); ++it) {
plexclient::Video *vid = &(*it); // cast raw pointer
- Add(new cPlexOsdItem( vid->m_sTitle.c_str(), vid) );
+ Add(new cPlexOsdItem( vid->GetTitle().c_str(), vid) );
}
}
if(Count() < 1) {
Add(new cPlexOsdItem("Empty"));
}
-
Display();
}
@@ -175,6 +166,48 @@ eOSState cPlexBrowser::ProcessSelected()
}
+cPlexInfo::cPlexInfo(plexclient::Video* video) : cOsdMenu(video->GetTitle().c_str())
+{
+ cOsdMenu::Display();
+
+ Add(new cOsdItem(video->m_sSummary.c_str()));
+}
+
+eOSState cPlexInfo::ProcessKey(eKeys Key)
+{
+ switch (int(Key)) {
+ case kUp|k_Repeat:
+ case kUp:
+ case kDown|k_Repeat:
+ case kDown:
+ case kLeft|k_Repeat:
+ case kLeft:
+ case kRight|k_Repeat:
+ case kRight:
+ DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
+ cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft);
+ return osContinue;
+ case kInfo:
+ return osBack;
+ default:
+ break;
+ }
+
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kGreen:
+ cRemote::Put(Key, true);
+ case kOk:
+ return osBack;
+ default:
+ break;
+ }
+ }
+ return state;
+}
+
//////////////////////////////////////////////////////////////////////////////
// cOsdMenu
//////////////////////////////////////////////////////////////////////////////
@@ -290,7 +323,7 @@ bool cMyPlugin::Initialize(void)
{
// First Startup? Save UUID
SetupStore("UUID", Config::GetInstance().GetUUID().c_str());
-
+
plexclient::plexgdm::GetInstance().clientDetails(Config::GetInstance().GetUUID(), DESCRIPTION, "3200", "VDR", VERSION);
plexclient::plexgdm::GetInstance().Start();
plexclient::ControlServer::GetInstance().Start();
diff --git a/plex.h b/plex.h
index e37e39e..3a80729 100644
--- a/plex.h
+++ b/plex.h
@@ -23,88 +23,17 @@
#include <iterator>
#include <algorithm>
-/**
-** Device plugin remote class.
-*/
-class cMyRemote:public cRemote
-{
-public:
-
- /**
- ** Soft device remote class constructor.
- **
- ** @param name remote name
- */
- cMyRemote(const char *name):cRemote(name) {
- }
-
- /**
- ** Put keycode into vdr event queue.
- **
- ** @param code key code
- ** @param repeat flag key repeated
- ** @param release flag key released
- */
- bool Put(const char *code, bool repeat = false, bool release = false) {
- return cRemote::Put(code, repeat, release);
- }
-};
-
-/**
-** Player class.
-*/
-class cMyPlayer:public cPlayer
-{
-private:
- char *FileName; ///< file to play
-
-public:
- cMyPlayer(const char *); ///< player constructor
- virtual ~ cMyPlayer(); ///< player destructor
- void Activate(bool); ///< player attached/detached
- /// get current replay mode
- virtual bool GetReplayMode(bool &, bool &, int &);
-};
-
-/**
-** Status class.
-**
-** To get volume changes.
-*/
-class cMyStatus:public cStatus
-{
-private:
- int Volume; ///< current volume
-
-public:
- cMyStatus(void); ///< my status constructor
-
-protected:
- virtual void SetVolume(int, bool); ///< volume changed
-};
-
-/**
-** Our player control class.
-*/
-class cMyControl:public cControl
-{
-private:
- cMyPlayer * Player; ///< our player
- cSkinDisplayReplay *Display; ///< our osd display
- void ShowReplayMode(void); ///< display replay mode
- void ShowProgress(void); ///< display progress bar
- virtual void Show(void); ///< show replay control
- virtual void Hide(void); ///< hide replay control
- bool infoVisible; ///< RecordingInfo visible
- time_t timeoutShow; ///< timeout shown control
-
-public:
- cMyControl(const char *); ///< player control constructor
- virtual ~ cMyControl(); ///< player control destructor
-
- virtual eOSState ProcessKey(eKeys); ///< handle keyboard input
-};
+/// vdr-plugin version number.
+/// Makefile extracts the version number for generating the file name
+/// for the distribution archive.
+static const char *const VERSION = "0.1.0"
+#ifdef GIT_REV
+ "-GIT" GIT_REV
+#endif
+;
+static const char *const DESCRIPTION = "Plex for VDR Plugin";
+static const char *const MAINMENUENTRY = "Plex for VDR";
/*
* Plex Browser
@@ -137,60 +66,24 @@ public:
};
-/**
-** Play plugin menu class.
-*/
-class cPlayMenu:public cOsdMenu
+class cPlexInfo : public cOsdMenu
{
-private:
-public:
- cPlayMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0);
- virtual ~ cPlayMenu();
- virtual eOSState ProcessKey(eKeys);
-};
-/**
-** My device plugin OSD class.
-*/
-class cMyOsd:public cOsd
-{
public:
- static volatile char Dirty; ///< flag force redraw everything
- int OsdLevel; ///< current osd level
-
- cMyOsd(int, int, uint); ///< osd constructor
- virtual ~ cMyOsd(void); ///< osd destructor
- virtual void Flush(void); ///< commits all data to the hardware
- virtual void SetActive(bool); ///< sets OSD to be the active one
+ cPlexInfo(plexclient::Video* video);
+ virtual eOSState ProcessKey(eKeys Keys);
};
/**
-** My device plugin OSD provider class.
+** Play plugin menu class.
*/
-class cMyOsdProvider:public cOsdProvider
+class cPlayMenu:public cOsdMenu
{
private:
- static cOsd *Osd;
-
public:
- virtual cOsd * CreateOsd(int, int, uint);
- virtual bool ProvidesTrueColor(void);
- cMyOsdProvider(void);
-};
-
-/**
-** Dummy device class.
-*/
-class cMyDevice:public cDevice
-{
-public:
- cMyDevice(void);
- virtual ~ cMyDevice(void);
-
- virtual void GetOsdSize(int &, int &, double &);
-
-protected:
- virtual void MakePrimaryDevice(bool);
+ cPlayMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0);
+ virtual ~ cPlayMenu();
+ virtual eOSState ProcessKey(eKeys);
};
class cMyPlugin:public cPlugin
diff --git a/plexgdm.cpp b/plexgdm.cpp
index 9eb152f..083e00d 100644
--- a/plexgdm.cpp
+++ b/plexgdm.cpp
@@ -142,9 +142,7 @@ void plexgdm::discover()
vBuffer[sender.host().toString()] = buf;
}
}
- } catch(Poco::TimeoutException& exc) {
- dsyslog("[plex]TimeoutException in %s s%", __func__, exc.displayText().c_str());
- }
+ } catch(Poco::TimeoutException) {}
socket.close();
m_discoveryComplete = true;