diff options
author | chriszero <zerov83@gmail.com> | 2015-12-16 21:02:47 +0100 |
---|---|---|
committer | chriszero <zerov83@gmail.com> | 2015-12-16 21:02:47 +0100 |
commit | 1d624e296ee8b6a13abf0a4012a5e07b2354970e (patch) | |
tree | 5d0ef6e14e5cdf21e0f68366cee21d53626d18b5 | |
parent | 7b64bf5062f3eb6ddff5d7606e44367bd5077e4c (diff) | |
download | vdr-plugin-plex-1d624e296ee8b6a13abf0a4012a5e07b2354970e.tar.gz vdr-plugin-plex-1d624e296ee8b6a13abf0a4012a5e07b2354970e.tar.bz2 |
Early remote server playback. Please test.
-rw-r--r-- | Plexservice.cpp | 98 | ||||
-rw-r--r-- | device.cpp | 1 | ||||
-rw-r--r-- | hlsPlayer.cpp | 15 | ||||
-rw-r--r-- | plex.cpp | 3 | ||||
-rw-r--r-- | plexgdm.cpp | 5 |
5 files changed, 77 insertions, 45 deletions
diff --git a/Plexservice.cpp b/Plexservice.cpp index 3e08613..3bb1c2a 100644 --- a/Plexservice.cpp +++ b/Plexservice.cpp @@ -97,11 +97,11 @@ void Plexservice::UpdateResources() return; // Plugin is used without plex.tv login } isyslog("[plex] Updating remote resources..."); - + std::shared_ptr<MediaContainer> pContainer = GetMediaContainer("https://plex.tv/api/resources?includeHttps=1"); - + 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? @@ -138,7 +138,7 @@ std::shared_ptr<MediaContainer> Plexservice::GetSection(std::string section, boo if(putOnStack) { m_vUriStack.push(uri); } - + dsyslog("[plex] URI: %s%s", pServer->GetUri().c_str(), uri.c_str()); //Poco::Net::HTTPClientSession session(pServer->GetHost(), pServer->GetPort()); //session.sendRequest(*pRequest); @@ -189,10 +189,10 @@ std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string p if(pServer && !pServer->GetAuthToken().empty()) { pRequest->add("X-Plex-Token", pServer->GetAuthToken()); dsyslog("[plex] Using server access token"); - } - else if(!token.empty()) + } else if(!token.empty()) { pRequest->add("X-Plex-Token", token); dsyslog("[plex] Using global access token"); + } } return pRequest; @@ -201,57 +201,56 @@ std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string p std::shared_ptr<MediaContainer> Plexservice::GetMediaContainer(std::string fullUrl) { Poco::Net::HTTPClientSession* pSession = NULL; + PlexServer* pServer = NULL; + bool ownSession = false; try { Poco::URI fileuri(fullUrl); - - // Check for https - Poco::Net::Context::Ptr context = new Poco::Net::Context( - Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, // VERIFY_NONE...?! - 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - - if(fileuri.getScheme().find("https") != std::string::npos) { - pSession = new Poco::Net::HTTPSClientSession(fileuri.getHost(), fileuri.getPort(), context); + dsyslog("[plex] GetMediaContainer: %s", fullUrl.c_str()); + + if(fileuri.getHost().find("plex.tv") != std::string::npos) { + if(fileuri.getScheme().find("https") != std::string::npos) { + pSession = new Poco::Net::HTTPSClientSession(fileuri.getHost(), fileuri.getPort()); + } else { + pSession = new Poco::Net::HTTPClientSession(fileuri.getHost(), fileuri.getPort()); + } + ownSession = true; } else { - pSession = new Poco::Net::HTTPClientSession(fileuri.getHost(), fileuri.getPort()); + pServer = plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort()); + pSession = pServer->GetClientSession(); } - // > HTTPS + + // > HTTPS + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); PlexHelper::AddHttpHeader(request); - + if(Config::GetInstance().UsePlexAccount) { // Add PlexToken to Header std::string token = GetMyPlexToken(); - if(!token.empty()) + if(pServer && !pServer->GetAuthToken().empty()) { + request.add("X-Plex-Token", pServer->GetAuthToken()); + dsyslog("[plex] Using server access token"); + } else if(!token.empty()) { request.add("X-Plex-Token", token); + dsyslog("[plex] Using global access token"); + } } pSession->sendRequest(request); Poco::Net::HTTPResponse response; std::istream &rs = pSession->receiveResponse(response); - + //Poco::StreamCopier::copyStream(rs, std::cout); - - std::shared_ptr<MediaContainer> pAllsections; - - // omit creating a server when talking to plex.tv - if(fileuri.getHost().find("plex.tv") != std::string::npos) { - pAllsections = std::shared_ptr<MediaContainer>(new MediaContainer(&rs)); - } - else { - pAllsections = std::shared_ptr<MediaContainer>(new MediaContainer(&rs, plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort()))); - } - - pSession->abort(); - delete pSession; + std::shared_ptr<MediaContainer> pAllsections = std::shared_ptr<MediaContainer>(new MediaContainer(&rs, pServer)); + if (ownSession) delete pSession; return pAllsections; } catch (Poco::Net::NetException &exc) { std::cout << exc.displayText() << std::endl; - delete pSession; return 0; } } @@ -268,7 +267,12 @@ std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, Plex PlexServer* pSrv = server ? server : video->m_pServer; std::stringstream params; params << "/video/:/transcode/universal/start.m3u8?"; - params << "path=" << encode(pSrv->GetUri() + video->m_sKey); + // Force set localhost and http + Poco::URI pathUri(pSrv->GetUri()+video->m_sKey); + pathUri.setHost("127.0.0.1"); + pathUri.setScheme("http"); + + params << "path=" << encode(pathUri.toString()); params << "&mediaIndex=0"; params << "&partIndex=0"; params << "&protocol=hls"; @@ -276,23 +280,37 @@ std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, Plex params << "&fastSeek=0"; params << "&directPlay=0"; params << "&directStream=1"; - params << "&maxVideoBitrate=20000"; params << "&subtitles=burn"; //params << "&subtitleSize=90"; //params << "&skipSubtitles=1"; //params << "&audioBoost=100"; - params << "&videoResolution=1920x1080"; - params << "&videoQuality=100"; - params << "&session=" << encode(Config::GetInstance().GetUUID()); // TODO: generate Random SessionID + if(Config::GetInstance().UsePlexAccount) { + if(!pSrv->GetAuthToken().empty()) { + params << "&X-Plex-Token=" << pSrv->GetAuthToken(); + } + } + + if(pSrv->IsLocal()) { + params << "&videoResolution=1920x1080"; + params << "&maxVideoBitrate=20000"; + params << "&videoQuality=100"; + } else { + params << "&videoResolution=1280x720"; + params << "&maxVideoBitrate=8000"; + params << "&videoQuality=100"; + } + + params << "&session=" << encode(Config::GetInstance().GetUUID()); // TODO: generate Random SessionID + params << "&includeCodecs=1"; params << "©ts=1"; - + if(Config::GetInstance().UseAc3) { params << "&X-Plex-Client-Profile-Extra="; if(Config::GetInstance().UseAc3) params << encode("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)"); @@ -32,7 +32,6 @@ Device::Device(Poco::XML::Node* pNode, MediaContainer* parent) NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL); Poco::XML::Node* pChildNode = it.nextNode(); - std::cout << "Found Device "; while(pChildNode) { if(Poco::icompare(pChildNode->nodeName(), "Device") == 0) { diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp index 70ce3fa..1baa75a 100644 --- a/hlsPlayer.cpp +++ b/hlsPlayer.cpp @@ -3,6 +3,7 @@ #include <vdr/tools.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPSClientSession.h> #include <Poco/Exception.h> #include <pcrecpp.h> @@ -10,6 +11,7 @@ #include <fstream> #include "Plexservice.h" +#include "plexgdm.h" #include "XmlObject.h" #include "Media.h" #include "Stream.h" @@ -137,6 +139,7 @@ bool cHlsSegmentLoader::LoadIndexList(void) if(responseStart.getStatus() != 200) { esyslog("[plex]%s Response Not Valid", __FUNCTION__); + Poco::StreamCopier::copyStream(indexFile, std::cout); return res; } m_indexParser = cM3u8Parser(); @@ -175,6 +178,7 @@ 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); @@ -184,6 +188,7 @@ bool cHlsSegmentLoader::LoadStartList(void) if(responseStart.getStatus() != 200) { esyslog("[plex]%s Response Not Valid", __FUNCTION__); + Poco::StreamCopier::copyStream(startFile, std::cout); return res; } @@ -295,8 +300,14 @@ void cHlsSegmentLoader::CloseConnection(void) bool cHlsSegmentLoader::ConnectToServer(void) { dsyslog("[plex]%s", __FUNCTION__); - if(!m_pClientSession) - m_pClientSession = new Poco::Net::HTTPClientSession(m_startUri.getHost(), m_startUri.getPort()); + 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(); } @@ -127,9 +127,8 @@ bool cMyPlugin::Initialize(void) plexclient::plexgdm::GetInstance().clientDetails(Config::GetInstance().GetUUID(), Config::GetInstance().GetHostname(), "3200", DESCRIPTION, VERSION); plexclient::plexgdm::GetInstance().Start(); plexclient::ControlServer::GetInstance().Start(); - plexclient::Plexservice::UpdateResources(); cPictureCache::GetInstance().Start(); - + return true; } diff --git a/plexgdm.cpp b/plexgdm.cpp index a3b3de2..dae0df3 100644 --- a/plexgdm.cpp +++ b/plexgdm.cpp @@ -2,6 +2,7 @@ #include "plexgdm.h" #include "Config.h" #include <ctime> +#include "Plexservice.h" namespace plexclient { @@ -58,6 +59,10 @@ std::string plexgdm::getClientDetails() void plexgdm::Action() { + + // Get remote Resources + Plexservice::UpdateResources(); + if(Config::GetInstance().UseConfiguredServer) { // Adds a Server to vector GetServer(Config::GetInstance().s_serverHost, Config::GetInstance().ServerPort); |