diff options
-rw-r--r-- | Config.cpp | 2 | ||||
-rw-r--r-- | Config.h | 1 | ||||
-rw-r--r-- | Media.cpp | 10 | ||||
-rw-r--r-- | Media.h | 8 | ||||
-rw-r--r-- | MediaContainer.h | 2 | ||||
-rw-r--r-- | PVideo.cpp | 7 | ||||
-rw-r--r-- | PVideo.h | 3 | ||||
-rw-r--r-- | PlexHTTPRequestHandler.cpp | 2 | ||||
-rw-r--r-- | Plexservice.cpp | 8 | ||||
-rw-r--r-- | Stream.cpp | 26 | ||||
-rw-r--r-- | Stream.h | 51 | ||||
-rw-r--r-- | SubscriptionManager.h | 1 | ||||
-rw-r--r-- | XmlObject.cpp | 16 | ||||
-rw-r--r-- | XmlObject.h | 2 | ||||
-rw-r--r-- | hlsPlayer.cpp | 134 | ||||
-rw-r--r-- | hlsPlayer.h | 12 | ||||
-rw-r--r-- | hlsPlayerControl.cpp | 20 | ||||
-rw-r--r-- | hlsPlayerControl.h | 4 | ||||
-rw-r--r-- | plex.cpp | 18 | ||||
-rw-r--r-- | plex.h | 203 |
20 files changed, 357 insertions, 173 deletions
@@ -67,7 +67,6 @@ cMyMenuSetupPage::cMyMenuSetupPage(void) strn0cpy(Uuid, Config::GetInstance().GetUUID().c_str(), STRING_SIZE); Add(new cMenuEditBoolItem(tr("Hide main menu entry"), (int*)&Config::GetInstance().HideMainMenuEntry, trVDR("no"), trVDR("yes"))); - Add(new cMenuEditBoolItem(tr("Disable remote"), (int*)&Config::GetInstance().DisableRemote, trVDR("no"), trVDR("yes"))); Add(new cMenuEditStrItem(tr("Plex Username"), Username, STRING_SIZE)); Add(new cMenuEditStrItem(tr("Plex Password"), Password, STRING_SIZE)); cMenuEditStrItem* devUUID = new cMenuEditStrItem(tr("Current UUID"), Uuid, STRING_SIZE); @@ -84,7 +83,6 @@ void cMyMenuSetupPage::Store(void) Config::GetInstance().s_password = std::string(Password); SetupStore("HideMainMenuEntry", Config::GetInstance().HideMainMenuEntry); - SetupStore("DisableRemote", Config::GetInstance().DisableRemote); SetupStore("Username", Config::GetInstance().s_username.c_str()); SetupStore("Password", Config::GetInstance().s_password.c_str()); SetupStore("UUID", Config::GetInstance().GetUUID().c_str()); @@ -39,7 +39,6 @@ public: std::string s_password; bool HideMainMenuEntry; - bool DisableRemote; std::string GetUUID(); void SetUUID(const char* uuid); @@ -30,7 +30,6 @@ Media::Media(Poco::XML::Node* pNode) } 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")); @@ -41,14 +40,11 @@ Media::Media(Poco::XML::Node* pNode) pAttribs->release(); } + if(Poco::icompare(pChildNode->nodeName(), "Stream") == 0) { + m_vStreams.push_back(Stream(pChildNode)); + } pChildNode = it.nextNode(); } } -Media::~Media() -{ } - - -} - @@ -16,6 +16,7 @@ #include <iostream> #include "XmlObject.h" // Base class: model::XmlObject +#include "Stream.h" using Poco::XML::DOMParser; using Poco::XML::Document; @@ -30,9 +31,9 @@ namespace plexclient class Media: XmlObject { -public: + public: + Media() {}; Media(Poco::XML::Node* pNode); - ~Media(); public: std::string m_sVideoResolution; @@ -54,7 +55,8 @@ public: std::string m_sPartFile; long m_lPartSize; std::string m_sPartContainer; - + + std::vector<Stream> m_vStreams; }; } diff --git a/MediaContainer.h b/MediaContainer.h index 5d5c722..aaf0d9a 100644 --- a/MediaContainer.h +++ b/MediaContainer.h @@ -36,8 +36,6 @@ class MediaContainer: XmlObject public: MediaContainer(std::istream *response, PlexServer* Server); - ~MediaContainer(); - protected: @@ -34,7 +34,7 @@ Video::Video(Poco::XML::Node* pNode, PlexServer* Server) pAttribs->release(); } else if(Poco::icompare(pChildNode->nodeName(), "Media") == 0) { - m_pMedia = new Media(pChildNode); + m_Media = Media(pChildNode); } else if(Poco::icompare(pChildNode->nodeName(), "Genre") == 0) { m_vGenre.push_back(GetNodeValue(pChildNode)); } else if(Poco::icompare(pChildNode->nodeName(), "Writer") == 0) { @@ -52,9 +52,4 @@ Video::Video(Poco::XML::Node* pNode, PlexServer* Server) } } -Video::~Video() -{ -} - - } @@ -34,7 +34,6 @@ class Video: XmlObject { public: Video(Poco::XML::Node* pNode, PlexServer* Server); - ~Video(); public: int m_iRatingKey; @@ -60,7 +59,7 @@ public: std::vector<std::string> m_vCountry; std::vector<std::string> m_vRole; std::string m_sCollection; - Media *m_pMedia; + Media m_Media; PlexServer* m_pServer; }; diff --git a/PlexHTTPRequestHandler.cpp b/PlexHTTPRequestHandler.cpp index 7fc3415..d6c8ad3 100644 --- a/PlexHTTPRequestHandler.cpp +++ b/PlexHTTPRequestHandler.cpp @@ -141,7 +141,7 @@ void PlayerRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, std::cout << "FullUrl: " << fullUrl << std::endl; MediaContainer *pCont = Plexservice::GetMediaContainer(fullUrl); - std::string filePath = pCont->m_vVideos[0].m_pMedia->m_sPartKey; + std::string filePath = pCont->m_vVideos[0].m_Media.m_sPartKey; Poco::URI fileuri(fullUrl); fileuri.setPath(filePath); diff --git a/Plexservice.cpp b/Plexservice.cpp index ce803c3..f156550 100644 --- a/Plexservice.cpp +++ b/Plexservice.cpp @@ -207,11 +207,11 @@ MediaContainer* Plexservice::GetMediaContainer(std::string fullUrl) //std::cout << "URI: " << session->getHost() << "[" << pRequest->getURI() << "]" << std::endl; + MediaContainer* pAllsections = new MediaContainer(&rs, new PlexServer(fileuri.getHost(), fileuri.getPort())); + delete pRequest; delete session; - - MediaContainer* pAllsections = new MediaContainer(&rs, new PlexServer(fileuri.getHost(), fileuri.getPort())); - //Poco::StreamCopier::copyStream(rs, std::cout); + return pAllsections; } @@ -319,7 +319,7 @@ std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, Plex params << "&videoQuality=100"; params << "&session=" << encode(Config::GetInstance().GetUUID()); // TODO: generate Random SessionID - + return pSrv->GetUri() + params.str(); } diff --git a/Stream.cpp b/Stream.cpp new file mode 100644 index 0000000..1611f72 --- /dev/null +++ b/Stream.cpp @@ -0,0 +1,26 @@ +#include "Stream.h" + +namespace plexclient +{ + +Stream::Stream(Poco::XML::Node* pNode) +{ + if(Poco::icompare(pNode->nodeName(), "Stream") == 0) { + + Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes(); + + 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")); + + pAttribs->release(); + } +} + +} // namespace diff --git a/Stream.h b/Stream.h new file mode 100644 index 0000000..f8a392c --- /dev/null +++ b/Stream.h @@ -0,0 +1,51 @@ +#ifndef STREAM_H +#define STREAM_H + + +#include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/NamedNodeMap.h> +#include <Poco/DOM/NodeIterator.h> +#include <Poco/DOM/NodeFilter.h> +#include <Poco/DOM/NodeList.h> +#include <Poco/DOM/AutoPtr.h> +#include <Poco/Exception.h> +#include <Poco/Timestamp.h> +#include <Poco/String.h> + +#include <vector> +#include <iostream> + +#include "XmlObject.h" // Base class: model::XmlObject + +using Poco::XML::DOMParser; +using Poco::XML::Document; +using Poco::XML::NodeIterator; +using Poco::XML::NodeFilter; +using Poco::XML::Node; +using Poco::XML::AutoPtr; +using Poco::Exception; + +namespace plexclient +{ + +class Stream: XmlObject +{ +public: + Stream(Poco::XML::Node* pNode); + +public: + 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; +}; + +} + +#endif // STREAM_H diff --git a/SubscriptionManager.h b/SubscriptionManager.h index b3f7f33..9d68e3c 100644 --- a/SubscriptionManager.h +++ b/SubscriptionManager.h @@ -26,7 +26,6 @@ class Subscriber virtual std::string to_string() { return "Subscriber-> Host: " + m_sHost + "; Port: " + std::string(itoa(m_iPort)) + "; Uuid:" + m_sUuid + "; CmdID:" + std::string(itoa(m_iCommandId)); - return ""; } private: diff --git a/XmlObject.cpp b/XmlObject.cpp index a9c0bb4..09db02d 100644 --- a/XmlObject.cpp +++ b/XmlObject.cpp @@ -87,4 +87,20 @@ MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node* pNode) return type; } +StreamType XmlObject::GetNodeValueAsStreamType(Poco::XML::Node* pNode) +{ + StreamType type = sUNDEF; + + if(pNode != 0) { + int iType = GetNodeValueAsInt(pNode); + switch(iType) { + case 1: type = sVIDEO; break; + case 2: type = sAUDIO; break; + case 3: type = sSUBTITLE; break; + default: type = sUNDEF; break; + } + } + return type; +} + } diff --git a/XmlObject.h b/XmlObject.h index db9969a..16b63b7 100644 --- a/XmlObject.h +++ b/XmlObject.h @@ -12,6 +12,7 @@ namespace plexclient { enum MediaType {UNDEF = 0, PHOTO, MOVIE, MUSIC, SHOW, SEASON}; +enum StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3}; class XmlObject { @@ -25,6 +26,7 @@ protected: static bool GetNodeValueAsBool(Poco::XML::Node* pNode); static Poco::Timestamp GetNodeValueAsTimeStamp(Poco::XML::Node* pNode); static MediaType GetNodeValueAsMediaType(Poco::XML::Node* pNode); + static StreamType GetNodeValueAsStreamType(Poco::XML::Node* pNode); private: }; diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp index 3f90750..9245efb 100644 --- a/hlsPlayer.cpp +++ b/hlsPlayer.cpp @@ -1,5 +1,6 @@ #include "hlsPlayer.h" +#include <sys/time.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> #include <Poco/Exception.h> @@ -8,6 +9,9 @@ #include <pcrecpp.h> #include "Plexservice.h" +#include "XmlObject.h" +#include "Media.h" +#include "Stream.h" static cMutex hlsMutex; @@ -18,7 +22,7 @@ cHlsSegmentLoader::cHlsSegmentLoader(std::string startm3u8) m_newList = false; m_bufferFilled = false; m_lastLoadedSegment = 0; - m_segmentsToBuffer = 3; + m_segmentsToBuffer = 2; m_pBuffer = new uchar[8192]; // Initialize members @@ -54,9 +58,9 @@ void cHlsSegmentLoader::Action(void) if(!LoadLists()) return; int estSize = EstimateSegmentSize(); - m_ringBufferSize = MEGABYTE(estSize*3); + m_ringBufferSize = MEGABYTE(estSize*m_segmentsToBuffer); - isyslog("[plex]%s Create Ringbuffer %d MB", __FUNCTION__, estSize*3); + isyslog("[plex]%s Create Ringbuffer %d MB", __FUNCTION__, estSize*m_segmentsToBuffer); m_pRingbuffer = new cRingBufferLinear(m_ringBufferSize, 2*TS_SIZE); @@ -128,9 +132,9 @@ bool cHlsSegmentLoader::LoadIndexList(void) m_segmentUriPart = path.substr(0, path.find_last_of("/")+1); } if(m_indexParser.TargetDuration > 3) { - m_segmentsToBuffer = 1; - } else { m_segmentsToBuffer = 2; + } else { + m_segmentsToBuffer = 3; } } return res; @@ -174,7 +178,11 @@ int cHlsSegmentLoader::EstimateSegmentSize() int len = m_indexParser.TargetDuration; double estSize = (bandw) * len; - estSize = max(estSize, 1.0); // default + estSize = max(estSize, 1.0); + // default + if(estSize <= 1) { + estSize = 32; + } return ceil(estSize); } @@ -322,8 +330,11 @@ cHlsPlayer::cHlsPlayer(std::string startm3u8, plexclient::Video* Video) m_pSegmentLoader = new cHlsSegmentLoader(startm3u8); m_pVideo = Video; m_timeOffset = 0; + m_jumpOffset = 0; + m_tTimeSum = 0; m_doJump = false; m_isBuffering = false; + AudioIndexOffset = 1000; // Just a magic number } cHlsPlayer::~cHlsPlayer() @@ -332,6 +343,21 @@ cHlsPlayer::~cHlsPlayer() m_pSegmentLoader = NULL; } +void cHlsPlayer::SetAudioAndSubtitleTracks(void) +{ + //DeviceClrAvailableTracks(); + DeviceSetAvailableTrack(ttDolby, 0, 0, "Current"); + if(m_pVideo->m_Media.m_vStreams.size() > 0) { + std::vector<plexclient::Stream> streams = m_pVideo->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::sAUDIO) { + DeviceSetAvailableTrack(ttDolby, pStream->m_iIndex, pStream->m_iIndex + AudioIndexOffset, pStream->m_sLanguage.c_str(), pStream->m_sCodec.c_str()); + } + } + } +} + void cHlsPlayer::Action(void) { @@ -344,12 +370,21 @@ void cHlsPlayer::Action(void) DeviceFreeze(); m_doJump = false; + m_bFirstPlay = true; std::string uri = plexclient::Plexservice::GetUniversalTranscodeUrl(m_pVideo, 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(); + m_bFirstPlay = false; + } + CountPlayedSeconds(); } else { // Pause cCondWait::SleepMs(3); @@ -359,6 +394,7 @@ void cHlsPlayer::Action(void) bool cHlsPlayer::DoPlay(void) { + bool res = false; cPoller Poller; if(DevicePoll(Poller, 10)) { hlsMutex.Lock(); @@ -372,6 +408,7 @@ bool cHlsPlayer::DoPlay(void) if(bytesAvaliable >= TS_SIZE) { int playedBytes = PlayTs(toPlay, TS_SIZE, false); m_pSegmentLoader->m_pRingbuffer->Del(playedBytes); + res = true; } else { // Pause & Buffer break; @@ -379,7 +416,7 @@ bool cHlsPlayer::DoPlay(void) } hlsMutex.Unlock(); } - return true; + return res; } void cHlsPlayer::Activate(bool On) @@ -391,12 +428,10 @@ void cHlsPlayer::Activate(bool On) } } -bool cHlsPlayer::GetIndex(int& Current, int& Total, bool SnapToIFrame) +bool cHlsPlayer::GetIndex(int& Current, int& Total, bool SnapToIFrame __attribute__((unused))) { - long stc = DeviceGetSTC(); - Total = m_pVideo->m_pMedia->m_lDuration / 1000 * 25;//FramesPerSecond(); // milliseconds - Current = stc / (100 * 1000) * FramesPerSecond(); // 100ns per Tick - Current += m_timeOffset; // apply offset + Total = m_pVideo->m_Media.m_lDuration / 1000 * FramesPerSecond(); // milliseconds + Current = GetPlayedSeconds() * FramesPerSecond(); return true; } @@ -446,18 +481,12 @@ void cHlsPlayer::Stop(void) double cHlsPlayer::FramesPerSecond(void) { - return m_pVideo->m_pMedia->m_VideoFrameRate ? m_pVideo->m_pMedia->m_VideoFrameRate : DEFAULTFRAMESPERSECOND; + return m_pVideo->m_Media.m_VideoFrameRate ? m_pVideo->m_Media.m_VideoFrameRate : DEFAULTFRAMESPERSECOND; } void cHlsPlayer::JumpRelative(int seconds) { - long stc = DeviceGetSTC(); - if(stc > 0) { - int current = stc / (100 * 1000); - JumpTo(current + seconds); - } else { - JumpTo(m_jumpOffset + seconds); - } + JumpTo(GetPlayedSeconds() + seconds); } void cHlsPlayer::JumpTo(int seconds) @@ -468,3 +497,68 @@ void cHlsPlayer::JumpTo(int seconds) m_jumpOffset = seconds; m_doJump = true; } + +void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tTrackId* TrackId) +{ + dsyslog("[plex]%s %d %s", __FUNCTION__, TrackId->id, TrackId->language); + // Check if stream availiable + int streamId = 0; + if(m_pVideo->m_Media.m_vStreams.size() > 0) { + std::vector<plexclient::Stream> streams = m_pVideo->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::sAUDIO && pStream->m_iIndex + AudioIndexOffset == TrackId->id) { + streamId = pStream->m_iID; + break; + } + } + } + // Then do the request + if(streamId > 0) { + Poco::Net::HTTPClientSession session(m_pVideo->m_pServer->GetIpAdress(), m_pVideo->m_pServer->GetPort()); + + std::string uri = "/library/parts/" + std::string(itoa(m_pVideo->m_Media.m_iPartId)) + "?audioStreamID=" + std::string(itoa(streamId)); + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri); + session.sendRequest(req); + + Poco::Net::HTTPResponse resp; + session.receiveResponse(resp); + + if(resp.getStatus() == 200) { + 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); + } + } +} + +unsigned long long cHlsPlayer::MsNow(void) +{ + static timeval tv; + gettimeofday(&tv, 0); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +int cHlsPlayer::GetPlayedSeconds(void) +{ + return m_timeOffset + (m_tTimeSum / 1000); +} + +void cHlsPlayer::CountPlayedSeconds(void) +{ + if (playMode == pmPlay) { + unsigned long long tTmp = MsNow(); + m_tTimeSum += (tTmp - m_tLastTime); + m_tLastTime = tTmp; + } + else { + m_tLastTime = MsNow(); + } +} + +void cHlsPlayer::ResetPlayedSeconds(void) +{ + m_tTimeSum = 0; + m_tLastTime = MsNow(); +} diff --git a/hlsPlayer.h b/hlsPlayer.h index a7663f5..49561d8 100644 --- a/hlsPlayer.h +++ b/hlsPlayer.h @@ -68,6 +68,7 @@ public: class cHlsPlayer : public cPlayer, cThread { private: + int AudioIndexOffset; cHlsSegmentLoader* m_pSegmentLoader; plexclient::Video* m_pVideo; @@ -80,12 +81,19 @@ private: int m_actualSegment; int m_actualTime; long m_lastValidSTC; + + unsigned long long m_tLastTime; + unsigned long long m_tTimeSum; + bool m_bFirstPlay; enum ePlayModes { pmPlay, pmPause }; ePlayModes playMode; virtual void Activate(bool On); - + unsigned long long MsNow(void); + int GetPlayedSeconds(void); + void CountPlayedSeconds(void); + void ResetPlayedSeconds(void); protected: void Action(void); @@ -100,12 +108,14 @@ public: 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 b4b93df..f4e1330 100644 --- a/hlsPlayerControl.cpp +++ b/hlsPlayerControl.cpp @@ -4,6 +4,8 @@ #include "PlexServer.h" #include "Plexservice.h" +#include "MediaContainer.h" +#include "PVideo.h" // static cControl* cHlsPlayerControl::Create(plexclient::Video* Video) @@ -11,17 +13,22 @@ cControl* cHlsPlayerControl::Create(plexclient::Video* Video) if(!Video->m_pServer) return NULL; - std::string transcodeUri = plexclient::Plexservice::GetUniversalTranscodeUrl(Video); + // get Metadata + std::string uri = Video->m_pServer->GetUri() + Video->m_sKey; + plexclient::MediaContainer *pmcontainer = plexclient::Plexservice::GetMediaContainer(uri); + + std::cout << "Video Size" << pmcontainer->m_vVideos.size() << " Video: " << pmcontainer->m_vVideos[0].m_sKey << std::endl; + std::string transcodeUri = plexclient::Plexservice::GetUniversalTranscodeUrl(&pmcontainer->m_vVideos[0]); - cHlsPlayerControl* playerControl = new cHlsPlayerControl(new cHlsPlayer(transcodeUri, Video), Video); - playerControl->m_title = Video->m_sTitle; + cHlsPlayerControl* playerControl = new cHlsPlayerControl(new cHlsPlayer(transcodeUri, &pmcontainer->m_vVideos[0]), pmcontainer); + playerControl->m_title = pmcontainer->m_vVideos[0].m_sTitle; return playerControl; } -cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer* Player, plexclient::Video* Video) :cControl(Player) +cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer* Player, plexclient::MediaContainer* Container) :cControl(Player) { player = Player; - m_pVideo = Video; + m_pVideo = &Container->m_vVideos[0]; //m_title = title; displayReplay = NULL; @@ -31,11 +38,12 @@ cHlsPlayerControl::cHlsPlayerControl(cHlsPlayer* Player, plexclient::Video* Vide lastSpeed = -2; // an invalid value timeoutShow = 0; - cStatus::MsgReplaying(this, m_title.c_str(), Video->m_pMedia->m_sPartFile.c_str(), true); + cStatus::MsgReplaying(this, m_title.c_str(), m_pVideo->m_Media.m_sPartFile.c_str(), true); } cHlsPlayerControl::~cHlsPlayerControl() { + //delete m_pMediaContainer; } cString cHlsPlayerControl::GetHeader(void) diff --git a/hlsPlayerControl.h b/hlsPlayerControl.h index 8eb8bc6..2f7347b 100644 --- a/hlsPlayerControl.h +++ b/hlsPlayerControl.h @@ -5,12 +5,14 @@ #include <vdr/tools.h> #include "hlsPlayer.h" +#include "MediaContainer.h" #include "PVideo.h" class cHlsPlayerControl : public cControl { private: static volatile int active; + plexclient::MediaContainer* m_pMediaContainer; plexclient::Video* m_pVideo; cHlsPlayer* player; std::string m_title; @@ -31,7 +33,7 @@ protected: public: static cControl* Create(plexclient::Video* Video); - cHlsPlayerControl(cHlsPlayer* Player, plexclient::Video* Video); + cHlsPlayerControl(cHlsPlayer* Player, plexclient::MediaContainer* Container); virtual ~cHlsPlayerControl(); virtual void Show(void); @@ -2,10 +2,13 @@ #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 +//static char ConfigHideMainMenuEntry; ///< hide main menu entry +//char ConfigDisableRemote; ///< disable remote during external play /** ** Play a file. @@ -273,14 +276,6 @@ const char *cMyPlugin::Description(void) } /** -** Process the command line arguments. -*/ -bool cMyPlugin::ProcessArgs(int argc, char *argv[]) -{ - return true; -} - -/** ** Start any background activities the plugin shall perform. */ bool cMyPlugin::Initialize(void) @@ -308,7 +303,7 @@ bool cMyPlugin::Initialize(void) */ const char *cMyPlugin::MainMenuEntry(void) { - return ConfigHideMainMenuEntry ? NULL : MAINMENUENTRY; + return Config::GetInstance().HideMainMenuEntry ? NULL : MAINMENUENTRY; } /** @@ -361,7 +356,6 @@ bool cMyPlugin::SetupParse(const char *name, const char *value) //dsyslog("[plex]%s: '%s' = '%s'\n", __FUNCTION__, name, value); if (strcasecmp(name, "HideMainMenuEntry") == 0) Config::GetInstance().HideMainMenuEntry = atoi(value) ? true : false; - else if (strcasecmp(name, "DisableRemote") == 0) Config::GetInstance().DisableRemote = 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); @@ -23,35 +23,31 @@ #include <iterator> #include <algorithm> -static const char *DESCRIPTION = "Plex for VDR Plugin"; -static const char *MAINMENUENTRY = "Plex for VDR"; - /** ** 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); - } +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); + } }; /** @@ -59,15 +55,15 @@ class cMyRemote:public cRemote */ 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 &); +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 &); }; /** @@ -77,14 +73,14 @@ class cMyPlayer:public cPlayer */ class cMyStatus:public cStatus { - private: - int Volume; ///< current volume +private: + int Volume; ///< current volume - public: - cMyStatus(void); ///< my status constructor +public: + cMyStatus(void); ///< my status constructor - protected: - virtual void SetVolume(int, bool); ///< volume changed +protected: + virtual void SetVolume(int, bool); ///< volume changed }; /** @@ -92,26 +88,26 @@ class cMyStatus:public cStatus */ 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 +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 }; /* - * Plex Browser + * Plex Browser */ class cPlexBrowser :public cOsdMenu @@ -124,21 +120,21 @@ private: 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(); - + /// Create a browser menu for current directory + void CreateMenu(); + /// Handle menu level up + eOSState LevelUp(void); + /// Handle menu item selection + eOSState ProcessSelected(); + public: cPlexBrowser(const char *title, plexclient::PlexServer* pServ); ~cPlexBrowser(); /// File browser destructor - //virtual ~ cPlexBrowser(); - /// Process keyboard input - virtual eOSState ProcessKey(eKeys); - + //virtual ~ cPlexBrowser(); + /// Process keyboard input + virtual eOSState ProcessKey(eKeys); + }; /** @@ -146,11 +142,11 @@ public: */ class cPlayMenu:public cOsdMenu { - private: - public: - cPlayMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0); - virtual ~ cPlayMenu(); - virtual eOSState ProcessKey(eKeys); +private: +public: + cPlayMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0); + virtual ~ cPlayMenu(); + virtual eOSState ProcessKey(eKeys); }; /** @@ -158,14 +154,14 @@ class cPlayMenu:public cOsdMenu */ 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 +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 }; /** @@ -173,13 +169,13 @@ class cMyOsd:public cOsd */ class cMyOsdProvider:public cOsdProvider { - private: - static cOsd *Osd; +private: + static cOsd *Osd; - public: - virtual cOsd * CreateOsd(int, int, uint); - virtual bool ProvidesTrueColor(void); - cMyOsdProvider(void); +public: + virtual cOsd * CreateOsd(int, int, uint); + virtual bool ProvidesTrueColor(void); + cMyOsdProvider(void); }; /** @@ -187,31 +183,30 @@ class cMyOsdProvider:public cOsdProvider */ class cMyDevice:public cDevice { - public: - cMyDevice(void); - virtual ~ cMyDevice(void); +public: + cMyDevice(void); + virtual ~ cMyDevice(void); - virtual void GetOsdSize(int &, int &, double &); + virtual void GetOsdSize(int &, int &, double &); - protected: - virtual void MakePrimaryDevice(bool); +protected: + virtual void MakePrimaryDevice(bool); }; class cMyPlugin:public cPlugin { - public: - cMyPlugin(void); - virtual ~ cMyPlugin(void); - virtual const char *Version(void); - virtual const char *Description(void); - virtual bool ProcessArgs(int, char *[]); - virtual bool Initialize(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 *); +public: + cMyPlugin(void); + virtual ~ cMyPlugin(void); + virtual const char *Version(void); + virtual const char *Description(void); + virtual bool Initialize(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 *); }; -#endif
\ No newline at end of file +#endif |