diff --git a/Installer/WifiRemote_1_2_Installer.xmp2 b/Installer/WifiRemote_1_2_Installer.xmp2
index 9209845..608c7d0 100644
--- a/Installer/WifiRemote_1_2_Installer.xmp2
+++ b/Installer/WifiRemote_1_2_Installer.xmp2
@@ -168,8 +168,8 @@ Click Next to continue or Cancel to exit Setup.
6
27644
- true
- This version of WifiRemote requires MediaPortal 1.2.0 Beta or higher!
+ false
+ This version of WifiRemote requires MediaPortal 1.6 or higher!
MediaPortal
@@ -181,13 +181,13 @@ Click Next to continue or Cancel to exit Setup.
WifiRemote
d2277c74-fdce-4146-9e23-d080d1799f72
Shukuyen, DieBagger
- http://code.google.com/p/wifiremote/
+ https://github.com/MPExtended/WifiRemote
http://forum.team-mediaportal.com/mediaportal-plugins-47/wifiremote-tcp-remote-control-server-0-1-2011-05-05-a-96251
- http://wifiremote.googlecode.com/svn/trunk/Installer/update.xml
+ https://raw.github.com/MPExtended/WifiRemote/master/Installer/update.xml
0
- 7
- 1
+ 8
+ 0
0
WifiRemote is a process plugin for the popular opensource mediacenter software "MediaPortal".
@@ -195,14 +195,30 @@ Click Next to continue or Cancel to exit Setup.
It publishes a Bonjour Service on your local network which allows clients (for example an iPhone or Android app) to list all found MediaPortal installations and connect to it.
- - fixes problems with installed 4tr/argus tv plugins (oxan)
-- Improve playback of playlist items (albums, artists, folders), reduce ui
-refreshing (DieBagger)
+ Developers: The WifiRemote source code moved to github! Please go to https://github.com/MPExtended/WifiRemote to check it out and feel free to fork and submit pull requests!
+
+New in 0.8:
+- api level increased to 14
+- MediaPortal 1.6 only, switched to .NET 4
+- Request a screenshot with the screenshot command
+- Fixed missing text in dialogs
+- Fixed crash related to music db changes in MediaPortal 1.6 (thanks, sebastiii!)
+- Fixed crash when encountering music with special chars in it (thanks, Martin K.!)
+- Added Artist to now playing radio message (thanks, johanj!)
+- Added methods for setting playlist repeat and shuffle (thanks, johanj!)
+- Improved starting radio channel (thanks, johanj!)
+- Send open dialogs to connecting clients
+- Send facade info to connecting clients
+- Added ViewType property to FacadeInfo message
+- Added support for the trakt plugin rating dialog
+
+
+
Stable
- http://wifiremote.googlecode.com/files/WifiRemote_0.6.1.mpe1
- 2012-11-25T20:16:04
+ https://github.com/MPExtended/WifiRemote/releases/download/Release_0_8/WifiRemote_0.8.mpe1
+ 2014-01-03T20:16:04
remote, wifi, json, client control
- WifiRemote_0.7.1.mpe1
+ WifiRemote_0.8.mpe1
@@ -255,14 +271,14 @@ refreshing (DieBagger)
OverwriteIfOlder
installer_logo.gif
- Installer{CopyFile}\{f8f8413e-7b79-4951-a9e2-dc8617a03a55}-installer_logo.gif
+ Installer{CopyFile}\{5c4acac1-409f-40b4-bdcb-fb143f49472d}-installer_logo.gif
OverwriteIfOlder
logo_radio.png
- Installer{CopyFile}\{5ab6c11c-a4ab-4d16-a13d-8f87806b783f}-logo_radio.png
+ Installer{CopyFile}\{76c05d6b-86b7-4bbc-9b74-e13e536cba88}-logo_radio.png
@@ -270,7 +286,7 @@ refreshing (DieBagger)
WifiRemote_1_2_Installer.xmp2
- D:\Documents\Visual Studio 2010\Projects\PluginDev\WifiRemote\WifiRemote\Installer\update.xml
+ D:\temp\wifiremote\Installer\update.xml
diff --git a/Installer/update.xml b/Installer/update.xml
index 568fbad..3175e23 100644
--- a/Installer/update.xml
+++ b/Installer/update.xml
@@ -73,12 +73,12 @@
1
0
- WifiRemote is a process plugin for the popular opensource mediacenter software "MediaPortal".
-
-
-
+ WifiRemote is a process plugin for the popular opensource mediacenter software "MediaPortal".
+
+
+
It publishes a Bonjour Service on your local network which allows clients (for example an iPhone or Android app) to list all found MediaPortal installations and connect to it.
- * fixes problems with installed 4tr/argus tv plugins (oxan)
+ * fixes problems with installed 4tr/argus tv plugins (oxan)
* Improve playback of playlist items (albums, artists, folders), reduce ui refreshing (DieBagger)
Stable
http://wifiremote.googlecode.com/files/WifiRemote_0.7.1.mpe1
@@ -95,8 +95,144 @@ It publishes a Bonjour Service on your local network which allows clients (for e
%Plugins%\process\WifiRemote.dll
Template
- The file used to configure the extension.
- If have .exe extension the will be executed
+ The file used to configure the extension.
+ If have .exe extension the will be executed
+ If have .dll extension used like MP plugin configuration
+
+
+
+ String
+ Online stored screenshot urls separated by ;
+
+
+ YES
+ Bool
+ Show dialog and force to uninstall previous version when updating an extension. Should only be disabled if you are using an NSIS/MSI installer.
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ 2.0
+
+
+
+ Default
+ true
+ Default
+
+
+
+
+
+ plugin_files
+ true
+ plugin_files
+
+
+
+
+
+ config_files
+ true
+ config_files
+
+
+
+
+
+
+
+
+
+
+
+
+ MediaPortal
+
+
+ 1
+ 1
+ 6
+ 27644
+
+
+ 1
+ 1
+ 6
+ 27644
+
+ false
+ This version of WifiRemote requires MediaPortal 1.6 or higher!
+ MediaPortal
+
+
+
+
+
+
+
+ WifiRemote
+ d2277c74-fdce-4146-9e23-d080d1799f72
+ Shukuyen, DieBagger
+ https://github.com/MPExtended/WifiRemote
+ http://forum.team-mediaportal.com/mediaportal-plugins-47/wifiremote-tcp-remote-control-server-0-1-2011-05-05-a-96251
+ https://raw.github.com/MPExtended/WifiRemote/master/Installer/update.xml
+
+ 0
+ 8
+ 0
+ 0
+
+ WifiRemote is a process plugin for the popular opensource mediacenter software "MediaPortal".
+
+
+
+It publishes a Bonjour Service on your local network which allows clients (for example an iPhone or Android app) to list all found MediaPortal installations and connect to it.
+ Developers: The WifiRemote source code moved to github! Please go to https://github.com/MPExtended/WifiRemote to check it out and feel free to fork and submit pull requests!
+
+New in 0.8:
+- api level increased to 14
+- MediaPortal 1.6 only, switched to .NET 4
+- Request a screenshot with the screenshot command
+- Fixed missing text in dialogs
+- Fixed crash related to music db changes in MediaPortal 1.6 (thanks, sebastiii!)
+- Fixed crash when encountering music with special chars in it (thanks, Martin K.!)
+- Added Artist to now playing radio message (thanks, johanj!)
+- Added methods for setting playlist repeat and shuffle (thanks, johanj!)
+- Improved starting radio channel (thanks, johanj!)
+- Send open dialogs to connecting clients
+- Send facade info to connecting clients
+- Added ViewType property to FacadeInfo message
+- Added support for the trakt plugin rating dialog
+
+
+
+ Stable
+ https://github.com/MPExtended/WifiRemote/releases/download/Release_0_8/WifiRemote_0.8.mpe1
+ 2014-01-03T20:16:04
+ remote, wifi, json, client control
+ WifiRemote_0.8.mpe1
+
+
+
+
+ String
+ The icon file of the package stored online (jpg,png,bmp)
+
+
+ %Plugins%\process\WifiRemote.dll
+ Template
+ The file used to configure the extension.
+ If have .exe extension the will be executed
If have .dll extension used like MP plugin configuration
diff --git a/Libs/Common.Utils.dll b/Libs/Common.Utils.dll
new file mode 100644
index 0000000..93c16d3
Binary files /dev/null and b/Libs/Common.Utils.dll differ
diff --git a/Libs/Core.dll b/Libs/Core.dll
new file mode 100644
index 0000000..ac5ce4c
Binary files /dev/null and b/Libs/Core.dll differ
diff --git a/Libs/Cornerstone.MP.dll b/Libs/Cornerstone.MP.dll
new file mode 100644
index 0000000..fe4f538
Binary files /dev/null and b/Libs/Cornerstone.MP.dll differ
diff --git a/Libs/Cornerstone.dll b/Libs/Cornerstone.dll
new file mode 100644
index 0000000..fd51f71
Binary files /dev/null and b/Libs/Cornerstone.dll differ
diff --git a/Libs/Databases.dll b/Libs/Databases.dll
new file mode 100644
index 0000000..08022ad
Binary files /dev/null and b/Libs/Databases.dll differ
diff --git a/Libs/Dialogs.dll b/Libs/Dialogs.dll
new file mode 100644
index 0000000..cb8bd36
Binary files /dev/null and b/Libs/Dialogs.dll differ
diff --git a/Libs/Gentle.Common.dll b/Libs/Gentle.Common.dll
index f6e2b60..1aa4f88 100644
Binary files a/Libs/Gentle.Common.dll and b/Libs/Gentle.Common.dll differ
diff --git a/Libs/Gentle.Framework.dll b/Libs/Gentle.Framework.dll
index cd71566..06d8b86 100644
Binary files a/Libs/Gentle.Framework.dll and b/Libs/Gentle.Framework.dll differ
diff --git a/Libs/MP-TVSeries.dll b/Libs/MP-TVSeries.dll
new file mode 100644
index 0000000..d58e225
Binary files /dev/null and b/Libs/MP-TVSeries.dll differ
diff --git a/Libs/MPNotificationBar.dll b/Libs/MPNotificationBar.dll
index 2a31a06..47610e8 100644
Binary files a/Libs/MPNotificationBar.dll and b/Libs/MPNotificationBar.dll differ
diff --git a/Libs/MediaPortal.Support.dll b/Libs/MediaPortal.Support.dll
new file mode 100644
index 0000000..cdcf474
Binary files /dev/null and b/Libs/MediaPortal.Support.dll differ
diff --git a/Libs/MovingPictures.dll b/Libs/MovingPictures.dll
new file mode 100644
index 0000000..96c9e97
Binary files /dev/null and b/Libs/MovingPictures.dll differ
diff --git a/Libs/RemotePlugins.dll b/Libs/RemotePlugins.dll
new file mode 100644
index 0000000..06f313e
Binary files /dev/null and b/Libs/RemotePlugins.dll differ
diff --git a/Libs/TVDatabase.dll b/Libs/TVDatabase.dll
index 246fb68..973480e 100644
Binary files a/Libs/TVDatabase.dll and b/Libs/TVDatabase.dll differ
diff --git a/Libs/TraktPlugin.dll b/Libs/TraktPlugin.dll
new file mode 100644
index 0000000..72c3102
Binary files /dev/null and b/Libs/TraktPlugin.dll differ
diff --git a/Libs/TvPlugin.dll b/Libs/TvPlugin.dll
index 5d5162c..0c4c6a4 100644
Binary files a/Libs/TvPlugin.dll and b/Libs/TvPlugin.dll differ
diff --git a/Libs/Utils.dll b/Libs/Utils.dll
new file mode 100644
index 0000000..9911c06
Binary files /dev/null and b/Libs/Utils.dll differ
diff --git a/Libs/WindowPlugins.dll b/Libs/WindowPlugins.dll
new file mode 100644
index 0000000..8129cc5
Binary files /dev/null and b/Libs/WindowPlugins.dll differ
diff --git a/Libs/taglib-sharp.dll b/Libs/taglib-sharp.dll
new file mode 100644
index 0000000..744c36c
Binary files /dev/null and b/Libs/taglib-sharp.dll differ
diff --git a/README.md b/README.md
index 2d64e19..d69cb13 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,15 @@ At the moment you can build the plugin in Visual Studio and run it on your HTPC,
Please copy the WifiRemote.xml file to your MediaPortal custom keymaps folder.
### Building a client
-If you want to build a client app for this plugin please contact me via PM on the MediaPortal forum (user Shukuyen). In the future I will add complete information on how to build a client app to the wiki. I am developing a client app for iPhone myself, DieBagger is developing an Android remote app.
+You should start by taking a look at the DemoClient app, included in the WifiRemote solution.
+This app shows how you can discover a server via Bonjour, connect to it, issue commands and receive messages. It also introduces the concept of the autologin key. The DemoClient app is written in C# but should be relatively easy to understand. If you have questions about this please contact me via PM on the MediaPortal forum (user Shukuyen).
+
+JSON messages sent from your client to WifiRemote are called commands. You can find a list of available commands here:
+http://wiki.team-mediaportal.com/1_MEDIAPORTAL_1/17_Extensions/3_Plugins/WifiRemote/Commands
+
+WifiRemote will send JSON messages to your client, a list can be found here:
+http://wiki.team-mediaportal.com/1_MEDIAPORTAL_1/17_Extensions/3_Plugins/WifiRemote/Messages
-[A list of messages sent from and to WifiRemote is available here.](http://code.google.com/p/wifiremote/wiki/APIDocumentation)
### Acknowledgements
WifiRemote uses the following libraries:
diff --git a/Sources/DemoClient/Messages/MessageScreenshot.cs b/Sources/DemoClient/Messages/MessageScreenshot.cs
new file mode 100644
index 0000000..034b8a9
--- /dev/null
+++ b/Sources/DemoClient/Messages/MessageScreenshot.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace DemoClient
+{
+ class MessageScreenshot : IMessage
+ {
+ string type = "screenshot";
+ public string Type
+ {
+ get { return type; }
+ }
+
+ public int Width
+ {
+ get { return 800; }
+ }
+
+ public String AutologinKey
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/Sources/WifiRemote/Core/SetupForm.cs b/Sources/WifiRemote/Core/SetupForm.cs
index 125a6be..ab6aa57 100644
--- a/Sources/WifiRemote/Core/SetupForm.cs
+++ b/Sources/WifiRemote/Core/SetupForm.cs
@@ -172,8 +172,8 @@ public SetupForm()
pluginsDataSource.Add(new WindowPlugin(aSavedPlugin.Value,
aSavedPlugin.Key,
(plugin.ActiveImage != null)
- ? WifiRemote.imageToByteArray(plugin.ActiveImage, System.Drawing.Imaging.ImageFormat.Png)
- : WifiRemote.imageToByteArray(Properties.Resources.NoPluginImage, System.Drawing.Imaging.ImageFormat.Png),
+ ? ImageHelper.imageToByteArray(plugin.ActiveImage, System.Drawing.Imaging.ImageFormat.Png)
+ : ImageHelper.imageToByteArray(Properties.Resources.NoPluginImage, System.Drawing.Imaging.ImageFormat.Png),
!ignoredPluginsList.Contains(aSavedPlugin.Key)));
}
break;
@@ -512,9 +512,9 @@ private void addPluginToList(ItemTag plugin)
{
pluginsDataSource.Add(
new WindowPlugin(plugin.SetupForm.PluginName(),
- plugin.WindowId,
- (plugin.ActiveImage != null) ? WifiRemote.imageToByteArray(plugin.ActiveImage, System.Drawing.Imaging.ImageFormat.Png)
- : WifiRemote.imageToByteArray(Properties.Resources.NoPluginImage, System.Drawing.Imaging.ImageFormat.Png),
+ plugin.WindowId,
+ (plugin.ActiveImage != null) ? ImageHelper.imageToByteArray(plugin.ActiveImage, System.Drawing.Imaging.ImageFormat.Png)
+ : ImageHelper.imageToByteArray(Properties.Resources.NoPluginImage, System.Drawing.Imaging.ImageFormat.Png),
!ignoredPluginsList.Contains(plugin.WindowId)));
}
}
diff --git a/Sources/WifiRemote/Core/SocketServer.cs b/Sources/WifiRemote/Core/SocketServer.cs
index 11d04c7..b6acbbd 100644
--- a/Sources/WifiRemote/Core/SocketServer.cs
+++ b/Sources/WifiRemote/Core/SocketServer.cs
@@ -42,6 +42,8 @@ class SocketServer
private List connectedSockets;
private AuthMethod allowedAuth;
private List loginTokens;
+ private Dictionary socketsWaitingForScreenshot;
+ private ImageHelper imageHelper;
private MessageWelcome welcomeMessage;
private MessageStatus statusMessage;
@@ -415,6 +417,25 @@ internal void SendListViewStatusToClient(AsyncSocket sender)
}
}
+ ///
+ /// Send the current screenshot to the client as byte array
+ ///
+ public void SendScreenshotToClient(AsyncSocket sender, int width, ImageHelperError error)
+ {
+ MessageScreenshot screenshot = new MessageScreenshot();
+
+ if (error != null)
+ {
+ screenshot.Error = error;
+ }
+ else
+ {
+ screenshot.Screenshot = imageHelper.resizedScreenshot(width);
+ }
+
+ SendMessageToClient(screenshot, sender);
+ }
+
///
/// A client connected.
///
@@ -769,6 +790,30 @@ void newSocket_DidRead(AsyncSocket sender, byte[] data, long tag)
SendImageToClient(sender, path, (string)message["UserTag"], imageWidth, imageHeight);
}
}
+ // screenshot action
+ else if (type == "screenshot")
+ {
+ if (socketsWaitingForScreenshot == null)
+ {
+ socketsWaitingForScreenshot = new Dictionary();
+ }
+
+ // Width to resize the image to, 0 to keep original width
+ int imageWidth = (message["Width"] != null) ? (int)message["Width"] : 0;
+
+ // Requests are added to a "waiting queue" because taking the screenshot happens
+ // async.
+ socketsWaitingForScreenshot.Add(sender, imageWidth);
+
+ if (imageHelper == null)
+ {
+ imageHelper = new ImageHelper();
+ imageHelper.ScreenshotReady += new ImageHelper.ScreenshotReadyCallback(imageHelperScreenshotReady);
+ imageHelper.ScreenshotFailed += new ImageHelper.ScreenshotFailedCallback(imageHelperScreenshotFailed);
+ }
+
+ imageHelper.TakeScreenshot();
+ }
//playlist actions
else if (type == "playlist")
{
@@ -821,7 +866,7 @@ void newSocket_DidRead(AsyncSocket sender, byte[] data, long tag)
else if (type == "showdialog")
{
ShowDialogMessageHandler.HandleShowDialogMessage(message, this, sender);
-
+
}
else
{
@@ -1157,6 +1202,13 @@ private void sendOverviewInformationToClient(AsyncSocket client)
// Send facade info to client
SendListViewStatusToClient(client);
+
+ // Inform client about open dialogs
+ if (MpDialogsHelper.IsDialogShown)
+ {
+ MessageDialog msg = MpDialogsHelper.GetDialogMessage(MpDialogsHelper.CurrentDialog);
+ SendMessageToClient(msg, client);
+ }
}
///
@@ -1179,5 +1231,32 @@ private String getRandomMD5()
return hash.ToString();
}
+
+ ///
+ /// A requested screenshot is ready, send it to all interested clients
+ ///
+ void imageHelperScreenshotReady()
+ {
+ foreach (var pair in socketsWaitingForScreenshot)
+ {
+ SendScreenshotToClient(pair.Key, pair.Value, null);
+ }
+
+ socketsWaitingForScreenshot = null;
+ }
+
+ ///
+ /// The screenshot could not be taken. Inform clients.
+ ///
+ ///
+ void imageHelperScreenshotFailed(ImageHelperError error)
+ {
+ foreach (var pair in socketsWaitingForScreenshot)
+ {
+ SendScreenshotToClient(pair.Key, pair.Value, error);
+ }
+
+ socketsWaitingForScreenshot = null;
+ }
}
}
diff --git a/Sources/WifiRemote/Core/WifiRemote.cs b/Sources/WifiRemote/Core/WifiRemote.cs
index 0519dd6..973e0f2 100644
--- a/Sources/WifiRemote/Core/WifiRemote.cs
+++ b/Sources/WifiRemote/Core/WifiRemote.cs
@@ -10,7 +10,6 @@
using System.Net.NetworkInformation;
using System.Collections;
using System.Drawing;
-using System.IO;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
@@ -166,6 +165,15 @@ public static bool IsAvailableTVSeries
set;
}
+ ///
+ /// true
if trakt plugin is available
+ ///
+ public static bool IsAvailableTrakt
+ {
+ get;
+ set;
+ }
+
///
/// true
if Fanart Handler is available
///
@@ -295,6 +303,7 @@ public void Start()
!IsAssemblyAvailable("ForTheRecord.UI.MediaPortal", null);
WifiRemote.IsAvailableMovingPictures = IsAssemblyAvailable("MovingPictures", new Version(1, 0, 6, 1116));
WifiRemote.IsAvailableTVSeries = IsAssemblyAvailable("MP-TVSeries", new Version(2, 6, 3, 1242));
+ WifiRemote.IsAvailableTrakt = IsAssemblyAvailable("TraktPlugin", new Version(3, 0));
WifiRemote.IsAvailableFanartHandler = IsAssemblyAvailable("FanartHandler", new Version(2, 2, 1, 19191));
WifiRemote.IsAvailableNotificationBar = IsAssemblyAvailable("MPNotificationBar", new Version(0, 8, 2, 1));
@@ -829,26 +838,6 @@ public static string GetServiceName()
}
}
-
- ///
- /// Returns an image as its byte array representation.
- /// Used to make images encodable in JSON.
- ///
- ///
- ///
- public static byte[] imageToByteArray(Image img, System.Drawing.Imaging.ImageFormat format)
- {
- byte[] byteArray = new byte[0];
- using (MemoryStream stream = new MemoryStream())
- {
- img.Save(stream, format);
- stream.Close();
- byteArray = stream.ToArray();
- }
-
- return byteArray;
- }
-
#endregion
#region WifiRemote methods
@@ -992,7 +981,7 @@ internal static ArrayList GetActiveWindowPluginsAndIDs(bool sendIcons)
if (icon != null)
{
- iconBytes = WifiRemote.imageToByteArray(icon, System.Drawing.Imaging.ImageFormat.Png);
+ iconBytes = ImageHelper.imageToByteArray(icon, System.Drawing.Imaging.ImageFormat.Png);
}
}
}
diff --git a/Sources/WifiRemote/ILMerge.exe b/Sources/WifiRemote/ILMerge.exe
index 5f4099f..9667425 100644
Binary files a/Sources/WifiRemote/ILMerge.exe and b/Sources/WifiRemote/ILMerge.exe differ
diff --git a/Sources/WifiRemote/MPDialogs/MpDialog.cs b/Sources/WifiRemote/MPDialogs/MpDialog.cs
index 380a089..857c7ec 100644
--- a/Sources/WifiRemote/MPDialogs/MpDialog.cs
+++ b/Sources/WifiRemote/MPDialogs/MpDialog.cs
@@ -58,12 +58,13 @@ public String GetLabel(GUIDialogWindow dialog, params int[] controlIds)
String t = GetSingleLabel(dialog, control);
if (t != null && !t.Equals(""))
{
- text.Append(t);
if (index > 0)
{
text.AppendLine();
}
index++;
+
+ text.Append(t);
}
}
@@ -81,20 +82,38 @@ private string GetSingleLabel(GUIDialogWindow dialog, int control)
GUIControlCollection coll = dialog.controlList;
foreach (GUIControl c in coll)
{
- if (c.GetID == control)
+ if (c.GetType() == typeof(GUIGroup))
{
- if (c.GetType() == typeof(GUILabelControl))
- {
- GUILabelControl l = (GUILabelControl)c;
- return l.Label;
- }
- else if (c.GetType() == typeof(GUIFadeLabel))
+ foreach (GUIControl subControl in ((GUIGroup)c).Children)
{
- GUIFadeLabel l = (GUIFadeLabel)c;
- return l.Label;
+ if (subControl.GetID == control)
+ {
+ return GetSingleLabelFromControl(subControl);
+ }
}
}
+ else if (c.GetID == control)
+ {
+ return GetSingleLabelFromControl(c);
+ }
}
+
+ return null;
+ }
+
+ private string GetSingleLabelFromControl(GUIControl control)
+ {
+ if (control.GetType() == typeof(GUILabelControl))
+ {
+ GUILabelControl label = (GUILabelControl)control;
+ return label.Label;
+ }
+ else if (control.GetType() == typeof(GUIFadeLabel))
+ {
+ GUIFadeLabel label = (GUIFadeLabel)control;
+ return label.Label;
+ }
+
return null;
}
diff --git a/Sources/WifiRemote/MPDialogs/MpDialogTraktRating.cs b/Sources/WifiRemote/MPDialogs/MpDialogTraktRating.cs
new file mode 100644
index 0000000..b7c6fdc
--- /dev/null
+++ b/Sources/WifiRemote/MPDialogs/MpDialogTraktRating.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TraktPlugin;
+
+namespace WifiRemote.MPDialogs
+{
+ public class MpDialogTraktRating : MpDialog
+ {
+ TraktPlugin.GUI.GUIRateDialog mpDialog;
+ public MpDialogTraktRating(TraktPlugin.GUI.GUIRateDialog dialog)
+ : base(dialog)
+ {
+ this.mpDialog = dialog;
+ this.DialogType = dialog.GetModuleName();
+ this.DialogId = dialog.GetID;
+ this.Rating = ratingFromTraktRateValue(dialog.Rated);
+ this.ShowAdvancedRatings = dialog.ShowAdvancedRatings;
+ GetHeading(dialog, 1);
+ GetText(dialog, 2, 3, 4, 5);
+
+ this.AvailableActions.Add("cancel");
+ this.AvailableActions.Add("setrating");
+ this.AvailableActions.Add("confirmrating");
+ }
+
+ private int ratingFromTraktRateValue(TraktPlugin.TraktAPI.TraktRateValue rateValue)
+ {
+ switch (rateValue)
+ {
+ case TraktPlugin.TraktAPI.TraktRateValue.unrate:
+ return 0;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.one:
+ case TraktPlugin.TraktAPI.TraktRateValue.hate:
+ return 1;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.two:
+ return 2;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.three:
+ return 3;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.four:
+ return 4;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.five:
+ return 5;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.six:
+ return 6;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.seven:
+ return 7;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.eight:
+ return 8;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.nine:
+ return 9;
+
+ case TraktPlugin.TraktAPI.TraktRateValue.ten:
+ case TraktPlugin.TraktAPI.TraktRateValue.love:
+ return 10;
+ }
+
+ return 0;
+ }
+
+ ///
+ /// Current Rating
+ ///
+ public int Rating { get; set; }
+
+ ///
+ /// true
if the dialog uses advanced rating (1-10), otherwise 'love' (1) and 'hate' (2) are used.
+ ///
+ public bool ShowAdvancedRatings { get; set; }
+
+ ///
+ /// Handle actions which are available on this dialog
+ ///
+ /// Action to execute
+ /// Index (e.g. needed for lists)
+ public override void HandleAction(String action, int index)
+ {
+ base.HandleAction(action, index);
+
+ if (action.Equals("setrating"))
+ {
+ SetRating(index);
+ }
+
+ if (action.Equals("confirmrating"))
+ {
+ ConfirmRating();
+ }
+ }
+
+ public void ConfirmRating()
+ {
+ MediaPortal.GUI.Library.Action confirmAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.ACTION_SELECT_ITEM, 0, 0);
+ mpDialog.OnAction(confirmAction);
+ }
+
+ ///
+ /// Set Rating for this dialog
+ ///
+ ///
+ public void SetRating(int rating)
+ {
+ MediaPortal.GUI.Library.Action ratingAction = null; ;
+ switch (rating)
+ {
+ case 1:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_1, 0, 0);
+ break;
+ case 2:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_2, 0, 0);
+ break;
+ case 3:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_3, 0, 0);
+ break;
+ case 4:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_4, 0, 0);
+ break;
+ case 5:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_5, 0, 0);
+ break;
+ case 6:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_6, 0, 0);
+ break;
+ case 7:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_7, 0, 0);
+ break;
+ case 8:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_8, 0, 0);
+ break;
+ case 9:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_9, 0, 0);
+ break;
+ case 10:
+ ratingAction = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.REMOTE_0, 0, 0);
+ break;
+ }
+
+ if (ratingAction != null)
+ {
+ mpDialog.OnAction(ratingAction);
+ }
+ }
+ }
+}
diff --git a/Sources/WifiRemote/MPDialogs/MpDialogsHelper.cs b/Sources/WifiRemote/MPDialogs/MpDialogsHelper.cs
index 280a8e4..ec73cda 100644
--- a/Sources/WifiRemote/MPDialogs/MpDialogsHelper.cs
+++ b/Sources/WifiRemote/MPDialogs/MpDialogsHelper.cs
@@ -32,6 +32,11 @@ public class MpDialogsHelper
///
public const int MOPI_PIN_ID = 9915;
+ ///
+ /// Id of the Trakt rating dialog
+ ///
+ public const int TRAKT_RATING_ID = 87300;
+
///
/// Is a dialog currently shown
///
@@ -99,6 +104,13 @@ public static MpDialog GetDialog(GUIDialogWindow dialog)
return GetDialogMovingPicturesPin();
}
}
+ if (WifiRemote.IsAvailableTrakt)
+ {
+ if (TraktHelper.IsTraktRatingDialog(dialog))
+ {
+ return GetDialogTraktRating();
+ }
+ }
return null;
}
@@ -125,7 +137,7 @@ public static MpDialogTvSeriesPin GetDialogMpTvSeriesPin()
}
///
- /// Get WifiRemote representation of the MpTvSeries rating dialog
+ /// Get WifiRemote representation of the MpMovingPictures rating dialog
///
/// WifiRemote Dialog Instance
public static MpDialogMovingPicturesRating GetDialogMovingPicturesRating()
@@ -136,7 +148,7 @@ public static MpDialogMovingPicturesRating GetDialogMovingPicturesRating()
}
///
- /// Get WifiRemote representation of the MpTvSeries pin dialog
+ /// Get WifiRemote representation of the MpMovingPictures pin dialog
///
/// WifiRemote Dialog Instance
public static MpDialogMovingPicturesPin GetDialogMovingPicturesPin()
@@ -146,6 +158,17 @@ public static MpDialogMovingPicturesPin GetDialogMovingPicturesPin()
return pinDialog;
}
+ ///
+ /// Get WifiRemote representation of the MpTrakt rating dialog
+ ///
+ /// WifiRemote Dialog Instance
+ public static MpDialogTraktRating GetDialogTraktRating()
+ {
+ TraktPlugin.GUI.GUIRateDialog menu = (TraktPlugin.GUI.GUIRateDialog)GUIWindowManager.GetWindow(TRAKT_RATING_ID);
+ MpDialogTraktRating ratingDialog = new MpDialogTraktRating(menu);
+ return ratingDialog;
+ }
+
///
/// Get WifiRemote representation of the select dialog
///
diff --git a/Sources/WifiRemote/MPDialogs/MpDialogsMessageHandler.cs b/Sources/WifiRemote/MPDialogs/MpDialogsMessageHandler.cs
index c2916aa..b7fd448 100644
--- a/Sources/WifiRemote/MPDialogs/MpDialogsMessageHandler.cs
+++ b/Sources/WifiRemote/MPDialogs/MpDialogsMessageHandler.cs
@@ -101,6 +101,14 @@ internal static void HandleDialogAction(Newtonsoft.Json.Linq.JObject message, So
diag.HandleAction(action, index);
}
}
+ else if (dialogId == MpDialogsHelper.TRAKT_RATING_ID)
+ {
+ if (WifiRemote.IsAvailableTrakt)
+ {
+ MpDialogTraktRating dialog = MpDialogsHelper.GetDialogTraktRating();
+ dialog.HandleAction(action, index);
+ }
+ }
}
}
}
diff --git a/Sources/WifiRemote/MPPlayList/PlaylistHelper.cs b/Sources/WifiRemote/MPPlayList/PlaylistHelper.cs
index 9b258b7..31a477b 100644
--- a/Sources/WifiRemote/MPPlayList/PlaylistHelper.cs
+++ b/Sources/WifiRemote/MPPlayList/PlaylistHelper.cs
@@ -228,6 +228,24 @@ public static void Shuffle(string type)
PlayListPlayer.SingletonPlayer.GetPlaylist(plType).Shuffle();
}
+ ///
+ /// Set repeat if type is of the current playlist type
+ ///
+ /// Type of the playlist
+ public static void Repeat(string type, bool repeat)
+ {
+ WifiRemote.LogMessage("Set playlist repeat:" + repeat, WifiRemote.LogType.Debug);
+ PlayListType plType = GetTypeFromString(type);
+ WifiRemote.LogMessage("plType:" + plType, WifiRemote.LogType.Debug);
+ WifiRemote.LogMessage("currentType:" + PlayListPlayer.SingletonPlayer.CurrentPlaylistType , WifiRemote.LogType.Debug);
+ if (plType == PlayListPlayer.SingletonPlayer.CurrentPlaylistType)
+ {
+ PlayListPlayer playListPlayer = PlayListPlayer.SingletonPlayer;
+ playListPlayer.RepeatPlaylist = repeat;
+ RefreshPlaylistIfVisible();
+ }
+ }
+
///
/// Returns a playlistitem from a song
///
@@ -329,6 +347,31 @@ public static void RemoveItemFromPlaylist(String type, int index)
RefreshPlaylistIfVisible();
}
+ ///
+ /// Retrieves the name of the playlist
+ ///
+ /// Type of the playlist
+ public static String GetPlaylistName(String type)
+ {
+ PlayListType plType = GetTypeFromString(type);
+ PlayListPlayer playListPlayer = PlayListPlayer.SingletonPlayer;
+ PlayList playList = playListPlayer.GetPlaylist(plType);
+ WifiRemote.LogMessage("Playlist name test:" + playList.Name, WifiRemote.LogType.Debug);
+
+ return playList.Name;
+ }
+
+ ///
+ /// Retrieves the repeat mode of the playlist
+ ///
+ /// Type of the playlist
+ public static bool GetPlaylistRepeat(String type)
+ {
+ PlayListType plType = GetTypeFromString(type);
+ PlayListPlayer playListPlayer = PlayListPlayer.SingletonPlayer;
+ return playListPlayer.RepeatPlaylist;
+ }
+
///
/// Gets the playlist for a given type
///
diff --git a/Sources/WifiRemote/MPPlayList/PlaylistMessageHandler.cs b/Sources/WifiRemote/MPPlayList/PlaylistMessageHandler.cs
index 0d5a578..42b2987 100644
--- a/Sources/WifiRemote/MPPlayList/PlaylistMessageHandler.cs
+++ b/Sources/WifiRemote/MPPlayList/PlaylistMessageHandler.cs
@@ -108,6 +108,8 @@ internal static void HandlePlaylistMessage(Newtonsoft.Json.Linq.JObject message,
MessagePlaylistDetails returnPlaylist = new MessagePlaylistDetails();
returnPlaylist.PlaylistType = playlistType;
+ returnPlaylist.PlaylistName = PlaylistHelper.GetPlaylistName(playlistType);
+ returnPlaylist.PlaylistRepeat = PlaylistHelper.GetPlaylistRepeat(playlistType);
returnPlaylist.PlaylistItems = items;
socketServer.SendMessageToClient(returnPlaylist, sender);
@@ -158,6 +160,24 @@ internal static void HandlePlaylistMessage(Newtonsoft.Json.Linq.JObject message,
}
}
+ else if (action.Equals("shuffle"))
+ {
+ PlaylistHelper.Shuffle(playlistType);
+ }
+ else if (action.Equals("repeat"))
+ {
+ WifiRemote.LogMessage("Playlist action repeat", WifiRemote.LogType.Debug);
+ if (message["Repeat"] != null)
+ {
+ bool repeat = (bool)message["Repeat"];
+ PlaylistHelper.Repeat(playlistType, repeat);
+ }
+ else
+ {
+ WifiRemote.LogMessage("Must specify repeat to change playlist repeat mode", WifiRemote.LogType.Warn);
+ }
+
+ }
}
}
}
diff --git a/Sources/WifiRemote/Messages/MessageNowPlaying.cs b/Sources/WifiRemote/Messages/MessageNowPlaying.cs
index 06e27ac..e57e2b0 100644
--- a/Sources/WifiRemote/Messages/MessageNowPlaying.cs
+++ b/Sources/WifiRemote/Messages/MessageNowPlaying.cs
@@ -158,11 +158,7 @@ public IAdditionalNowPlayingInfo MediaInfo
// MyVideos movie
if (movie.ID > 0)
{
-#if COMPILE_FOR_1_2_0 || COMPILE_FOR_1_1_2 // MyVideos extended info available since MediaPortal 1.1.2 (Rev 26532)
return new NowPlayingVideo(movie);
-#else
- return null;
-#endif
}
else
// MovingPictures, TVSeries or something else
diff --git a/Sources/WifiRemote/Messages/MessagePlaylistDetails.cs b/Sources/WifiRemote/Messages/MessagePlaylistDetails.cs
index 541d203..73f086e 100644
--- a/Sources/WifiRemote/Messages/MessagePlaylistDetails.cs
+++ b/Sources/WifiRemote/Messages/MessagePlaylistDetails.cs
@@ -16,6 +16,16 @@ public string Type
get { return "playlistdetails"; }
}
+ ///
+ /// Repeat mode of the playlist
+ ///
+ public bool PlaylistRepeat { get; set; }
+
+ ///
+ /// Name of the playlist
+ ///
+ public String PlaylistName { get; set; }
+
///
/// Type of the playlist (currently supported: music, video)
///
diff --git a/Sources/WifiRemote/Messages/MessageScreenshot.cs b/Sources/WifiRemote/Messages/MessageScreenshot.cs
new file mode 100644
index 0000000..c4afda2
--- /dev/null
+++ b/Sources/WifiRemote/Messages/MessageScreenshot.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using MediaPortal.GUI.Library;
+using System.Drawing;
+
+
+namespace WifiRemote
+{
+ ///
+ /// Sends a screenshot to the client that requested it with the
+ /// screenshot command.
+ ///
+ class MessageScreenshot : IMessage
+ {
+ public string Type
+ {
+ get { return "screenshot"; }
+ }
+
+ byte[] screenshot = new byte[0];
+ ///
+ /// The requested screenshot as byte array
+ ///
+ public byte[] Screenshot
+ {
+ get;
+ set;
+ }
+
+ public ImageHelperError Error { get; set; }
+ }
+}
diff --git a/Sources/WifiRemote/Messages/MessageWelcome.cs b/Sources/WifiRemote/Messages/MessageWelcome.cs
index b9518ee..66ceaaf 100644
--- a/Sources/WifiRemote/Messages/MessageWelcome.cs
+++ b/Sources/WifiRemote/Messages/MessageWelcome.cs
@@ -10,7 +10,7 @@ namespace WifiRemote
class MessageWelcome : IMessage
{
string type = "welcome";
- int server_version = 13;
+ int server_version = 14;
AuthMethod authMethod = AuthMethod.UserPassword;
///
diff --git a/Sources/WifiRemote/Messages/Now Playing/NowPlayingMusic.cs b/Sources/WifiRemote/Messages/Now Playing/NowPlayingMusic.cs
index 28e3237..7e4ffb7 100644
--- a/Sources/WifiRemote/Messages/Now Playing/NowPlayingMusic.cs
+++ b/Sources/WifiRemote/Messages/Now Playing/NowPlayingMusic.cs
@@ -88,7 +88,7 @@ public NowPlayingMusic(Song song)
Track = song.Track;
TrackTotal = song.TrackTotal;
URL = song.URL;
- WebImage = song.WebImage;
+ WebImage = String.Empty;
Year = song.Year;
ImageName = MediaPortal.Util.Utils.GetAlbumThumbName(song.Artist, song.Album);
diff --git a/Sources/WifiRemote/Messages/Now Playing/NowPlayingRadio.cs b/Sources/WifiRemote/Messages/Now Playing/NowPlayingRadio.cs
index 4eeffd8..5e26b17 100644
--- a/Sources/WifiRemote/Messages/Now Playing/NowPlayingRadio.cs
+++ b/Sources/WifiRemote/Messages/Now Playing/NowPlayingRadio.cs
@@ -7,6 +7,7 @@
using System.Drawing;
using WifiRemote.MpExtended;
using TvDatabase;
+using MediaPortal.GUI.Library;
namespace WifiRemote
{
@@ -51,6 +52,15 @@ public string ChannelName
set;
}
+ ///
+ /// Name of the current artits
+ ///
+ public string ArtistName
+ {
+ get;
+ set;
+ }
+
///
/// Id of current program
///
@@ -165,20 +175,26 @@ public string CurrentUrl
public NowPlayingRadio()
{
TvPlugin.TVHome.Navigator.UpdateCurrentChannel();
- TvDatabase.Channel current = TvPlugin.TVHome.Navigator.Channel;
- if (current.IsWebstream())
- {
- IList details = current.ReferringTuningDetail();
- TuningDetail detail = details[0];
- CurrentProgramName = detail.Name;
- CurrentProgramId = detail.IdChannel;
- CurrentUrl = detail.Url;
+ TvDatabase.Channel current = TvPlugin.Radio.CurrentChannel;
+ if (current != null && current.IsWebstream())
+ {
+ if (current.ReferringTuningDetail() != null && current.ReferringTuningDetail().Count > 0)
+ {
+ IList details = current.ReferringTuningDetail();
+ TuningDetail detail = details[0];
+ CurrentProgramName = detail.Name;
+ CurrentProgramId = detail.IdChannel;
+ CurrentUrl = detail.Url;
+ ChannelName = GUIPropertyManager.GetProperty("#Play.Current.Album");
+ ArtistName = GUIPropertyManager.GetProperty("#Play.Current.Artist");
+ }
}
- else
+ else if (current != null && !current.IsWebstream())
{
ChannelId = current.IdChannel;
ChannelName = current.DisplayName;
+ ArtistName = GUIPropertyManager.GetProperty("#Play.Current.Artist");
if (current.CurrentProgram != null)
{
diff --git a/Sources/WifiRemote/PluginConnection/MpMusicHelper.cs b/Sources/WifiRemote/PluginConnection/MpMusicHelper.cs
index 56f24f0..da74167 100644
--- a/Sources/WifiRemote/PluginConnection/MpMusicHelper.cs
+++ b/Sources/WifiRemote/PluginConnection/MpMusicHelper.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using MediaPortal.Music.Database;
+using MediaPortal.Database;
using WifiRemote.MPPlayList;
using System.IO;
using MediaPortal.Playlists;
@@ -22,7 +23,8 @@ public class MpMusicHelper
public static void PlayMusicTrack(int trackId, int startPos)
{
List songs = new List();
- string sql = "select * from tracks where idTrack=" + trackId;
+
+ string sql = String.Format("select * from tracks where idTrack={0}", trackId);
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
@@ -40,7 +42,9 @@ public static void PlayMusicTrack(int trackId, int startPos)
public static void PlayAlbum(String albumArtist, String album, int startPos)
{
List songs = new List();
- string sql = "select * from tracks where strAlbumArtist like '%" + albumArtist + "%' AND strAlbum LIKE '%" + album + "%' order by iTrack ASC";
+ string sql = String.Format("select * from tracks where strAlbumArtist like '%{0}%' AND strAlbum LIKE '%{1}%' order by iTrack ASC",
+ DatabaseUtility.RemoveInvalidChars(albumArtist),
+ DatabaseUtility.RemoveInvalidChars(album));
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
@@ -64,7 +68,8 @@ public static void PlayAlbum(String albumArtist, String album, int startPos)
internal static void PlayArtist(string albumArtist, int startPos)
{
List songs = new List();
- string sql = "select * from tracks where strAlbumArtist like '%" + albumArtist + "%'";
+ string sql = String.Format("select * from tracks where strAlbumArtist like '%{0}%'",
+ DatabaseUtility.RemoveInvalidChars(albumArtist));
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
@@ -212,6 +217,7 @@ internal static MediaPortal.Playlists.PlayListItem CreatePlaylistItemFromMusicTr
List songs = new List();
string sql = "select * from tracks where idTrack=" + trackId;
+ DatabaseUtility.RemoveInvalidChars(sql);
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
@@ -232,7 +238,9 @@ internal static List CreatePlaylistItemsFromMusicAlbum(string albu
{
List returnList = new List();
List songs = new List();
- string sql = "select * from tracks where strAlbumArtist like '%" + albumArtist + "%' AND strAlbum LIKE '%" + album + "%'";
+ string sql = String.Format("select * from tracks where strAlbumArtist like '%{0}%' AND strAlbum LIKE '%{1}%'",
+ DatabaseUtility.RemoveInvalidChars(albumArtist),
+ DatabaseUtility.RemoveInvalidChars(album));
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
@@ -254,7 +262,8 @@ internal static List CreatePlaylistItemsFromMusicArtist(string alb
{
List returnList = new List();
List songs = new List();
- string sql = "select * from tracks where strAlbumArtist like '%" + albumArtist + "%'";
+ string sql = String.Format("select * from tracks where strAlbumArtist like '%{0}%'",
+ DatabaseUtility.RemoveInvalidChars(albumArtist));
MusicDatabase.Instance.GetSongsByFilter(sql, out songs, "tracks");
if (songs.Count > 0)
diff --git a/Sources/WifiRemote/PluginConnection/MpTvServerHelper.cs b/Sources/WifiRemote/PluginConnection/MpTvServerHelper.cs
index c9db22e..eaffbfc 100644
--- a/Sources/WifiRemote/PluginConnection/MpTvServerHelper.cs
+++ b/Sources/WifiRemote/PluginConnection/MpTvServerHelper.cs
@@ -109,37 +109,65 @@ public static void PlayRadioChannel(int channelId)
if (channel != null)
{
- if (g_Player.Playing && (!g_Player.IsTimeShifting || (g_Player.IsTimeShifting && channel.IsWebstream())))
+ if (GUIWindowManager.ActiveWindow != (int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_RADIO)
{
- WifiRemote.LogMessage("Stopping current media so we can start playing radio", WifiRemote.LogType.Debug);
- g_Player.Stop();
- }
- bool success;
- if (channel.IsWebstream())
- {
- IList details = channel.ReferringTuningDetail();
- TuningDetail detail = details[0];
- success = g_Player.PlayAudioStream(detail.Url);
- }
- else
- {
- success = TvPlugin.TVHome.ViewChannelAndCheck(channel);
+ WifiRemote.LogMessage("Radio Window not active, activating it", WifiRemote.LogType.Debug);
+ MediaPortal.GUI.Library.GUIWindowManager.ActivateWindow((int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_RADIO);
}
+ GUIPropertyManager.RemovePlayerProperties();
+ GUIPropertyManager.SetProperty("#Play.Current.ArtistThumb", channel.DisplayName);
+ GUIPropertyManager.SetProperty("#Play.Current.Album", channel.DisplayName);
+ GUIPropertyManager.SetProperty("#Play.Current.Title", channel.DisplayName);
+
+ GUIPropertyManager.SetProperty("#Play.Current.Title", channel.DisplayName);
string strLogo = Utils.GetCoverArt(Thumbs.Radio, channel.DisplayName);
if (string.IsNullOrEmpty(strLogo))
{
strLogo = "defaultMyRadioBig.png";
}
-
GUIPropertyManager.SetProperty("#Play.Current.Thumb", strLogo);
-
- if (GUIWindowManager.ActiveWindow != (int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_RADIO && !g_Player.Playing)
+
+ if (g_Player.Playing && !channel.IsWebstream())
{
- WifiRemote.LogMessage("Radio Window not active, activating it", WifiRemote.LogType.Debug);
- MediaPortal.GUI.Library.GUIWindowManager.ActivateWindow((int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_RADIO);
- }
- WifiRemote.LogMessage("Started radio channel " + channelId + " Success: " + success, WifiRemote.LogType.Info);
+ if (!g_Player.IsTimeShifting || (g_Player.IsTimeShifting && channel.IsWebstream()))
+ {
+ WifiRemote.LogMessage("Stopping current media so we can start playing radio", WifiRemote.LogType.Debug);
+ g_Player.Stop();
+ }
+ }
+ bool success = false;
+ if (channel.IsWebstream())
+ {
+ IList details = channel.ReferringTuningDetail();
+ TuningDetail detail = details[0];
+ WifiRemote.LogMessage("Play webStream:" +detail.Name + ", url:" + detail.Url, WifiRemote.LogType.Debug);
+ success = g_Player.PlayAudioStream(detail.Url);
+ GUIPropertyManager.SetProperty("#Play.Current.Title", channel.DisplayName);
+ }
+ else
+ {
+ // TV card radio channel
+ WifiRemote.LogMessage("Play TV card radio channel", WifiRemote.LogType.Debug);
+ //Check if same channel is alrady playing
+ if (g_Player.IsRadio && g_Player.Playing)
+ {
+ Channel currentlyPlaying = TvPlugin.TVHome.Navigator.Channel;
+ if (currentlyPlaying != null && currentlyPlaying.IdChannel == channel.IdChannel)
+ {
+ WifiRemote.LogMessage("Already playing TV card radio channel with id:" + channel.IdChannel + ", do not tune again", WifiRemote.LogType.Debug);
+ }
+ else
+ {
+ success = TvPlugin.TVHome.ViewChannelAndCheck(channel);
+ }
+ }
+ else
+ {
+ success = TvPlugin.TVHome.ViewChannelAndCheck(channel);
+ }
+ }
+ WifiRemote.LogMessage("Started radio channel " + channelId + " Success: " + success, WifiRemote.LogType.Debug);
}
else
{
diff --git a/Sources/WifiRemote/PluginConnection/TraktHelper.cs b/Sources/WifiRemote/PluginConnection/TraktHelper.cs
new file mode 100644
index 0000000..8126dba
--- /dev/null
+++ b/Sources/WifiRemote/PluginConnection/TraktHelper.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TraktPlugin.GUI;
+
+namespace WifiRemote
+{
+ class TraktHelper
+ {
+ ///
+ /// Check if a dialog is a trakt rating dialog
+ ///
+ /// Dialog
+ /// true/false ;)
+ internal static bool IsTraktRatingDialog(MediaPortal.Dialogs.GUIDialogWindow dialog)
+ {
+ if (dialog.GetType().Equals(typeof(TraktPlugin.GUI.GUIRateDialog)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/Sources/WifiRemote/Properties/AssemblyInfo.cs b/Sources/WifiRemote/Properties/AssemblyInfo.cs
index b400377..db485b5 100644
--- a/Sources/WifiRemote/Properties/AssemblyInfo.cs
+++ b/Sources/WifiRemote/Properties/AssemblyInfo.cs
@@ -1,20 +1,17 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-
-#if COMPILE_FOR_1_2_0
using MediaPortal.Common.Utils;
// Version Compatibility
// http://wiki.team-mediaportal.com/1_MEDIAPORTAL_1/18_Contribute/6_Plugins/Plugin_Related_Changes/1.1.0_to_1.2.0/Version_Compatibility
-[assembly: CompatibleVersion("1.1.6.27644")]
+[assembly: CompatibleVersion("1.5.100.0", "1.1.6.27644")]
//[assembly: UsesSubsystem("MP.DB.Music")]
//[assembly: UsesSubsystem("MP.DB.Videos")]
//[assembly: UsesSubsystem("MP.Config")]
//[assembly: UsesSubsystem("MP.Input.Mapping")]
//[assembly: UsesSubsystem("MP.Players")]
-#endif
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
@@ -46,5 +43,5 @@
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.7.0.0")]
-[assembly: AssemblyFileVersion("0.7.0.0")]
+[assembly: AssemblyVersion("0.8.0.0")]
+[assembly: AssemblyFileVersion("0.8.0.0")]
diff --git a/Sources/WifiRemote/Properties/Resources.Designer.cs b/Sources/WifiRemote/Properties/Resources.Designer.cs
index 2fea1da..2325733 100644
--- a/Sources/WifiRemote/Properties/Resources.Designer.cs
+++ b/Sources/WifiRemote/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.225
+// Runtime Version:4.0.30319.18052
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -60,6 +60,9 @@ internal Resources() {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
internal static System.Drawing.Bitmap NoPluginImage {
get {
object obj = ResourceManager.GetObject("NoPluginImage", resourceCulture);
diff --git a/Sources/WifiRemote/Utility/ImageHelper.cs b/Sources/WifiRemote/Utility/ImageHelper.cs
new file mode 100644
index 0000000..4e2685e
--- /dev/null
+++ b/Sources/WifiRemote/Utility/ImageHelper.cs
@@ -0,0 +1,415 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using System.IO;
+using MediaPortal.GUI.Library;
+
+namespace WifiRemote
+{
+ class ImageHelperError
+ {
+ public enum ImageHelperErrorType
+ {
+ WatcherCreate,
+ WatcherEnable,
+ DirectoryCreate,
+ Timeout,
+ ScreenshotRead
+ };
+
+ ///
+ /// Unique code for this error
+ ///
+ public int ErrorCode { get; set; }
+
+ ///
+ /// Descriptive message of this error
+ ///
+ public String ErrorMessage { get; set; }
+
+ public ImageHelperError(ImageHelperErrorType type)
+ {
+ setupExceptionWithType(type);
+ }
+
+ protected void setupExceptionWithType(ImageHelperErrorType type)
+ {
+ switch (type)
+ {
+ case ImageHelperErrorType.WatcherCreate:
+ ErrorCode = 10;
+ ErrorMessage = "Could not watch for MediaPortal screenshots.";
+ break;
+
+ case ImageHelperErrorType.WatcherEnable:
+ ErrorCode = 11;
+ ErrorMessage = "Error starting to watch for MediaPortal screenshots.";
+ break;
+
+ case ImageHelperErrorType.DirectoryCreate:
+ ErrorCode = 20;
+ ErrorMessage = "Could not create screenshot directory.";
+ break;
+
+ case ImageHelperErrorType.Timeout:
+ ErrorCode = 30;
+ ErrorMessage = "Timeout while waiting for MediaPortal to take the screenshot.";
+ break;
+
+ case ImageHelperErrorType.ScreenshotRead:
+ ErrorCode = 40;
+ ErrorMessage = "Could not read MediaPortal screenshot";
+ break;
+
+ default:
+ ErrorCode = 0;
+ ErrorMessage = "An unexpected error occured.";
+ break;
+ }
+ }
+ }
+
+ class ImageHelper
+ {
+ #region Take a MediaPortal screenshot
+
+ ///
+ /// Callback for when the screenshot was taken and is stored as a
+ /// byte array in the Screenshot property.
+ ///
+ public delegate void ScreenshotReadyCallback();
+
+ ///
+ /// Callback for when the screenshot could not be taken or processed.
+ ///
+ public delegate void ScreenshotFailedCallback(ImageHelperError error);
+
+ ///
+ /// Tracks if a screenshot is being made at the moment
+ ///
+ bool takingScreenshot;
+
+ ///
+ /// FileSystemWatcher watching for new screenshots
+ ///
+ FileSystemWatcher watcher;
+
+ ///
+ /// Path of the current screenshot
+ ///
+ String screenshotPath;
+
+ ///
+ /// Number of times the screenshot was tried to open.
+ /// We abort after maximumScreenshotOpenTries times to avoid an
+ /// infinite loop.
+ ///
+ uint screenshotOpenTries;
+
+ ///
+ /// Abort trying to open the screenshot after this number of tries.
+ ///
+ uint maximumScreenshotOpenTries;
+
+ private Image screenshot;
+ ///
+ /// The screenshot taken with the takeScreenshot() method
+ ///
+ public Image Screenshot
+ {
+ get { return screenshot; }
+ set { screenshot = value; }
+ }
+
+ public ImageHelper()
+ {
+ maximumScreenshotOpenTries = 20;
+ screenshotOpenTries = 0;
+ }
+
+ ///
+ /// Make MediaPortal take a screenshot, take that and delete it
+ /// from disk. First we need to check if the screenshot folder already exists.
+ /// See https://github.com/MediaPortal/MediaPortal-1/blob/cae80bd6dd2241bd7182c39418373bee545bf464/mediaportal/MediaPortal.Application/MediaPortal.cs#L3611
+ ///
+ public void TakeScreenshot()
+ {
+ // Only take one screenshot at a time, all requests
+ // will be served from that screenshot.
+ if (takingScreenshot)
+ {
+ return;
+ }
+
+ takingScreenshot = true;
+
+ // MediaPortal doesn't output events for new screenshots so we 'manually'
+ // watch the screenshot folder
+ setupFileSystemWatcher();
+
+ if (watcher == null)
+ {
+ // Something went wrong creating the filesystem watcher
+ takingScreenshot = false;
+ OnScreenshotFailed(new ImageHelperError(ImageHelperError.ImageHelperErrorType.WatcherCreate));
+ return;
+ }
+
+ if (!watcher.EnableRaisingEvents)
+ {
+ try
+ {
+ watcher.EnableRaisingEvents = true;
+ }
+ catch (Exception e)
+ {
+ WifiRemote.LogMessage(String.Format("Could not watch the screenshots folder: {0}", e.Message), WifiRemote.LogType.Error);
+ watcher = null;
+ takingScreenshot = false;
+ OnScreenshotFailed(new ImageHelperError(ImageHelperError.ImageHelperErrorType.WatcherEnable));
+ return;
+ }
+ }
+
+ // Take the screenshot
+ MediaPortal.GUI.Library.Action action = new MediaPortal.GUI.Library.Action(MediaPortal.GUI.Library.Action.ActionType.ACTION_TAKE_SCREENSHOT, 0, 0);
+ GUIGraphicsContext.OnAction(action);
+ }
+
+ ///
+ /// Returns the resized screenshot as a byte array.
+ ///
+ /// Width to resize the screenshot proportionally to, 0 to keep original
+ ///
+ public byte[] resizedScreenshot(int width)
+ {
+ if (Screenshot == null)
+ {
+ return new byte[0];
+ }
+
+ Image image = (width > 0) ? ImageHelper.ResizedImage(Screenshot, width) : Screenshot;
+ return ImageHelper.imageToByteArray(image, System.Drawing.Imaging.ImageFormat.Jpeg);
+ }
+
+ protected void setupFileSystemWatcher()
+ {
+ String directory = String.Format("{0}\\MediaPortal Screenshots\\{1:0000}-{2:00}-{3:00}",
+ Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
+ DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
+
+ if (!Directory.Exists(directory))
+ {
+ WifiRemote.LogMessage(String.Format("Creating screenshot directory: {0}", directory), WifiRemote.LogType.Info);
+
+ try
+ {
+ Directory.CreateDirectory(directory);
+ }
+ catch (Exception e)
+ {
+ WifiRemote.LogMessage(String.Format("Could not create screenshot directory {0}: {1}", directory, e.Message), WifiRemote.LogType.Error);
+ watcher = null;
+ takingScreenshot = false;
+ OnScreenshotFailed(new ImageHelperError(ImageHelperError.ImageHelperErrorType.DirectoryCreate));
+ return;
+ }
+ }
+
+ if (watcher == null)
+ {
+ // Add a filesystem watcher to be informed when MediaPortal creates the screenshot
+ watcher = new FileSystemWatcher(directory, "*.png");
+ watcher.Created += new FileSystemEventHandler(watcherCreated);
+ }
+ else if (!watcher.Path.Equals(directory))
+ {
+ // Date changed, update path
+ watcher.Path = directory;
+ }
+ }
+
+ ///
+ /// A screenshot was created
+ ///
+ ///
+ ///
+ protected void watcherCreated(object sender, FileSystemEventArgs e)
+ {
+ screenshotPath = e.FullPath;
+
+ // Wait until the screenshot is written to disk
+ System.Timers.Timer timer = new System.Timers.Timer(100);
+ timer.AutoReset = false;
+ timer.Elapsed += new System.Timers.ElapsedEventHandler(screenshotReadyCheck);
+ timer.Start();
+ }
+
+ protected void screenshotReadyCheck(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ ((System.Timers.Timer)sender).Stop();
+ if (IsScreenshotReady(screenshotPath))
+ {
+ // MediaPortal completed writing the screenshot to disk
+ // We can now grab and delete it
+ processScreenshot();
+ screenshotOpenTries = 0;
+ }
+ else
+ {
+ if (screenshotOpenTries < maximumScreenshotOpenTries)
+ {
+ // Continue checking if the file is locked
+ WifiRemote.LogMessage("Waiting for screenshot to be written ...", WifiRemote.LogType.Debug);
+ screenshotOpenTries++;
+ ((System.Timers.Timer)sender).Start();
+ }
+ else
+ {
+ WifiRemote.LogMessage("Maximum number of screenshot open tries reached, aborting.", WifiRemote.LogType.Debug);
+ OnScreenshotFailed(new ImageHelperError(ImageHelperError.ImageHelperErrorType.Timeout));
+ screenshotOpenTries = 0;
+ }
+ }
+ }
+
+ protected void processScreenshot()
+ {
+ try
+ {
+ using (FileStream stream = new FileStream(screenshotPath, FileMode.Open, FileAccess.Read))
+ {
+ Screenshot = Image.FromStream(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ WifiRemote.LogMessage(String.Format("Could not open screenshot file {0}: {1}", screenshotPath, ex.Message), WifiRemote.LogType.Error);
+ takingScreenshot = false;
+ OnScreenshotFailed(new ImageHelperError(ImageHelperError.ImageHelperErrorType.ScreenshotRead));
+ return;
+ }
+
+ // Delete the screenshot from disk
+ try
+ {
+ File.Delete(screenshotPath);
+
+ if (Directory.GetFiles(Path.GetDirectoryName(screenshotPath), "*.png").Length == 0)
+ {
+ // No screenshots in the screenshot folder, delete that as well
+ Directory.Delete(Path.GetDirectoryName(screenshotPath));
+ }
+ }
+ catch (Exception ex)
+ {
+ WifiRemote.LogMessage(String.Format("Could not delete screenshot or screenshot folder {0}: {1}", screenshotPath, ex.Message), WifiRemote.LogType.Info);
+ }
+
+ // Stop listening for new files
+ watcher.EnableRaisingEvents = false;
+
+ // Inform observers that the screenshot is now ready
+ OnScreenshotReady();
+ takingScreenshot = false;
+ }
+
+ ///
+ /// Check if the screenshot is locked.
+ ///
+ ///
+ ///
+ protected static bool IsScreenshotReady(String path)
+ {
+ // If the file can be opened for exclusive access it means that the file
+ // is no longer locked by another process.
+ try
+ {
+ using (FileStream inputStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
+ {
+ long streamLength = inputStream.Length;
+ return streamLength > 0;
+ }
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Screenshot ready event
+ ///
+ public event ScreenshotReadyCallback ScreenshotReady;
+ protected void OnScreenshotReady()
+ {
+ if (ScreenshotReady != null)
+ {
+ ScreenshotReady();
+ }
+ }
+
+ ///
+ /// Screenshot failed event
+ ///
+ public event ScreenshotFailedCallback ScreenshotFailed;
+ protected void OnScreenshotFailed(ImageHelperError error)
+ {
+ if (ScreenshotFailed != null)
+ {
+ ScreenshotFailed(error);
+ }
+ }
+
+ #endregion
+
+ #region Static utility methods
+
+ ///
+ /// Returns an image as its byte array representation.
+ /// Used to make images encodable in JSON.
+ ///
+ ///
+ ///
+ public static byte[] imageToByteArray(Image img, System.Drawing.Imaging.ImageFormat format)
+ {
+ byte[] byteArray = new byte[0];
+ using (MemoryStream stream = new MemoryStream())
+ {
+ img.Save(stream, format);
+ stream.Close();
+ byteArray = stream.ToArray();
+ }
+
+ return byteArray;
+ }
+
+ ///
+ /// Resizes an image to the target with. The height is calculated
+ /// proportionally to the source image height.
+ ///
+ /// The source image to resize
+ /// Target width for the resized image
+ ///
+ public static Image ResizedImage(Image source, int width)
+ {
+ if (source.Width <= width)
+ {
+ return source;
+ }
+
+ int height = (int)(source.Height / ((double)source.Width / (double)width));
+ Image target = new Bitmap(source, width, height);
+
+ return target;
+ }
+
+ #endregion
+ }
+}
diff --git a/Sources/WifiRemote/WifiRemote.csproj b/Sources/WifiRemote/WifiRemote.csproj
index 2c63d81..5c0e6c0 100644
--- a/Sources/WifiRemote/WifiRemote.csproj
+++ b/Sources/WifiRemote/WifiRemote.csproj
@@ -10,7 +10,7 @@
Properties
WifiRemote
WifiRemote
- v3.5
+ v4.0
512
@@ -39,7 +39,7 @@
full
false
bin\Debug\
- TRACE;DEBUG;COMPILE_FOR_1_2_0
+ TRACE;DEBUG
prompt
4
@@ -47,7 +47,7 @@
pdbonly
true
bin\Release\
- TRACE;COMPILE_FOR_1_1_2
+ TRACE
prompt
4
@@ -55,17 +55,18 @@
..\..\Libs\Common.Utils.dll
-
+
False
..\..\Libs\Core.dll
- ..\..\..\..\..\..\..\..\..\Program Files (x86)\Team MediaPortal\MediaPortal\plugins\Windows\Cornerstone.dll
+ ..\..\Libs\Cornerstone.dll
- ..\..\..\Libs\Cornerstone.MP.dll
+ ..\..\Libs\Cornerstone.MP.dll
-
+
+ False
..\..\Libs\Databases.dll
@@ -106,6 +107,9 @@
+
+ ..\..\Libs\TraktPlugin.dll
+
False
..\..\Libs\TVDatabase.dll
@@ -114,10 +118,12 @@
False
..\..\Libs\TvPlugin.dll
-
+
+ False
..\..\Libs\Utils.dll
-
+
+ False
..\..\Libs\WindowPlugins.dll
@@ -145,6 +151,7 @@
+
@@ -162,6 +169,7 @@
+
@@ -192,6 +200,7 @@
+
@@ -201,6 +210,7 @@
Resources.resx
+
diff --git a/Sources/WifiRemote/merge.bat b/Sources/WifiRemote/merge.bat
index 18671da..3d61b35 100644
--- a/Sources/WifiRemote/merge.bat
+++ b/Sources/WifiRemote/merge.bat
@@ -1,7 +1,7 @@
@echo off
IF EXIST WifiRemote_TMP.dll del WifiRemote_TMP.dll
IF EXIST WifiRemote_TMP.pdb del WifiRemote_TMP.pdb
-ilmerge /out:WifiRemote_TMP.dll WifiRemote.dll ZeroconfService.dll Newtonsoft.Json.Net35.dll zxing.dll
+ilmerge /out:WifiRemote_TMP.dll WifiRemote.dll ZeroconfService.dll Newtonsoft.Json.Net35.dll zxing.dll /targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
IF EXIST WifiRemote.dll del WifiRemote.dll
IF EXIST WifiRemote.pdb del WifiRemote.pdb