2 * Copyright (C) 2005-2010 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, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "PlayerOperations.h"
23 #include "Application.h"
25 #include "PlayListPlayer.h"
26 #include "guilib/GUIWindowManager.h"
27 #include "GUIUserMessages.h"
28 #include "pictures/GUIWindowSlideShow.h"
29 #include "interfaces/Builtins.h"
30 #include "PlayListPlayer.h"
31 #include "PartyModeManager.h"
32 #include "ApplicationMessenger.h"
35 using namespace JSONRPC;
36 using namespace PLAYLIST;
38 JSON_STATUS CPlayerOperations::GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
40 int activePlayers = GetActivePlayers();
41 result = CVariant(CVariant::VariantTypeArray);
43 if (activePlayers & Video)
45 CVariant video = CVariant(CVariant::VariantTypeObject);
46 video["playerid"] = GetPlaylist(Video);
47 video["type"] = "video";
50 if (activePlayers & Audio)
52 CVariant audio = CVariant(CVariant::VariantTypeObject);
53 audio["playerid"] = GetPlaylist(Audio);
54 audio["type"] = "audio";
57 if (activePlayers & Picture)
59 CVariant picture = CVariant(CVariant::VariantTypeObject);
60 picture["playerid"] = GetPlaylist(Picture);
61 picture["type"] = "picture";
62 result.append(picture);
68 JSON_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
70 PlayerType player = GetPlayer(parameterObject["playerid"]);
72 CVariant properties = CVariant(CVariant::VariantTypeObject);
73 for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
75 CStdString propertyName = parameterObject["properties"][index].asString();
78 if ((ret = GetPropertyValue(player, propertyName, property)) != OK)
81 properties[propertyName] = property;
89 JSON_STATUS CPlayerOperations::PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
91 CGUIWindowSlideShow *slideshow = NULL;
92 switch (GetPlayer(parameterObject["playerid"]))
96 CBuiltins::Execute("playercontrol(play)");
97 result["speed"] = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
101 SendSlideshowAction(ACTION_PAUSE);
102 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
103 if (slideshow && slideshow->IsPlaying() && !slideshow->IsPaused())
104 result["speed"] = slideshow->GetDirection();
111 return FailedToExecute;
115 JSON_STATUS CPlayerOperations::Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
117 switch (GetPlayer(parameterObject["playerid"]))
121 g_application.getApplicationMessenger().SendAction(CAction(ACTION_STOP));
125 SendSlideshowAction(ACTION_STOP);
130 return FailedToExecute;
134 JSON_STATUS CPlayerOperations::SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
137 switch (GetPlayer(parameterObject["playerid"]))
141 if (parameterObject["speed"].isInteger())
143 speed = (int)parameterObject["speed"].asInteger();
146 // If the player is paused we first need to unpause
147 if (g_application.IsPaused())
148 g_application.m_pPlayer->Pause();
149 g_application.SetPlaySpeed(speed);
152 g_application.m_pPlayer->Pause();
154 else if (parameterObject["speed"].isString())
156 speed = g_application.GetPlaySpeed();
157 if (parameterObject["speed"].asString().compare("increment") == 0)
158 CBuiltins::Execute("playercontrol(forward)");
160 CBuiltins::Execute("playercontrol(rewind)");
163 return InvalidParams;
165 result["speed"] = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
171 return FailedToExecute;
175 JSON_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
177 PlayerType player = GetPlayer(parameterObject["playerid"]);
182 if (parameterObject["value"].isObject())
183 g_application.SeekTime(((parameterObject["value"]["hours"].asInteger() * 60) + parameterObject["value"]["minutes"].asInteger()) * 60 +
184 parameterObject["value"]["seconds"].asInteger() + ((double)parameterObject["value"]["milliseconds"].asInteger() / 1000.0));
185 else if (IsType(parameterObject["value"], NumberValue))
186 g_application.SeekPercentage(parameterObject["value"].asFloat());
187 else if (parameterObject["value"].isString())
189 CStdString step = parameterObject["value"].asString();
190 if (step.Equals("smallforward"))
191 CBuiltins::Execute("playercontrol(smallskipforward)");
192 else if (step.Equals("smallbackward"))
193 CBuiltins::Execute("playercontrol(smallskipbackward)");
194 else if (step.Equals("bigforward"))
195 CBuiltins::Execute("playercontrol(bigskipforward)");
196 else if (step.Equals("bigbackward"))
197 CBuiltins::Execute("playercontrol(bigskipbackward)");
199 return InvalidParams;
202 return InvalidParams;
204 GetPropertyValue(player, "percentage", result["percentage"]);
205 GetPropertyValue(player, "time", result["time"]);
206 GetPropertyValue(player, "totaltime", result["totaltime"]);
212 return FailedToExecute;
216 JSON_STATUS CPlayerOperations::MoveLeft(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
218 switch (GetPlayer(parameterObject["playerid"]))
221 SendSlideshowAction(ACTION_MOVE_LEFT);
228 return FailedToExecute;
232 JSON_STATUS CPlayerOperations::MoveRight(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
234 switch (GetPlayer(parameterObject["playerid"]))
237 SendSlideshowAction(ACTION_MOVE_RIGHT);
244 return FailedToExecute;
248 JSON_STATUS CPlayerOperations::MoveDown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
250 switch (GetPlayer(parameterObject["playerid"]))
253 SendSlideshowAction(ACTION_MOVE_DOWN);
260 return FailedToExecute;
264 JSON_STATUS CPlayerOperations::MoveUp(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
266 switch (GetPlayer(parameterObject["playerid"]))
269 SendSlideshowAction(ACTION_MOVE_UP);
276 return FailedToExecute;
280 JSON_STATUS CPlayerOperations::ZoomOut(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
282 switch (GetPlayer(parameterObject["playerid"]))
285 SendSlideshowAction(ACTION_ZOOM_OUT);
292 return FailedToExecute;
296 JSON_STATUS CPlayerOperations::ZoomIn(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
298 switch (GetPlayer(parameterObject["playerid"]))
301 SendSlideshowAction(ACTION_ZOOM_IN);
308 return FailedToExecute;
312 JSON_STATUS CPlayerOperations::Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
314 switch (GetPlayer(parameterObject["playerid"]))
317 SendSlideshowAction(ACTION_ZOOM_LEVEL_NORMAL + ((int)parameterObject["value"].asInteger() - 1));
324 return FailedToExecute;
328 JSON_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
330 switch (GetPlayer(parameterObject["playerid"]))
333 SendSlideshowAction(ACTION_ROTATE_PICTURE);
340 return FailedToExecute;
344 JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
346 if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
348 int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();
353 if (g_playlistPlayer.GetCurrentPlaylist() != playlistid)
354 g_playlistPlayer.SetCurrentPlaylist(playlistid);
356 g_application.getApplicationMessenger().PlayListPlayerPlay((int)parameterObject["item"]["position"].asInteger());
361 case PLAYLIST_PICTURE:
362 return StartSlideshow();
368 else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path"))
370 CStdString exec = "slideShow(";
372 exec += parameterObject["item"]["path"].asString();
374 if (parameterObject["item"]["random"].asBoolean())
377 exec += ", notrandom";
379 if (parameterObject["item"]["recursive"].asBoolean())
380 exec += ", recursive";
383 ThreadMessage msg = { TMSG_EXECUTE_BUILT_IN, (DWORD)0, (DWORD)0, exec };
384 g_application.getApplicationMessenger().SendMessage(msg);
391 if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0)
393 bool slideshow = true;
394 for (int index = 0; index < list.Size(); index++)
396 if (!list[index]->HasPictureInfoTag())
405 CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
407 return FailedToExecute;
409 SendSlideshowAction(ACTION_STOP);
411 for (int index = 0; index < list.Size(); index++)
412 slideshow->Add(list[index].get());
414 return StartSlideshow();
417 g_application.getApplicationMessenger().MediaPlay(list);
422 return InvalidParams;
425 return InvalidParams;
428 JSON_STATUS CPlayerOperations::GoPrevious(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
430 switch (GetPlayer(parameterObject["playerid"]))
434 g_application.getApplicationMessenger().SendAction(CAction(ACTION_PREV_ITEM));
438 SendSlideshowAction(ACTION_PREV_PICTURE);
443 return FailedToExecute;
447 JSON_STATUS CPlayerOperations::GoNext(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
449 switch (GetPlayer(parameterObject["playerid"]))
453 g_application.getApplicationMessenger().SendAction(CAction(ACTION_NEXT_ITEM));
457 SendSlideshowAction(ACTION_NEXT_PICTURE);
462 return FailedToExecute;
466 JSON_STATUS CPlayerOperations::GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
468 int position = (int)parameterObject["position"].asInteger();
469 switch (GetPlayer(parameterObject["playerid"]))
473 g_application.getApplicationMessenger().PlayListPlayerPlay(position);
479 return FailedToExecute;
486 JSON_STATUS CPlayerOperations::Shuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
488 CGUIWindowSlideShow *slideshow = NULL;
489 switch (GetPlayer(parameterObject["playerid"]))
493 g_application.getApplicationMessenger().PlayListPlayerShuffle(GetPlaylist(GetPlayer(parameterObject["playerid"])), true);
498 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
499 if (slideshow && !slideshow->IsShuffled())
500 slideshow->Shuffle();
502 return FailedToExecute;
506 return FailedToExecute;
511 JSON_STATUS CPlayerOperations::UnShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
513 switch (GetPlayer(parameterObject["playerid"]))
517 g_application.getApplicationMessenger().PlayListPlayerShuffle(GetPlaylist(GetPlayer(parameterObject["playerid"])), false);
523 return FailedToExecute;
528 JSON_STATUS CPlayerOperations::Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
530 REPEAT_STATE state = REPEAT_NONE;
531 std::string strState = parameterObject["state"].asString();
533 switch (GetPlayer(parameterObject["playerid"]))
537 if (strState.compare("one") == 0)
539 else if (strState.compare("all") == 0)
542 g_application.getApplicationMessenger().PlayListPlayerRepeat(GetPlaylist(GetPlayer(parameterObject["playerid"])), state);
548 return FailedToExecute;
554 JSON_STATUS CPlayerOperations::SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
556 switch (GetPlayer(parameterObject["playerid"]))
559 if (g_application.m_pPlayer)
562 if (parameterObject["stream"].isString())
564 std::string action = parameterObject["stream"].asString();
565 if (action.compare("previous") == 0)
567 index = g_application.m_pPlayer->GetAudioStream() - 1;
569 index = g_application.m_pPlayer->GetAudioStreamCount() - 1;
571 else if (action.compare("next") == 0)
573 index = g_application.m_pPlayer->GetAudioStream() + 1;
574 if (index >= g_application.m_pPlayer->GetAudioStreamCount())
578 return InvalidParams;
580 else if (parameterObject["stream"].isInteger())
581 index = (int)parameterObject["stream"].asInteger();
583 if (index < 0 || g_application.m_pPlayer->GetAudioStreamCount() <= index)
584 return InvalidParams;
586 g_application.m_pPlayer->SetAudioStream(index);
589 return FailedToExecute;
595 return FailedToExecute;
601 JSON_STATUS CPlayerOperations::SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
603 switch (GetPlayer(parameterObject["playerid"]))
606 if (g_application.m_pPlayer)
609 if (parameterObject["subtitle"].isString())
611 std::string action = parameterObject["subtitle"].asString();
612 if (action.compare("previous") == 0)
614 index = g_application.m_pPlayer->GetSubtitle() - 1;
616 index = g_application.m_pPlayer->GetSubtitleCount() - 1;
618 else if (action.compare("next") == 0)
620 index = g_application.m_pPlayer->GetSubtitle() + 1;
621 if (index >= g_application.m_pPlayer->GetSubtitleCount())
624 else if (action.compare("off") == 0)
626 g_application.m_pPlayer->SetSubtitleVisible(false);
629 else if (action.compare("on") == 0)
631 g_application.m_pPlayer->SetSubtitleVisible(true);
635 return InvalidParams;
637 else if (parameterObject["subtitle"].isInteger())
638 index = (int)parameterObject["subtitle"].asInteger();
640 if (index < 0 || g_application.m_pPlayer->GetSubtitleCount() <= index)
641 return InvalidParams;
643 g_application.m_pPlayer->SetSubtitle(index);
646 return FailedToExecute;
652 return FailedToExecute;
658 int CPlayerOperations::GetActivePlayers()
660 int activePlayers = 0;
662 if (g_application.IsPlayingVideo())
663 activePlayers |= Video;
664 if (g_application.IsPlayingAudio())
665 activePlayers |= Audio;
666 if (g_windowManager.IsWindowActive(WINDOW_SLIDESHOW))
667 activePlayers |= Picture;
669 return activePlayers;
672 PlayerType CPlayerOperations::GetPlayer(const CVariant &player)
674 int activePlayers = GetActivePlayers();
677 switch ((int)player.asInteger())
687 case PLAYLIST_PICTURE:
692 playerID = PlayerImplicit;
696 int choosenPlayer = playerID & activePlayers;
699 if (choosenPlayer & Video)
701 else if (choosenPlayer & Audio)
703 else if (choosenPlayer & Picture)
709 int CPlayerOperations::GetPlaylist(PlayerType player)
714 return PLAYLIST_VIDEO;
717 return PLAYLIST_MUSIC;
720 return PLAYLIST_PICTURE;
723 return PLAYLIST_NONE;
727 JSON_STATUS CPlayerOperations::StartSlideshow()
729 CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
730 if (!slideshow && slideshow->NumSlides() <= 0)
731 return FailedToExecute;
733 if (g_application.IsPlayingVideo())
734 g_application.StopPlaying();
736 g_graphicsContext.Lock();
738 g_application.WakeUpScreenSaverAndDPMS();
739 slideshow->StartSlideShow();
741 if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
742 g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
744 g_graphicsContext.Unlock();
749 void CPlayerOperations::SendSlideshowAction(int actionID)
751 g_application.getApplicationMessenger().SendAction(CAction(actionID), WINDOW_SLIDESHOW);
754 void CPlayerOperations::OnPlaylistChanged()
756 CGUIMessage msg(GUI_MSG_PLAYLIST_CHANGED, 0, 0);
757 g_windowManager.SendThreadMessage(msg);
760 JSON_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result)
763 return FailedToExecute;
765 int playlist = GetPlaylist(player);
767 if (property.Equals("type"))
784 return FailedToExecute;
787 else if (property.Equals("partymode"))
793 result = g_partyModeManager.IsEnabled();
801 return FailedToExecute;
804 else if (property.Equals("speed"))
806 CGUIWindowSlideShow *slideshow = NULL;
811 result = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
815 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
816 if (slideshow && slideshow->IsPlaying() && !slideshow->IsPaused())
817 result = slideshow->GetDirection();
823 return FailedToExecute;
826 else if (property.Equals("time"))
832 MillisecondsToTimeObject((int)(g_application.GetTime() * 1000.0), result);
836 MillisecondsToTimeObject(0, result);
840 return FailedToExecute;
843 else if (property.Equals("percentage"))
845 CGUIWindowSlideShow *slideshow = NULL;
850 result = g_application.GetPercentage();
854 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
855 if (slideshow && slideshow->NumSlides() > 0)
856 result = (double)slideshow->CurrentSlide() / slideshow->NumSlides();
862 return FailedToExecute;
865 else if (property.Equals("totaltime"))
871 MillisecondsToTimeObject((int)(g_application.GetTotalTime() * 1000.0), result);
875 MillisecondsToTimeObject(0, result);
879 return FailedToExecute;
882 else if (property.Equals("playlistid"))
886 else if (property.Equals("position"))
888 CGUIWindowSlideShow *slideshow = NULL;
893 if (g_playlistPlayer.GetCurrentPlaylist() == playlist)
894 result = g_playlistPlayer.GetCurrentSong();
900 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
901 if (slideshow && slideshow->IsPlaying())
902 result = slideshow->CurrentSlide() - 1;
912 else if (property.Equals("repeat"))
918 switch (g_playlistPlayer.GetRepeat(playlist))
938 else if (property.Equals("shuffled"))
940 CGUIWindowSlideShow *slideshow = NULL;
945 result = g_playlistPlayer.IsShuffled(playlist);
949 slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
950 if (slideshow && slideshow->IsPlaying())
951 result = slideshow->IsShuffled();
961 else if (property.Equals("canseek"))
967 if (g_application.m_pPlayer)
968 result = g_application.m_pPlayer->CanSeek();
979 else if (property.Equals("canchangespeed"))
994 else if (property.Equals("canmove"))
1009 else if (property.Equals("canzoom"))
1024 else if (property.Equals("canrotate"))
1039 else if (property.Equals("canshuffle"))
1054 else if (property.Equals("canrepeat"))
1069 else if (property.Equals("currentaudiostream"))
1075 if (g_application.m_pPlayer)
1077 result = CVariant(CVariant::VariantTypeObject);
1078 int index = g_application.m_pPlayer->GetAudioStream();
1081 result["index"] = index;
1083 g_application.m_pPlayer->GetAudioStreamName(index, value);
1084 result["name"] = value;
1086 g_application.m_pPlayer->GetAudioStreamLanguage(index, value);
1087 result["language"] = value;
1089 result["codec"] = g_application.m_pPlayer->GetAudioCodecName();
1090 result["bitrate"] = g_application.m_pPlayer->GetAudioBitrate();
1091 result["channels"] = g_application.m_pPlayer->GetChannels();
1094 result = CVariant(CVariant::VariantTypeNull);
1099 result = CVariant(CVariant::VariantTypeNull);
1103 else if (property.Equals("audiostreams"))
1105 result = CVariant(CVariant::VariantTypeArray);
1109 if (g_application.m_pPlayer)
1111 for (int index = 0; index < g_application.m_pPlayer->GetAudioStreamCount(); index++)
1113 CVariant audioStream(CVariant::VariantTypeObject);
1114 audioStream["index"] = index;
1116 g_application.m_pPlayer->GetAudioStreamName(index, value);
1117 audioStream["name"] = value;
1119 g_application.m_pPlayer->GetAudioStreamLanguage(index, value);
1120 audioStream["language"] = value;
1122 result.append(audioStream);
1133 else if (property.Equals("subtitleenabled"))
1138 if (g_application.m_pPlayer)
1139 result = g_application.m_pPlayer->GetSubtitleVisible();
1149 else if (property.Equals("currentsubtitle"))
1154 if (g_application.m_pPlayer)
1156 result = CVariant(CVariant::VariantTypeObject);
1157 int index = g_application.m_pPlayer->GetSubtitle();
1160 result["index"] = index;
1162 g_application.m_pPlayer->GetSubtitleName(index, value);
1163 result["name"] = value;
1165 g_application.m_pPlayer->GetSubtitleLanguage(index, value);
1166 result["language"] = value;
1170 result = CVariant(CVariant::VariantTypeNull);
1176 result = CVariant(CVariant::VariantTypeNull);
1180 else if (property.Equals("subtitles"))
1182 result = CVariant(CVariant::VariantTypeArray);
1186 if (g_application.m_pPlayer)
1188 for (int index = 0; index < g_application.m_pPlayer->GetSubtitleCount(); index++)
1190 CVariant subtitle(CVariant::VariantTypeObject);
1191 subtitle["index"] = index;
1193 g_application.m_pPlayer->GetSubtitleName(index, value);
1194 subtitle["name"] = value;
1196 g_application.m_pPlayer->GetSubtitleLanguage(index, value);
1197 subtitle["language"] = value;
1199 result.append(subtitle);
1211 return InvalidParams;