2 * Copyright (C) 2005-2012 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "PlayerOperations.h"
22 #include "Application.h"
24 #include "PlayListPlayer.h"
25 #include "playlists/PlayList.h"
26 #include "guilib/GUIWindowManager.h"
27 #include "GUIUserMessages.h"
28 #include "pictures/GUIWindowSlideShow.h"
29 #include "interfaces/Builtins.h"
30 #include "PartyModeManager.h"
31 #include "ApplicationMessenger.h"
33 #include "VideoLibrary.h"
34 #include "video/VideoDatabase.h"
35 #include "AudioLibrary.h"
36 #include "GUIInfoManager.h"
37 #include "filesystem/File.h"
38 #include "PartyModeManager.h"
39 #include "epg/EpgInfoTag.h"
40 #include "music/MusicDatabase.h"
41 #include "pvr/PVRManager.h"
42 #include "pvr/channels/PVRChannel.h"
43 #include "pvr/channels/PVRChannelGroupsContainer.h"
45 using namespace JSONRPC;
46 using namespace PLAYLIST;
49 JSONRPC_STATUS CPlayerOperations::GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
51 int activePlayers = GetActivePlayers();
52 result = CVariant(CVariant::VariantTypeArray);
54 if (activePlayers & Video)
56 CVariant video = CVariant(CVariant::VariantTypeObject);
57 video["playerid"] = GetPlaylist(Video);
58 video["type"] = "video";
61 if (activePlayers & Audio)
63 CVariant audio = CVariant(CVariant::VariantTypeObject);
64 audio["playerid"] = GetPlaylist(Audio);
65 audio["type"] = "audio";
68 if (activePlayers & Picture)
70 CVariant picture = CVariant(CVariant::VariantTypeObject);
71 picture["playerid"] = GetPlaylist(Picture);
72 picture["type"] = "picture";
73 result.append(picture);
79 JSONRPC_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
81 PlayerType player = GetPlayer(parameterObject["playerid"]);
83 CVariant properties = CVariant(CVariant::VariantTypeObject);
84 for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
86 CStdString propertyName = parameterObject["properties"][index].asString();
89 if ((ret = GetPropertyValue(player, propertyName, property)) != OK)
92 properties[propertyName] = property;
100 JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
102 PlayerType player = GetPlayer(parameterObject["playerid"]);
103 CFileItemPtr fileItem;
110 fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem()));
111 if (fileItem->GetLabel().empty())
115 CPVRChannelPtr currentChannel;
116 if (g_PVRManager.GetCurrentChannel(currentChannel) && currentChannel.get() != NULL)
117 fileItem = CFileItemPtr(new CFileItem(*currentChannel.get()));
119 else if (player == Video)
121 if (!CVideoLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject))
123 const CVideoInfoTag *currentVideoTag = g_infoManager.GetCurrentMovieTag();
124 if (currentVideoTag != NULL)
125 fileItem = CFileItemPtr(new CFileItem(*currentVideoTag));
126 fileItem->SetPath(g_application.CurrentFileItem().GetPath());
131 if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject))
133 const MUSIC_INFO::CMusicInfoTag *currentMusicTag = g_infoManager.GetCurrentSongTag();
134 if (currentMusicTag != NULL)
135 fileItem = CFileItemPtr(new CFileItem(*currentMusicTag));
136 fileItem->SetPath(g_application.CurrentFileItem().GetPath());
146 bool additionalInfo = false;
147 bool streamdetails = false;
148 for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
150 CStdString fieldValue = itr->asString();
151 if (fieldValue == "cast" || fieldValue == "set" || fieldValue == "setid" || fieldValue == "showlink" || fieldValue == "resume" ||
152 (fieldValue == "streamdetails" && !fileItem->GetVideoInfoTag()->m_streamDetails.HasItems()))
153 additionalInfo = true;
156 CVideoDatabase videodatabase;
157 if ((additionalInfo) &&
158 videodatabase.Open())
162 switch (fileItem->GetVideoContentType())
164 case VIDEODB_CONTENT_MOVIES:
165 videodatabase.GetMovieInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId);
168 case VIDEODB_CONTENT_MUSICVIDEOS:
169 videodatabase.GetMusicVideoInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId);
172 case VIDEODB_CONTENT_EPISODES:
173 videodatabase.GetEpisodeInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId);
176 case VIDEODB_CONTENT_TVSHOWS:
177 case VIDEODB_CONTENT_MOVIE_SETS:
183 videodatabase.Close();
186 else if (player == Audio)
188 if (fileItem->IsMusicDb())
190 CMusicDatabase musicdb;
193 CAudioLibrary::GetAdditionalSongDetails(parameterObject, items, musicdb);
201 CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
203 return FailedToExecute;
205 CFileItemList slides;
206 slideshow->GetSlideShowContents(slides);
207 fileItem = slides[slideshow->CurrentSlide() - 1];
213 return FailedToExecute;
216 HandleFileItem("id", !IsPVRChannel(), "item", fileItem, parameterObject, parameterObject["properties"], result, false);
220 JSONRPC_STATUS CPlayerOperations::PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
222 CGUIWindowSlideShow *slideshow = NULL;
223 switch (GetPlayer(parameterObject["playerid"]))
227 if (g_application.m_pPlayer && !g_application.m_pPlayer->CanPause())
228 return FailedToExecute;
230 if (parameterObject["play"].isString())
231 CBuiltins::Execute("playercontrol(play)");
234 if (parameterObject["play"].asBoolean() == g_application.IsPaused())
235 CApplicationMessenger::Get().MediaPause();
237 result["speed"] = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
241 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
242 if (slideshow && slideshow->IsPlaying() &&
243 (parameterObject["play"].isString() ||
244 (parameterObject["play"].isBoolean() && parameterObject["play"].asBoolean() == slideshow->IsPaused())))
245 SendSlideshowAction(ACTION_PAUSE);
247 if (slideshow && slideshow->IsPlaying() && !slideshow->IsPaused())
248 result["speed"] = slideshow->GetDirection();
255 return FailedToExecute;
259 JSONRPC_STATUS CPlayerOperations::Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
261 switch (GetPlayer(parameterObject["playerid"]))
265 CApplicationMessenger::Get().SendAction(CAction(ACTION_STOP));
269 SendSlideshowAction(ACTION_STOP);
274 return FailedToExecute;
278 JSONRPC_STATUS CPlayerOperations::SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
281 switch (GetPlayer(parameterObject["playerid"]))
285 if (parameterObject["speed"].isInteger())
287 speed = (int)parameterObject["speed"].asInteger();
290 // If the player is paused we first need to unpause
291 if (g_application.IsPaused())
292 g_application.m_pPlayer->Pause();
293 g_application.SetPlaySpeed(speed);
296 g_application.m_pPlayer->Pause();
298 else if (parameterObject["speed"].isString())
300 speed = g_application.GetPlaySpeed();
301 if (parameterObject["speed"].asString().compare("increment") == 0)
302 CBuiltins::Execute("playercontrol(forward)");
304 CBuiltins::Execute("playercontrol(rewind)");
307 return InvalidParams;
309 result["speed"] = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
315 return FailedToExecute;
319 JSONRPC_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
321 PlayerType player = GetPlayer(parameterObject["playerid"]);
326 if (g_application.m_pPlayer && !g_application.m_pPlayer->CanSeek())
327 return FailedToExecute;
329 if (parameterObject["value"].isObject())
330 g_application.SeekTime(ParseTimeInSeconds(parameterObject["value"]));
331 else if (IsType(parameterObject["value"], NumberValue))
332 g_application.SeekPercentage(parameterObject["value"].asFloat());
333 else if (parameterObject["value"].isString())
335 CStdString step = parameterObject["value"].asString();
336 if (step.Equals("smallforward"))
337 CBuiltins::Execute("playercontrol(smallskipforward)");
338 else if (step.Equals("smallbackward"))
339 CBuiltins::Execute("playercontrol(smallskipbackward)");
340 else if (step.Equals("bigforward"))
341 CBuiltins::Execute("playercontrol(bigskipforward)");
342 else if (step.Equals("bigbackward"))
343 CBuiltins::Execute("playercontrol(bigskipbackward)");
345 return InvalidParams;
348 return InvalidParams;
350 GetPropertyValue(player, "percentage", result["percentage"]);
351 GetPropertyValue(player, "time", result["time"]);
352 GetPropertyValue(player, "totaltime", result["totaltime"]);
358 return FailedToExecute;
362 JSONRPC_STATUS CPlayerOperations::Move(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
364 std::string direction = parameterObject["direction"].asString();
365 switch (GetPlayer(parameterObject["playerid"]))
368 if (direction == "left")
369 SendSlideshowAction(ACTION_MOVE_LEFT);
370 else if (direction == "right")
371 SendSlideshowAction(ACTION_MOVE_RIGHT);
372 else if (direction == "up")
373 SendSlideshowAction(ACTION_MOVE_UP);
374 else if (direction == "down")
375 SendSlideshowAction(ACTION_MOVE_DOWN);
377 return InvalidParams;
383 if (direction == "left" || direction == "up")
384 CApplicationMessenger::Get().SendAction(CAction(ACTION_PREV_ITEM));
385 else if (direction == "right" || direction == "down")
386 CApplicationMessenger::Get().SendAction(CAction(ACTION_NEXT_ITEM));
388 return InvalidParams;
394 return FailedToExecute;
398 JSONRPC_STATUS CPlayerOperations::Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
400 CVariant zoom = parameterObject["zoom"];
401 switch (GetPlayer(parameterObject["playerid"]))
404 if (zoom.isInteger())
405 SendSlideshowAction(ACTION_ZOOM_LEVEL_NORMAL + ((int)zoom.asInteger() - 1));
406 else if (zoom.isString())
408 std::string strZoom = zoom.asString();
410 SendSlideshowAction(ACTION_ZOOM_IN);
411 else if (strZoom == "out")
412 SendSlideshowAction(ACTION_ZOOM_OUT);
414 return InvalidParams;
417 return InvalidParams;
425 return FailedToExecute;
429 JSONRPC_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
431 switch (GetPlayer(parameterObject["playerid"]))
434 if (parameterObject["value"].asString().compare("clockwise") == 0)
435 SendSlideshowAction(ACTION_ROTATE_PICTURE_CW);
437 SendSlideshowAction(ACTION_ROTATE_PICTURE_CCW);
444 return FailedToExecute;
448 JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
450 CVariant optionShuffled = parameterObject["options"]["shuffled"];
451 CVariant optionRepeat = parameterObject["options"]["repeat"];
452 CVariant optionResume = parameterObject["options"]["resume"];
454 if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
456 int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();
458 if (playlistid < PLAYLIST_PICTURE)
460 // Apply the "shuffled" option if available
461 if (optionShuffled.isBoolean())
462 g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false);
463 // Apply the "repeat" option if available
464 if (!optionRepeat.isNull())
465 g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false);
472 CApplicationMessenger::Get().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger());
476 case PLAYLIST_PICTURE:
477 return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean());
483 else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path"))
485 bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) ||
486 (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean());
487 return StartSlideshow(parameterObject["item"]["path"].asString(), parameterObject["item"]["recursive"].asBoolean(), random);
489 else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("partymode"))
491 if (g_partyModeManager.IsEnabled())
492 g_partyModeManager.Disable();
493 CApplicationMessenger::Get().ExecBuiltIn("playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))");
496 else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid"))
498 if (!g_PVRManager.IsStarted())
499 return FailedToExecute;
501 CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
502 if (channelGroupContainer == NULL)
503 return FailedToExecute;
505 CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger());
507 return InvalidParams;
509 CApplicationMessenger::Get().MediaPlay(CFileItem(*channel.get()));
515 if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0)
517 bool slideshow = true;
518 for (int index = 0; index < list.Size(); index++)
520 if (!list[index]->IsPicture())
529 CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
531 return FailedToExecute;
533 SendSlideshowAction(ACTION_STOP);
535 for (int index = 0; index < list.Size(); index++)
536 slideshow->Add(list[index].get());
538 return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean());
542 // Handle "shuffled" option
543 if (optionShuffled.isBoolean())
544 list.SetProperty("shuffled", optionShuffled);
545 // Handle "repeat" option
546 if (!optionRepeat.isNull())
547 list.SetProperty("repeat", ParseRepeatState(optionRepeat));
548 // Handle "resume" option
549 if (list.Size() == 1)
551 if (optionResume.isBoolean() && optionResume.asBoolean())
552 list[0]->m_lStartOffset = STARTOFFSET_RESUME;
553 else if (optionResume.isDouble())
554 list[0]->SetProperty("StartPercent", optionResume);
555 else if (optionResume.isObject())
556 list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0);
559 CApplicationMessenger::Get().MediaPlay(list);
565 return InvalidParams;
568 return InvalidParams;
571 JSONRPC_STATUS CPlayerOperations::GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
573 CVariant to = parameterObject["to"];
574 switch (GetPlayer(parameterObject["playerid"]))
580 std::string strTo = to.asString();
582 if (strTo == "previous")
583 actionID = ACTION_PREV_ITEM;
584 else if (strTo == "next")
585 actionID = ACTION_NEXT_ITEM;
587 return InvalidParams;
589 CApplicationMessenger::Get().SendAction(CAction(actionID));
591 else if (to.isInteger())
594 CApplicationMessenger::Get().SendAction(CAction(ACTION_CHANNEL_SWITCH, (float)to.asInteger()));
596 CApplicationMessenger::Get().PlayListPlayerPlay((int)to.asInteger());
599 return InvalidParams;
605 std::string strTo = to.asString();
607 if (strTo == "previous")
608 actionID = ACTION_PREV_PICTURE;
609 else if (strTo == "next")
610 actionID = ACTION_NEXT_PICTURE;
612 return InvalidParams;
614 SendSlideshowAction(actionID);
617 return FailedToExecute;
622 return FailedToExecute;
629 JSONRPC_STATUS CPlayerOperations::SetShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
631 CGUIWindowSlideShow *slideshow = NULL;
632 CVariant shuffle = parameterObject["shuffle"];
633 switch (GetPlayer(parameterObject["playerid"]))
639 return FailedToExecute;
641 int playlistid = GetPlaylist(GetPlayer(parameterObject["playerid"]));
642 if (g_playlistPlayer.IsShuffled(playlistid))
644 if ((shuffle.isBoolean() && !shuffle.asBoolean()) ||
645 (shuffle.isString() && shuffle.asString() == "toggle"))
647 CApplicationMessenger::Get().PlayListPlayerShuffle(playlistid, false);
653 if ((shuffle.isBoolean() && shuffle.asBoolean()) ||
654 (shuffle.isString() && shuffle.asString() == "toggle"))
656 CApplicationMessenger::Get().PlayListPlayerShuffle(playlistid, true);
664 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
665 if (slideshow == NULL)
666 return FailedToExecute;
667 if (slideshow->IsShuffled())
669 if ((shuffle.isBoolean() && !shuffle.asBoolean()) ||
670 (shuffle.isString() && shuffle.asString() == "toggle"))
671 return FailedToExecute;
675 if ((shuffle.isBoolean() && shuffle.asBoolean()) ||
676 (shuffle.isString() && shuffle.asString() == "toggle"))
677 slideshow->Shuffle();
682 return FailedToExecute;
687 JSONRPC_STATUS CPlayerOperations::SetRepeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
689 switch (GetPlayer(parameterObject["playerid"]))
695 return FailedToExecute;
697 REPEAT_STATE repeat = REPEAT_NONE;
698 int playlistid = GetPlaylist(GetPlayer(parameterObject["playerid"]));
699 if (parameterObject["repeat"].asString() == "cycle")
701 REPEAT_STATE repeatPrev = g_playlistPlayer.GetRepeat(playlistid);
703 if (repeatPrev == REPEAT_NONE)
705 else if (repeatPrev == REPEAT_ALL)
708 repeat = REPEAT_NONE;
711 repeat = (REPEAT_STATE)ParseRepeatState(parameterObject["repeat"]);
713 CApplicationMessenger::Get().PlayListPlayerRepeat(playlistid, repeat);
720 return FailedToExecute;
726 JSONRPC_STATUS CPlayerOperations::SetPartymode(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
728 PlayerType player = GetPlayer(parameterObject["playerid"]);
735 return FailedToExecute;
738 PartyModeContext context = PARTYMODECONTEXT_UNKNOWN;
739 std::string strContext;
742 context = PARTYMODECONTEXT_VIDEO;
743 strContext = "video";
745 else if (player == Audio)
747 context = PARTYMODECONTEXT_MUSIC;
748 strContext = "music";
751 bool toggle = parameterObject["partymode"].isString();
752 if (g_partyModeManager.IsEnabled())
754 if (g_partyModeManager.GetType() != context)
755 return InvalidParams;
757 if (toggle || parameterObject["partymode"].asBoolean() == false)
762 if (toggle || parameterObject["partymode"].asBoolean() == true)
767 CApplicationMessenger::Get().ExecBuiltIn("playercontrol(partymode(" + strContext + "))");
773 return FailedToExecute;
779 JSONRPC_STATUS CPlayerOperations::SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
781 switch (GetPlayer(parameterObject["playerid"]))
784 if (g_application.m_pPlayer)
787 if (parameterObject["stream"].isString())
789 std::string action = parameterObject["stream"].asString();
790 if (action.compare("previous") == 0)
792 index = g_application.m_pPlayer->GetAudioStream() - 1;
794 index = g_application.m_pPlayer->GetAudioStreamCount() - 1;
796 else if (action.compare("next") == 0)
798 index = g_application.m_pPlayer->GetAudioStream() + 1;
799 if (index >= g_application.m_pPlayer->GetAudioStreamCount())
803 return InvalidParams;
805 else if (parameterObject["stream"].isInteger())
806 index = (int)parameterObject["stream"].asInteger();
808 if (index < 0 || g_application.m_pPlayer->GetAudioStreamCount() <= index)
809 return InvalidParams;
811 g_application.m_pPlayer->SetAudioStream(index);
814 return FailedToExecute;
820 return FailedToExecute;
826 JSONRPC_STATUS CPlayerOperations::SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
828 switch (GetPlayer(parameterObject["playerid"]))
831 if (g_application.m_pPlayer)
834 if (parameterObject["subtitle"].isString())
836 std::string action = parameterObject["subtitle"].asString();
837 if (action.compare("previous") == 0)
839 index = g_application.m_pPlayer->GetSubtitle() - 1;
841 index = g_application.m_pPlayer->GetSubtitleCount() - 1;
843 else if (action.compare("next") == 0)
845 index = g_application.m_pPlayer->GetSubtitle() + 1;
846 if (index >= g_application.m_pPlayer->GetSubtitleCount())
849 else if (action.compare("off") == 0)
851 g_application.m_pPlayer->SetSubtitleVisible(false);
854 else if (action.compare("on") == 0)
856 g_application.m_pPlayer->SetSubtitleVisible(true);
860 return InvalidParams;
862 else if (parameterObject["subtitle"].isInteger())
863 index = (int)parameterObject["subtitle"].asInteger();
865 if (index < 0 || g_application.m_pPlayer->GetSubtitleCount() <= index)
866 return InvalidParams;
868 g_application.m_pPlayer->SetSubtitle(index);
870 // Check if we need to enable subtitles to be displayed
871 if (parameterObject["enable"].asBoolean() && !g_application.m_pPlayer->GetSubtitleVisible())
872 g_application.m_pPlayer->SetSubtitleVisible(true);
875 return FailedToExecute;
881 return FailedToExecute;
887 int CPlayerOperations::GetActivePlayers()
889 int activePlayers = 0;
891 if (g_application.IsPlayingVideo() || g_PVRManager.IsPlayingTV() || g_PVRManager.IsPlayingRecording())
892 activePlayers |= Video;
893 if (g_application.IsPlayingAudio() || g_PVRManager.IsPlayingRadio())
894 activePlayers |= Audio;
895 if (g_windowManager.IsWindowActive(WINDOW_SLIDESHOW))
896 activePlayers |= Picture;
898 return activePlayers;
901 PlayerType CPlayerOperations::GetPlayer(const CVariant &player)
903 int activePlayers = GetActivePlayers();
906 switch ((int)player.asInteger())
916 case PLAYLIST_PICTURE:
921 playerID = PlayerImplicit;
925 int choosenPlayer = playerID & activePlayers;
928 if (choosenPlayer & Video)
930 else if (choosenPlayer & Audio)
932 else if (choosenPlayer & Picture)
938 int CPlayerOperations::GetPlaylist(PlayerType player)
943 return PLAYLIST_VIDEO;
946 return PLAYLIST_MUSIC;
949 return PLAYLIST_PICTURE;
952 return PLAYLIST_NONE;
956 JSONRPC_STATUS CPlayerOperations::StartSlideshow(const std::string path, bool recursive, bool random)
966 CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags);
967 msg.SetStringParam(path);
968 CApplicationMessenger::Get().SendGUIMessage(msg, WINDOW_SLIDESHOW, true);
973 void CPlayerOperations::SendSlideshowAction(int actionID)
975 CApplicationMessenger::Get().SendAction(CAction(actionID), WINDOW_SLIDESHOW);
978 void CPlayerOperations::OnPlaylistChanged()
980 CGUIMessage msg(GUI_MSG_PLAYLIST_CHANGED, 0, 0);
981 g_windowManager.SendThreadMessage(msg);
984 JSONRPC_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result)
987 return FailedToExecute;
989 int playlist = GetPlaylist(player);
991 if (property.Equals("type"))
1008 return FailedToExecute;
1011 else if (property.Equals("partymode"))
1023 result = g_partyModeManager.IsEnabled();
1031 return FailedToExecute;
1034 else if (property.Equals("speed"))
1036 CGUIWindowSlideShow *slideshow = NULL;
1041 result = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
1045 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
1046 if (slideshow && slideshow->IsPlaying() && !slideshow->IsPaused())
1047 result = slideshow->GetDirection();
1053 return FailedToExecute;
1056 else if (property.Equals("time"))
1064 if (!IsPVRChannel())
1065 ms = (int)(g_application.GetTime() * 1000.0);
1068 EPG::CEpgInfoTag epg;
1069 if (GetCurrentEpg(epg))
1070 ms = epg.Progress() * 1000;
1073 MillisecondsToTimeObject(ms, result);
1078 MillisecondsToTimeObject(0, result);
1082 return FailedToExecute;
1085 else if (property.Equals("percentage"))
1087 CGUIWindowSlideShow *slideshow = NULL;
1093 if (!IsPVRChannel())
1094 result = g_application.GetPercentage();
1097 EPG::CEpgInfoTag epg;
1098 if (GetCurrentEpg(epg))
1099 result = epg.ProgressPercentage();
1107 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
1108 if (slideshow && slideshow->NumSlides() > 0)
1109 result = (double)slideshow->CurrentSlide() / slideshow->NumSlides();
1115 return FailedToExecute;
1118 else if (property.Equals("totaltime"))
1126 if (!IsPVRChannel())
1127 ms = (int)(g_application.GetTotalTime() * 1000.0);
1130 EPG::CEpgInfoTag epg;
1131 if (GetCurrentEpg(epg))
1132 ms = epg.GetDuration() * 1000;
1135 MillisecondsToTimeObject(ms, result);
1140 MillisecondsToTimeObject(0, result);
1144 return FailedToExecute;
1147 else if (property.Equals("playlistid"))
1151 else if (property.Equals("position"))
1153 CGUIWindowSlideShow *slideshow = NULL;
1158 if (!IsPVRChannel() && g_playlistPlayer.GetCurrentPlaylist() == playlist)
1159 result = g_playlistPlayer.GetCurrentSong();
1165 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
1166 if (slideshow && slideshow->IsPlaying())
1167 result = slideshow->CurrentSlide() - 1;
1177 else if (property.Equals("repeat"))
1189 switch (g_playlistPlayer.GetRepeat(playlist))
1209 else if (property.Equals("shuffled"))
1211 CGUIWindowSlideShow *slideshow = NULL;
1222 result = g_playlistPlayer.IsShuffled(playlist);
1226 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
1227 if (slideshow && slideshow->IsPlaying())
1228 result = slideshow->IsShuffled();
1238 else if (property.Equals("canseek"))
1244 if (g_application.m_pPlayer)
1245 result = g_application.m_pPlayer->CanSeek();
1256 else if (property.Equals("canchangespeed"))
1262 result = !IsPVRChannel();
1271 else if (property.Equals("canmove"))
1286 else if (property.Equals("canzoom"))
1301 else if (property.Equals("canrotate"))
1316 else if (property.Equals("canshuffle"))
1323 result = !IsPVRChannel();
1331 else if (property.Equals("canrepeat"))
1337 result = !IsPVRChannel();
1346 else if (property.Equals("currentaudiostream"))
1352 if (g_application.m_pPlayer)
1354 result = CVariant(CVariant::VariantTypeObject);
1355 int index = g_application.m_pPlayer->GetAudioStream();
1358 result["index"] = index;
1360 g_application.m_pPlayer->GetAudioStreamName(index, value);
1361 result["name"] = value;
1363 g_application.m_pPlayer->GetAudioStreamLanguage(index, value);
1364 result["language"] = value;
1366 result["codec"] = g_application.m_pPlayer->GetAudioCodecName();
1367 result["bitrate"] = g_application.m_pPlayer->GetAudioBitrate();
1368 result["channels"] = g_application.m_pPlayer->GetChannels();
1371 result = CVariant(CVariant::VariantTypeNull);
1376 result = CVariant(CVariant::VariantTypeNull);
1380 else if (property.Equals("audiostreams"))
1382 result = CVariant(CVariant::VariantTypeArray);
1386 if (g_application.m_pPlayer)
1388 for (int index = 0; index < g_application.m_pPlayer->GetAudioStreamCount(); index++)
1390 CVariant audioStream(CVariant::VariantTypeObject);
1391 audioStream["index"] = index;
1393 g_application.m_pPlayer->GetAudioStreamName(index, value);
1394 audioStream["name"] = value;
1396 g_application.m_pPlayer->GetAudioStreamLanguage(index, value);
1397 audioStream["language"] = value;
1399 result.append(audioStream);
1410 else if (property.Equals("subtitleenabled"))
1415 if (g_application.m_pPlayer)
1416 result = g_application.m_pPlayer->GetSubtitleVisible();
1426 else if (property.Equals("currentsubtitle"))
1431 if (g_application.m_pPlayer)
1433 result = CVariant(CVariant::VariantTypeObject);
1434 int index = g_application.m_pPlayer->GetSubtitle();
1437 result["index"] = index;
1439 g_application.m_pPlayer->GetSubtitleName(index, value);
1440 result["name"] = value;
1442 g_application.m_pPlayer->GetSubtitleLanguage(index, value);
1443 result["language"] = value;
1447 result = CVariant(CVariant::VariantTypeNull);
1453 result = CVariant(CVariant::VariantTypeNull);
1457 else if (property.Equals("subtitles"))
1459 result = CVariant(CVariant::VariantTypeArray);
1463 if (g_application.m_pPlayer)
1465 for (int index = 0; index < g_application.m_pPlayer->GetSubtitleCount(); index++)
1467 CVariant subtitle(CVariant::VariantTypeObject);
1468 subtitle["index"] = index;
1470 g_application.m_pPlayer->GetSubtitleName(index, value);
1471 subtitle["name"] = value;
1473 g_application.m_pPlayer->GetSubtitleLanguage(index, value);
1474 subtitle["language"] = value;
1476 result.append(subtitle);
1487 else if (property.Equals("live"))
1488 result = IsPVRChannel();
1490 return InvalidParams;
1495 int CPlayerOperations::ParseRepeatState(const CVariant &repeat)
1497 REPEAT_STATE state = REPEAT_NONE;
1498 std::string strState = repeat.asString();
1500 if (strState.compare("one") == 0)
1502 else if (strState.compare("all") == 0)
1508 double CPlayerOperations::ParseTimeInSeconds(const CVariant &time)
1510 double seconds = 0.0;
1511 if (time.isObject())
1513 if (time.isMember("hours"))
1514 seconds += time["hours"].asInteger() * 60 * 60;
1515 if (time.isMember("minutes"))
1516 seconds += time["minutes"].asInteger() * 60;
1517 if (time.isMember("seconds"))
1518 seconds += time["seconds"].asInteger();
1519 if (time.isMember("milliseconds"))
1520 seconds += time["milliseconds"].asDouble() / 1000.0;
1526 bool CPlayerOperations::IsPVRChannel()
1528 return g_PVRManager.IsPlayingTV() || g_PVRManager.IsPlayingRadio();
1531 bool CPlayerOperations::GetCurrentEpg(EPG::CEpgInfoTag &epg)
1533 if (!g_PVRManager.IsPlayingTV() && !g_PVRManager.IsPlayingRadio())
1536 CPVRChannelPtr currentChannel;
1537 if (!g_PVRManager.GetCurrentChannel(currentChannel))
1540 if (!currentChannel->GetEPGNow(epg))