Go to the documentation of this file.00001
00009 package org.rosmultimedia.player.xbmc.internal;
00010
00011 import java.util.List;
00012
00013 import org.ros.message.Duration;
00014 import org.rosbuilding.common.media.IPlayer;
00015 import org.rosmultimedia.player.xbmc.XbmcNode;
00016 import org.rosmultimedia.player.xbmc.jsonrpc.XbmcJson;
00017 import org.xbmc.android.jsonrpc.api.call.GUI;
00018 import org.xbmc.android.jsonrpc.api.call.Input;
00019 import org.xbmc.android.jsonrpc.api.call.Player;
00020 import org.xbmc.android.jsonrpc.api.call.Player.GetActivePlayers.GetActivePlayersResult;
00021 import org.xbmc.android.jsonrpc.api.call.Playlist;
00022 import org.xbmc.android.jsonrpc.api.model.GUIModel;
00023 import org.xbmc.android.jsonrpc.api.model.GlobalModel.Toggle;
00024 import org.xbmc.android.jsonrpc.api.model.ListModel;
00025 import org.xbmc.android.jsonrpc.api.model.PlayerModel;
00026 import org.xbmc.android.jsonrpc.api.model.PlayerModel.PositionTime;
00027 import org.xbmc.android.jsonrpc.api.model.PlaylistModel;
00028
00029 import com.google.common.base.Strings;
00030
00031 import smarthome_media_msgs.MediaAction;
00032 import smarthome_media_msgs.MediaType;
00033 import smarthome_media_msgs.PlayerInfo;
00034 import smarthome_media_msgs.StateData;
00035
00042 public class XbmcPlayer implements IPlayer {
00043 private static final String XBMC_PLUGIN_YOUTUBE_URL =
00044 "plugin://plugin.video.youtube/?action=play_video&videoid=%s";
00045
00049 @SuppressWarnings("unused")
00050 private XbmcNode xbmcNode;
00051
00055 private XbmcJson xbmcJson;
00056
00062 public XbmcPlayer(XbmcJson xbmcJson, XbmcNode node) {
00063 this.xbmcJson = xbmcJson;
00064 this.xbmcNode = node;
00065 }
00066
00067 @Override
00068 public void load(StateData statedata) {
00069 this.load(statedata.getPlayer());
00070 }
00071
00072 public void load(PlayerInfo playerInfo) {
00073 this.resetInfo(playerInfo);
00074
00075 List<GetActivePlayersResult> players = this.xbmcJson
00076 .getResults(new Player.GetActivePlayers());
00077
00078 if (players != null && !players.isEmpty()) {
00079 GetActivePlayersResult player = players.get(0);
00080 this.updateInfo(playerInfo, player.playerid);
00081 }
00082 }
00083
00084 @Override
00085 public void callbackCmdAction(MediaAction message, StateData stateData) {
00086 switch (message.getMethod()) {
00087 case OP_PAUSE:
00088 this.xbmcJson.getResult(new Player.PlayPause(1, new Toggle(false)));
00089 break;
00090
00091 case OP_PLAY:
00092 this.xbmcJson.getResult(new Player.PlayPause(1, new Toggle(true)));
00093 break;
00094
00095 case OP_PLAYPAUSE:
00096 this.xbmcJson.getResult(new Player.PlayPause(1));
00097 break;
00098
00099 case OP_STOP:
00100 this.xbmcJson.getResult(new Player.Stop(1));
00101 break;
00102
00103 case OP_SPEED:
00104 if (stateData.getPlayer().getCanseek()) {
00105 int speed = Integer.parseInt(message.getData().get(0));
00106 this.xbmcJson.getResult(new Player.SetSpeed(1, speed));
00107 }
00108 break;
00109
00110 case OP_SPEED_UP:
00111 if (stateData.getPlayer().getCanseek()) {
00112 int speed = 2;
00113 this.xbmcJson.getResult(new Player.SetSpeed(1, speed));
00114 }
00115 break;
00116
00117 case OP_SPEED_DOWN:
00118 if (stateData.getPlayer().getCanseek()) {
00119 int speed = -2;
00120 this.xbmcJson.getResult(new Player.SetSpeed(1, speed));
00121 }
00122 break;
00123
00124 case OP_OPEN:
00125 this.xbmcJson.getResult(new Player.Open(this.makeItem(message)));
00126 break;
00127
00128 case OP_SEEK:
00129 if (stateData.getPlayer().getCanseek()) {
00130 this.xbmcJson.getResult(new Player.Seek(1, this
00131 .getPositionTime(message)));
00132 }
00133 break;
00134
00135 case OP_NEXT:
00136 if (stateData.getPlayer().getCanseek()) {
00137 this.xbmcJson.getResult(new Player.GoTo(1, Player.GoTo.To.NEXT));
00138 }
00139 break;
00140
00141 case OP_PREVIOUS:
00142 if (stateData.getPlayer().getCanseek()) {
00143 this.xbmcJson.getResult(new Player.GoTo(1, Player.GoTo.To.PREVIOUS));
00144 }
00145 break;
00146
00147 case OP_ADD_PLAYLIST:
00148
00149
00150 break;
00151
00152 case OP_INS_PLAYLIST:
00153
00154
00155 break;
00156
00157 case OP_REM_PLAYLIST:
00158
00159
00160 break;
00161
00162 case OP_CLR_PLAYLIST:
00163 this.xbmcJson.getResult(new Playlist.Clear(1));
00164 break;
00165
00166 case OP_BACK:
00167 this.xbmcJson.getResult(new Input.Back());
00168 break;
00169
00170 case OP_HOME:
00171 this.xbmcJson.getResult(new Input.Home());
00172 break;
00173
00174 case OP_INFO:
00175 this.xbmcJson.getResult(new Input.Info());
00176 break;
00177
00178 case OP_DISPLAY:
00179 this.xbmcJson.getResult(new Input.ShowOSD());
00180 break;
00181
00182 case OP_SELECT:
00183 if (stateData.getPlayer().getCanseek()) {
00184 message.setMethod(OP_PLAYPAUSE);
00185 this.callbackCmdAction(message, stateData);
00186 } else {
00187 this.xbmcJson.getResult(new Input.Select());
00188 }
00189 break;
00190
00191 case OP_CONTEXT:
00192 this.xbmcJson.getResult(new Input.ContextMenu());
00193 break;
00194
00195 case OP_UP:
00196 if (stateData.getPlayer().getCanseek()) {
00197 this.xbmcJson.getResult(new Player.Seek(1, Player.Seek.Value.BIGFORWARD));
00198 } else {
00199 this.xbmcJson.getResult(new Input.Up());
00200 }
00201 break;
00202
00203 case OP_DOWN:
00204 if (stateData.getPlayer().getCanseek()) {
00205 this.xbmcJson.getResult(new Player.Seek(1, Player.Seek.Value.BIGBACKWARD));
00206 } else {
00207 this.xbmcJson.getResult(new Input.Down());
00208 }
00209 break;
00210
00211 case OP_LEFT:
00212 if (stateData.getPlayer().getCanseek()) {
00213 this.xbmcJson.getResult(new Player.Seek(1, Player.Seek.Value.SMALLBACKWARD));
00214 } else {
00215 this.xbmcJson.getResult(new Input.Left());
00216 }
00217 break;
00218
00219 case OP_RIGHT:
00220 if (stateData.getPlayer().getCanseek()) {
00221 this.xbmcJson.getResult(new Player.Seek(1, Player.Seek.Value.SMALLFORWARD));
00222 } else {
00223 this.xbmcJson.getResult(new Input.Right());
00224 }
00225 break;
00226
00227 case OP_TXT:
00228 this.xbmcJson
00229 .getResult(new Input.SendText(message.getData().get(0)));
00230 break;
00231 }
00232 }
00233
00238 private void resetInfo(PlayerInfo playerInfo) {
00239 playerInfo.setCanseek(false);
00240 playerInfo.setMediaid(-1);
00241 playerInfo.getMediatype().setValue("");
00242 playerInfo.setStamp(new Duration(0, 0));
00243 playerInfo.setTotaltime(new Duration(0, 0));
00244 playerInfo.setSpeed(0);
00245 playerInfo.setSubtitleenabled(false);
00246 playerInfo.setFile("");
00247 playerInfo.setTitle("");
00248 playerInfo.setThumbnail("");
00249 }
00250
00256 private void updateInfo(PlayerInfo playerInfo, int playerid) {
00257 PlayerModel.PropertyValue playerProperty = this.xbmcJson
00258 .getResult(new Player.GetProperties(playerid,
00259
00260
00261
00262 "speed",
00263 "percentage",
00264 "audiostreams",
00265
00266
00267
00268
00269
00270
00271
00272
00273 "canseek",
00274 "time",
00275 "totaltime",
00276
00277 "currentaudiostream",
00278
00279 "subtitleenabled"));
00280
00281 GUIModel.PropertyValue guiProperty = this.xbmcJson
00282 .getResult(new GUI.GetProperties(
00283 "currentwindow",
00284 "currentcontrol"));
00285
00286 ListModel.AllItems itemProperty = this.xbmcJson
00287 .getResult(new Player.GetItem(playerid,
00288 "file",
00289 "title",
00290 "thumbnail"));
00291
00292 playerInfo.setCanseek(true);
00293
00294 if (playerProperty != null) {
00295 playerInfo.setStamp(new Duration(playerProperty.time.hours
00296 * 60 * 60 + playerProperty.time.minutes * 60
00297 + playerProperty.time.seconds,
00298 playerProperty.time.milliseconds * 100));
00299
00300 playerInfo.setTotaltime(new Duration(
00301 playerProperty.totaltime.hours * 60 * 60
00302 + playerProperty.totaltime.minutes * 60
00303 + playerProperty.totaltime.seconds,
00304 playerProperty.totaltime.milliseconds * 100));
00305
00306 playerInfo.setSpeed(playerProperty.speed);
00307 playerInfo.setCanseek(playerProperty.canseek);
00308 playerInfo.setSubtitleenabled(playerProperty.subtitleenabled);
00309 }
00310
00311 if (guiProperty != null) {
00312
00313 playerInfo.setCanseek(
00314 guiProperty.currentwindow.id == 12005
00315 || guiProperty.currentwindow.id == 12006);
00316 }
00317
00318 if (itemProperty != null) {
00319 playerInfo.setMediaid(0);
00320 playerInfo.getMediatype().setValue(itemProperty.type);
00321
00322 if (!playerInfo.getMediatype().getValue().equals(MediaType.UNKNOW)) {
00323 playerInfo.setMediaid(itemProperty.id);
00324 }
00325
00326 playerInfo.setFile(itemProperty.file);
00327 playerInfo.setTitle(itemProperty.title);
00328 playerInfo.setThumbnail(XbmcUtils.getImageUrl(itemProperty.thumbnail));
00329 }
00330 }
00331
00337 private PlaylistModel.Item makeItem(MediaAction msg) {
00338 PlaylistModel.Item item = null;
00339 String uri = msg.getUri();
00340
00341 if (!Strings.isNullOrEmpty(uri)) {
00342 if (uri.startsWith(IPlayer.URI_MEDIA_IMDB)) {
00343
00344
00345 } else if (uri.startsWith(IPlayer.URI_MEDIA_YOUTUBE)) {
00346 item = new PlaylistModel.Item(
00347 new PlaylistModel.Item.File(String.format(
00348 XBMC_PLUGIN_YOUTUBE_URL,
00349 uri.replace(IPlayer.URI_MEDIA_YOUTUBE, ""))));
00350 } else if (msg.getType().equals(MediaType.VIDEO_MOVIE)) {
00351 item = new PlaylistModel.Item(new PlaylistModel.Item.Movieid(
00352 Integer.parseInt(uri.replace(IPlayer.URI_MEDIA, ""))));
00353 } else if (msg.getType().equals(MediaType.VIDEO_TVSHOW_EPISODE)) {
00354 item = new PlaylistModel.Item(new PlaylistModel.Item.Episodeid(
00355 Integer.parseInt(uri.replace(IPlayer.URI_MEDIA, ""))));
00356 }
00357 }
00358
00359 return item;
00360 }
00361
00367 private PositionTime getPositionTime(MediaAction msg) {
00368 int time = Integer.parseInt(msg.getData().get(0));
00369
00370 int hours = time / 3600;
00371 int rem = time % 3600;
00372 int minutes = rem / 60;
00373 int seconds = rem % 60;
00374
00375 return new PositionTime(hours, 0, minutes, seconds);
00376 }
00377 }