Skip to content

Commit

Permalink
Merge pull request xbmc#2325 from da-anda/instant-livetv
Browse files Browse the repository at this point in the history
[PVR] add possibility to start liveTV playback via cAction and keymaps.
  • Loading branch information
Lars Op den Kamp committed Mar 9, 2013
2 parents 1dffc6d + 5cd5807 commit 47e93ba
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 8 deletions.
2 changes: 1 addition & 1 deletion language/English/strings.po
Expand Up @@ -6548,7 +6548,7 @@ msgid "Already started recording on this channel"
msgstr "" msgstr ""


msgctxt "#19035" msgctxt "#19035"
msgid "This channel cannot be played. Check the log for details." msgid "%s could not be played. Check the log for details."
msgstr "" msgstr ""


msgctxt "#19036" msgctxt "#19036"
Expand Down
4 changes: 4 additions & 0 deletions xbmc/Application.cpp
Expand Up @@ -2746,6 +2746,10 @@ bool CApplication::OnAction(const CAction &action)
return true; return true;
} }


// forward action to g_PVRManager and break if it was able to handle it
if (g_PVRManager.OnAction(action))
return true;

if (IsPlaying()) if (IsPlaying())
{ {
// forward channel switches to the player - he knows what to do // forward channel switches to the player - he knows what to do
Expand Down
3 changes: 3 additions & 0 deletions xbmc/guilib/Key.h
Expand Up @@ -280,6 +280,9 @@
#define ACTION_CHANNEL_DOWN 185 #define ACTION_CHANNEL_DOWN 185
#define ACTION_NEXT_CHANNELGROUP 186 #define ACTION_NEXT_CHANNELGROUP 186
#define ACTION_PREVIOUS_CHANNELGROUP 187 #define ACTION_PREVIOUS_CHANNELGROUP 187
#define ACTION_PVR_PLAY 188
#define ACTION_PVR_PLAY_TV 189
#define ACTION_PVR_PLAY_RADIO 190


#define ACTION_TOGGLE_FULLSCREEN 199 // switch 2 desktop resolution #define ACTION_TOGGLE_FULLSCREEN 199 // switch 2 desktop resolution
#define ACTION_TOGGLE_WATCHED 200 // Toggle watched status (videos) #define ACTION_TOGGLE_WATCHED 200 // Toggle watched status (videos)
Expand Down
3 changes: 3 additions & 0 deletions xbmc/input/ButtonTranslator.cpp
Expand Up @@ -223,6 +223,9 @@ static const ActionMapping actions[] =
{"channeldown" , ACTION_CHANNEL_DOWN}, {"channeldown" , ACTION_CHANNEL_DOWN},
{"previouschannelgroup" , ACTION_PREVIOUS_CHANNELGROUP}, {"previouschannelgroup" , ACTION_PREVIOUS_CHANNELGROUP},
{"nextchannelgroup" , ACTION_NEXT_CHANNELGROUP}, {"nextchannelgroup" , ACTION_NEXT_CHANNELGROUP},
{"playpvr" , ACTION_PVR_PLAY},
{"playpvrtv" , ACTION_PVR_PLAY_TV},
{"playpvrradio" , ACTION_PVR_PLAY_RADIO},


// Mouse actions // Mouse actions
{"leftclick" , ACTION_MOUSE_LEFT_CLICK}, {"leftclick" , ACTION_MOUSE_LEFT_CLICK},
Expand Down
111 changes: 110 additions & 1 deletion xbmc/pvr/PVRManager.cpp
Expand Up @@ -53,6 +53,7 @@
#include "timers/PVRTimers.h" #include "timers/PVRTimers.h"
#include "interfaces/AnnouncementManager.h" #include "interfaces/AnnouncementManager.h"
#include "addons/AddonInstaller.h" #include "addons/AddonInstaller.h"
#include "guilib/Key.h"


using namespace std; using namespace std;
using namespace MUSIC_INFO; using namespace MUSIC_INFO;
Expand Down Expand Up @@ -1023,6 +1024,76 @@ bool CPVRManager::StartPlayback(const CPVRChannel *channel, bool bPreview /* = f
return true; return true;
} }


bool CPVRManager::StartPlayback(PlaybackType type /* = PlaybackTypeAny */)
{
bool bIsRadio(false);
bool bReturn(false);
bool bIsPlaying(false);
CFileItemPtr channel;

// check if the desired PlaybackType is already playing,
// and if not, try to grab the last played channel of this type
switch (type)
{
case PlaybackTypeRadio:
if (IsPlayingRadio())
bIsPlaying = true;
else
channel = m_channelGroups->GetGroupAllRadio()->GetLastPlayedChannel();
bIsRadio = true;
break;

case PlaybackTypeTv:
if (IsPlayingTV())
bIsPlaying = true;
else
channel = m_channelGroups->GetGroupAllTV()->GetLastPlayedChannel();
break;

default:
if (IsPlaying())
bIsPlaying = true;
else
channel = m_channelGroups->GetLastPlayedChannel();
}

// we're already playing? Then nothing to do
if (bIsPlaying)
return true;

// if we have a last played channel, start playback
if (channel && channel->HasPVRChannelInfoTag())
{
bReturn = StartPlayback(channel->GetPVRChannelInfoTag(), false);
}
else
{
// if we don't, find the active channel group of the demanded type and play it's first channel
CPVRChannelGroupPtr channelGroup = GetPlayingGroup(bIsRadio);
if (channelGroup)
{
// try to start playback of first channel in this group
CFileItemPtr channel = channelGroup->GetByIndex(0);
if (channel && channel->HasPVRChannelInfoTag())
bReturn = StartPlayback(channel->GetPVRChannelInfoTag(), false);
}
}

if (!bReturn)
{
CLog::Log(LOGNOTICE, "PVRManager - %s - could not determine %s channel to start playback with. No last played channel found, and first channel of active group could also not be determined.", __FUNCTION__, bIsRadio ? "radio": "tv");

CStdString msg;
msg.Format(g_localizeStrings.Get(19035).c_str(), g_localizeStrings.Get(bIsRadio ? 19021 : 19020).c_str()); // RADIO/TV could not be played. Check the log for details.
CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
g_localizeStrings.Get(19166), // PVR information
msg);
}

return bReturn;
}


bool CPVRManager::PerformChannelSwitch(const CPVRChannel &channel, bool bPreview) bool CPVRManager::PerformChannelSwitch(const CPVRChannel &channel, bool bPreview)
{ {
// check parental lock state // check parental lock state
Expand Down Expand Up @@ -1083,9 +1154,11 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannel &channel, bool bPreview


CLog::Log(LOGERROR, "PVRManager - %s - failed to switch to channel '%s'", __FUNCTION__, channel.ChannelName().c_str()); CLog::Log(LOGERROR, "PVRManager - %s - failed to switch to channel '%s'", __FUNCTION__, channel.ChannelName().c_str());


CStdString msg;
msg.Format(g_localizeStrings.Get(19035).c_str(), channel.ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details.
CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
g_localizeStrings.Get(19166), // PVR information g_localizeStrings.Get(19166), // PVR information
g_localizeStrings.Get(19035)); // This channel cannot be played. Check the log for details. msg);
} }
else else
{ {
Expand Down Expand Up @@ -1323,6 +1396,42 @@ void CPVRManager::ExecutePendingJobs(void)
m_triggerEvent.Reset(); m_triggerEvent.Reset();
} }


bool CPVRManager::OnAction(const CAction &action)
{
// process PVR specific play actions
if (action.GetID() == ACTION_PVR_PLAY || action.GetID() == ACTION_PVR_PLAY_TV || action.GetID() == ACTION_PVR_PLAY_RADIO)
{
// pvr not active yet, show error message
if (!IsStarted())
{
CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(19045), g_localizeStrings.Get(19044));
}
else
{
// see if we're already playing a PVR stream and if not or the stream type
// doesn't match the demanded type, start playback of according type
bool isPlayingPvr(IsPlaying() && g_application.CurrentFileItem().HasPVRChannelInfoTag());
switch (action.GetID())
{
case ACTION_PVR_PLAY:
if (!isPlayingPvr)
StartPlayback(PlaybackTypeAny);
break;
case ACTION_PVR_PLAY_TV:
if (!isPlayingPvr || g_application.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
StartPlayback(PlaybackTypeTv);
break;
case ACTION_PVR_PLAY_RADIO:
if (!isPlayingPvr || !g_application.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
StartPlayback(PlaybackTypeRadio);
break;
}
}
return true;
}
return false;
}

bool CPVRChannelSwitchJob::DoWork(void) bool CPVRChannelSwitchJob::DoWork(void)
{ {
// announce OnStop and delete m_previous when done // announce OnStop and delete m_previous when done
Expand Down
22 changes: 22 additions & 0 deletions xbmc/pvr/PVRManager.h
Expand Up @@ -27,6 +27,7 @@


class CGUIDialogProgressBarHandle; class CGUIDialogProgressBarHandle;
class CStopWatch; class CStopWatch;
class CAction;


namespace EPG namespace EPG
{ {
Expand Down Expand Up @@ -57,6 +58,13 @@ namespace PVR
ManagerStateStarted ManagerStateStarted
}; };


enum PlaybackType
{
PlaybackTypeAny = 0,
PlaybackTypeTv,
PlaybackTypeRadio
};

#define g_PVRManager CPVRManager::Get() #define g_PVRManager CPVRManager::Get()
#define g_PVRChannelGroups g_PVRManager.ChannelGroups() #define g_PVRChannelGroups g_PVRManager.ChannelGroups()
#define g_PVRTimers g_PVRManager.Timers() #define g_PVRTimers g_PVRManager.Timers()
Expand Down Expand Up @@ -388,6 +396,13 @@ namespace PVR
*/ */
bool StartPlayback(const CPVRChannel *channel, bool bPreview = false); bool StartPlayback(const CPVRChannel *channel, bool bPreview = false);


/*!
* @brief Start playback of the last used channel, and if it fails use first channel in the current channelgroup.
* @param type The type of playback to be started (any, radio, tv). See PlaybackType enum
* @return True if playback was started, false otherwise.
*/
bool StartPlayback(PlaybackType type = PlaybackTypeAny);

/*! /*!
* @brief Update the current playing file in the guiinfomanager and application. * @brief Update the current playing file in the guiinfomanager and application.
*/ */
Expand Down Expand Up @@ -473,6 +488,13 @@ namespace PVR
*/ */
bool WaitUntilInitialised(void); bool WaitUntilInitialised(void);


/*!
* @brief Handle PVR specific cActions
* @param action The action to process
* @return True if action could be handled, false otherwise.
*/
bool OnAction(const CAction &action);

protected: protected:
/*! /*!
* @brief PVR update and control thread. * @brief PVR update and control thread.
Expand Down
4 changes: 3 additions & 1 deletion xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
Expand Up @@ -209,9 +209,11 @@ void CGUIDialogPVRChannelsOSD::GotoChannel(int item)
if (!g_PVRManager.CheckParentalLock(*channel) || if (!g_PVRManager.CheckParentalLock(*channel) ||
!g_application.m_pPlayer->SwitchChannel(*channel)) !g_application.m_pPlayer->SwitchChannel(*channel))
{ {
CStdString msg;
msg.Format(g_localizeStrings.Get(19035).c_str(), channel->ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details.
CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
g_localizeStrings.Get(19166), // PVR information g_localizeStrings.Get(19166), // PVR information
g_localizeStrings.Get(19035)); // This channel cannot be played. Check the log for details. msg);
return; return;
} }
} }
Expand Down
9 changes: 8 additions & 1 deletion xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp
Expand Up @@ -23,6 +23,7 @@
#include "guilib/GUIWindowManager.h" #include "guilib/GUIWindowManager.h"
#include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogOK.h"
#include "dialogs/GUIDialogYesNo.h" #include "dialogs/GUIDialogYesNo.h"
#include "guilib/LocalizeStrings.h"


#include "pvr/PVRManager.h" #include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannelGroupsContainer.h" #include "pvr/channels/PVRChannelGroupsContainer.h"
Expand Down Expand Up @@ -170,9 +171,15 @@ bool CGUIDialogPVRGuideInfo::OnClickButtonSwitch(CGUIMessage &message)


if (!m_progItem->GetEPGInfoTag()->HasPVRChannel() || if (!m_progItem->GetEPGInfoTag()->HasPVRChannel() ||
!g_application.PlayFile(CFileItem(*m_progItem->GetEPGInfoTag()->ChannelTag()))) !g_application.PlayFile(CFileItem(*m_progItem->GetEPGInfoTag()->ChannelTag())))
CGUIDialogOK::ShowAndGetInput(19033,0,19035,0); {
CStdString msg;
msg.Format(g_localizeStrings.Get(19035).c_str(), g_localizeStrings.Get(19029).c_str()); // Channel could not be played. Check the log for details.
CGUIDialogOK::ShowAndGetInput(19033, 0, msg, 0);
}
else else
{
bReturn = true; bReturn = true;
}
} }


return bReturn; return bReturn;
Expand Down
13 changes: 10 additions & 3 deletions xbmc/pvr/windows/GUIWindowPVRCommon.cpp
Expand Up @@ -537,8 +537,9 @@ bool CGUIWindowPVRCommon::ActionPlayEpg(CFileItem *item)


if (!bReturn) if (!bReturn)
{ {
/* cannot play file */ CStdString msg;
CGUIDialogOK::ShowAndGetInput(19033,0,19035,0); msg.Format(g_localizeStrings.Get(19035).c_str(), channel->ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details.
CGUIDialogOK::ShowAndGetInput(19033, 0, msg, 0);
} }


return bReturn; return bReturn;
Expand Down Expand Up @@ -717,9 +718,15 @@ bool CGUIWindowPVRCommon::PlayFile(CFileItem *item, bool bPlayMinimized /* = fal


if (!bSwitchSuccessful) if (!bSwitchSuccessful)
{ {
CStdString msg;
CStdString channelName = g_localizeStrings.Get(19029); // Channel
if (channel)
channelName = channel->ChannelName();
msg.Format(g_localizeStrings.Get(19035).c_str(), channelName.c_str()); // CHANNELNAME could not be played. Check the log for details.

CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
g_localizeStrings.Get(19166), // PVR information g_localizeStrings.Get(19166), // PVR information
g_localizeStrings.Get(19035)); // This channel cannot be played. Check the log for details. msg);
return false; return false;
} }
} }
Expand Down
6 changes: 5 additions & 1 deletion xbmc/pvr/windows/GUIWindowPVRGuide.cpp
Expand Up @@ -429,7 +429,11 @@ bool CGUIWindowPVRGuide::PlayEpgItem(CFileItem *item)
CLog::Log(LOGDEBUG, "play channel '%s'", channel->ChannelName().c_str()); CLog::Log(LOGDEBUG, "play channel '%s'", channel->ChannelName().c_str());
bool bReturn = g_application.PlayFile(CFileItem(*channel)); bool bReturn = g_application.PlayFile(CFileItem(*channel));
if (!bReturn) if (!bReturn)
CGUIDialogOK::ShowAndGetInput(19033,0,19035,0); {
CStdString msg;
msg.Format(g_localizeStrings.Get(19035).c_str(), channel->ChannelName().c_str()); // CHANNELNAME could not be played. Check the log for details.
CGUIDialogOK::ShowAndGetInput(19033, 0, msg, 0);
}


return bReturn; return bReturn;
} }
Expand Down

0 comments on commit 47e93ba

Please sign in to comment.