diff options
Diffstat (limited to 'MediaBrowser.Plugins.MpcHc')
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj | 109 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs | 574 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Plugin.cs | 32 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs | 53 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs | 62 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Properties/Resources.resx | 117 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs | 30 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/Properties/Settings.settings | 7 | ||||
| -rw-r--r-- | MediaBrowser.Plugins.MpcHc/app.config | 11 |
9 files changed, 995 insertions, 0 deletions
diff --git a/MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj b/MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj new file mode 100644 index 000000000..f95b73b65 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}</ProjectGuid> + <OutputType>library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>MediaBrowser.Plugins.MpcHc</RootNamespace> + <AssemblyName>MediaBrowser.Plugins.MpcHc</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> + <RestorePackages>true</RestorePackages> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup> + <RunPostBuildEvent>Always</RunPostBuildEvent> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.ComponentModel.Composition" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Xaml"> + <RequiredTargetFramework>4.0</RequiredTargetFramework> + </Reference> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <Compile Include="MpcHcMediaPlayer.cs" /> + <Compile Include="Plugin.cs" /> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="app.config" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + <AppDesigner Include="Properties\" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> + <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project> + <Name>MediaBrowser.Common</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> + <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> + <Name>MediaBrowser.Model</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.UI\MediaBrowser.UI.csproj"> + <Project>{b5ece1fb-618e-420b-9a99-8e972d76920a}</Project> + <Name>MediaBrowser.UI</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <PropertyGroup> + <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent> + </PropertyGroup> + <Import Project="$(SolutionDir)\.nuget\nuget.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs b/MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs new file mode 100644 index 000000000..bbeff2206 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs @@ -0,0 +1,574 @@ +using MediaBrowser.Common.Logging; +using MediaBrowser.Model.DTO; +using MediaBrowser.Model.Entities; +using MediaBrowser.UI.Configuration; +using MediaBrowser.UI.Controller; +using MediaBrowser.UI.Playback; +using MediaBrowser.UI.Playback.ExternalPlayer; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Plugins.MpcHc +{ + /// <summary> + /// Class GenericExternalPlayer + /// </summary> + [Export(typeof(BaseMediaPlayer))] + public class MpcHcMediaPlayer : BaseExternalPlayer + { + /// <summary> + /// The state sync lock + /// </summary> + private object stateSyncLock = new object(); + + /// <summary> + /// The MPC HTTP interface resource pool + /// </summary> + private SemaphoreSlim MpcHttpInterfaceResourcePool = new SemaphoreSlim(1, 1); + + /// <summary> + /// Gets or sets the HTTP interface cancellation token. + /// </summary> + /// <value>The HTTP interface cancellation token.</value> + private CancellationTokenSource HttpInterfaceCancellationTokenSource { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has started playing. + /// </summary> + /// <value><c>true</c> if this instance has started playing; otherwise, <c>false</c>.</value> + private bool HasStartedPlaying { get; set; } + + /// <summary> + /// Gets or sets the status update timer. + /// </summary> + /// <value>The status update timer.</value> + private Timer StatusUpdateTimer { get; set; } + + /// <summary> + /// Gets a value indicating whether this instance can monitor progress. + /// </summary> + /// <value><c>true</c> if this instance can monitor progress; otherwise, <c>false</c>.</value> + protected override bool CanMonitorProgress + { + get + { + return true; + } + } + + /// <summary> + /// The _current position ticks + /// </summary> + private long? _currentPositionTicks; + + /// <summary> + /// Gets the current position ticks. + /// </summary> + /// <value>The current position ticks.</value> + public override long? CurrentPositionTicks + { + get + { + return _currentPositionTicks; + } + } + + /// <summary> + /// The _current playlist index + /// </summary> + private int _currentPlaylistIndex; + + /// <summary> + /// Gets the index of the current playlist. + /// </summary> + /// <value>The index of the current playlist.</value> + public override int CurrentPlaylistIndex + { + get + { + return _currentPlaylistIndex; + } + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "MpcHc"; } + } + + /// <summary> + /// Gets a value indicating whether this instance can close automatically. + /// </summary> + /// <value><c>true</c> if this instance can close automatically; otherwise, <c>false</c>.</value> + protected override bool CanCloseAutomatically + { + get + { + return true; + } + } + + /// <summary> + /// Determines whether this instance can play the specified item. + /// </summary> + /// <param name="item">The item.</param> + /// <returns><c>true</c> if this instance can play the specified item; otherwise, <c>false</c>.</returns> + public override bool CanPlay(DtoBaseItem item) + { + return item.IsVideo || item.IsAudio; + } + + /// <summary> + /// Gets the command arguments. + /// </summary> + /// <param name="items">The items.</param> + /// <param name="options">The options.</param> + /// <param name="playerConfiguration">The player configuration.</param> + /// <returns>System.String.</returns> + protected override string GetCommandArguments(List<DtoBaseItem> items, PlayOptions options, PlayerConfiguration playerConfiguration) + { + var formatString = "{0} /play /fullscreen /close"; + + var firstItem = items[0]; + + var startTicks = Math.Max(options.StartPositionTicks, 0); + + if (startTicks > 0 && firstItem.IsVideo && firstItem.VideoType.HasValue && firstItem.VideoType.Value == VideoType.Dvd) + { + formatString += " /dvdpos 1#" + TimeSpan.FromTicks(startTicks).ToString("hh\\:mm\\:ss"); + } + else + { + formatString += " /start " + TimeSpan.FromTicks(startTicks).TotalMilliseconds; + } + + + return GetCommandArguments(items, formatString); + } + + /// <summary> + /// Gets the path for command line. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>System.String.</returns> + protected override string GetPathForCommandLine(DtoBaseItem item) + { + var path = base.GetPathForCommandLine(item); + + if (item.IsVideo && item.VideoType.HasValue) + { + if (item.VideoType.Value == VideoType.Dvd) + { + // Point directly to the video_ts path + // Otherwise mpc will play any other media files that might exist in the dvd top folder (e.g. video backdrops). + var videoTsPath = Path.Combine(path, "video_ts"); + + if (Directory.Exists(videoTsPath)) + { + path = videoTsPath; + } + } + if (item.VideoType.Value == VideoType.BluRay) + { + // Point directly to the bdmv path + var bdmvPath = Path.Combine(path, "bdmv"); + + if (Directory.Exists(bdmvPath)) + { + path = bdmvPath; + } + } + } + + return FormatPath(path); + } + + /// <summary> + /// Formats the path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>System.String.</returns> + private string FormatPath(string path) + { + if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase)) + { + path = path.TrimEnd('\\'); + } + + return path; + } + + /// <summary> + /// Called when [external player launched]. + /// </summary> + protected override void OnExternalPlayerLaunched() + { + base.OnExternalPlayerLaunched(); + + ReloadStatusUpdateTimer(); + } + + /// <summary> + /// Reloads the status update timer. + /// </summary> + private void ReloadStatusUpdateTimer() + { + DisposeStatusTimer(); + + HttpInterfaceCancellationTokenSource = new CancellationTokenSource(); + + StatusUpdateTimer = new Timer(OnStatusUpdateTimerStopped, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); + } + + /// <summary> + /// Called when [status update timer stopped]. + /// </summary> + /// <param name="state">The state.</param> + private async void OnStatusUpdateTimerStopped(object state) + { + try + { + var token = HttpInterfaceCancellationTokenSource.Token; + + using (var stream = await UIKernel.Instance.HttpManager.Get(StatusUrl, MpcHttpInterfaceResourcePool, token).ConfigureAwait(false)) + { + token.ThrowIfCancellationRequested(); + + using (var reader = new StreamReader(stream)) + { + token.ThrowIfCancellationRequested(); + + var result = await reader.ReadToEndAsync().ConfigureAwait(false); + + token.ThrowIfCancellationRequested(); + + ProcessStatusResult(result); + } + } + } + catch (HttpRequestException ex) + { + Logger.ErrorException("Error connecting to MpcHc status interface", ex); + } + catch (OperationCanceledException) + { + // Manually cancelled by us + Logger.Info("Status request cancelled"); + } + } + + /// <summary> + /// Processes the status result. + /// </summary> + /// <param name="result">The result.</param> + private async void ProcessStatusResult(string result) + { + // Sample result + // OnStatus('test.avi', 'Playing', 5292, '00:00:05', 1203090, '00:20:03', 0, 100, 'C:\test.avi') + // 5292 = position in ms + // 00:00:05 = position + // 1203090 = duration in ms + // 00:20:03 = duration + + var quoteChar = result.IndexOf(", \"", StringComparison.OrdinalIgnoreCase) == -1 ? '\'' : '\"'; + + // Strip off the leading "OnStatus(" and the trailing ")" + result = result.Substring(result.IndexOf(quoteChar)); + result = result.Substring(0, result.LastIndexOf(quoteChar)); + + // Strip off the filename at the beginning + result = result.Substring(result.IndexOf(string.Format("{0}, {0}", quoteChar), StringComparison.OrdinalIgnoreCase) + 3); + + // Find the last index of ", '" so that we can extract and then strip off the file path at the end. + var lastIndexOfSeparator = result.LastIndexOf(", " + quoteChar, StringComparison.OrdinalIgnoreCase); + + // Get the current playing file path + var currentPlayingFile = result.Substring(lastIndexOfSeparator + 2).Trim(quoteChar); + + // Strip off the current playing file path + result = result.Substring(0, lastIndexOfSeparator); + + var values = result.Split(',').Select(v => v.Trim().Trim(quoteChar)).ToList(); + + var currentPositionTicks = TimeSpan.FromMilliseconds(double.Parse(values[1])).Ticks; + //var currentDurationTicks = TimeSpan.FromMilliseconds(double.Parse(values[3])).Ticks; + + var playstate = values[0]; + + var playlistIndex = GetPlaylistIndex(currentPlayingFile); + + if (playstate.Equals("stopped", StringComparison.OrdinalIgnoreCase)) + { + if (HasStartedPlaying) + { + await ClosePlayer().ConfigureAwait(false); + } + } + else + { + lock (stateSyncLock) + { + if (_currentPlaylistIndex != playlistIndex) + { + OnMediaChanged(_currentPlaylistIndex, _currentPositionTicks, playlistIndex); + } + + _currentPositionTicks = currentPositionTicks; + _currentPlaylistIndex = playlistIndex; + } + + if (playstate.Equals("playing", StringComparison.OrdinalIgnoreCase)) + { + HasStartedPlaying = true; + PlayState = PlayState.Playing; + } + else if (playstate.Equals("paused", StringComparison.OrdinalIgnoreCase)) + { + HasStartedPlaying = true; + PlayState = PlayState.Paused; + } + } + } + + /// <summary> + /// Gets the index of the playlist. + /// </summary> + /// <param name="nowPlayingPath">The now playing path.</param> + /// <returns>System.Int32.</returns> + private int GetPlaylistIndex(string nowPlayingPath) + { + for (var i = 0; i < Playlist.Count; i++) + { + var item = Playlist[i]; + + var pathArg = GetPathForCommandLine(item); + + if (pathArg.Equals(nowPlayingPath, StringComparison.OrdinalIgnoreCase)) + { + return i; + } + + if (item.VideoType.HasValue) + { + if (item.VideoType.Value == VideoType.BluRay || item.VideoType.Value == VideoType.Dvd || item.VideoType.Value == VideoType.HdDvd) + { + if (nowPlayingPath.StartsWith(pathArg, StringComparison.OrdinalIgnoreCase)) + { + return i; + } + } + } + } + return -1; + } + + /// <summary> + /// Called when [player stopped internal]. + /// </summary> + protected override void OnPlayerStoppedInternal() + { + HttpInterfaceCancellationTokenSource.Cancel(); + + DisposeStatusTimer(); + _currentPositionTicks = null; + _currentPlaylistIndex = 0; + HasStartedPlaying = false; + HttpInterfaceCancellationTokenSource = null; + + base.OnPlayerStoppedInternal(); + } + + /// <summary> + /// Disposes the status timer. + /// </summary> + private void DisposeStatusTimer() + { + if (StatusUpdateTimer != null) + { + StatusUpdateTimer.Dispose(); + } + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected override void Dispose(bool dispose) + { + if (dispose) + { + DisposeStatusTimer(); + + MpcHttpInterfaceResourcePool.Dispose(); + } + + base.Dispose(dispose); + } + + /// <summary> + /// Seeks the internal. + /// </summary> + /// <param name="positionTicks">The position ticks.</param> + /// <returns>Task.</returns> + protected override Task SeekInternal(long positionTicks) + { + var additionalParams = new Dictionary<string, string>(); + + var time = TimeSpan.FromTicks(positionTicks); + + var timeString = time.Hours + ":" + time.Minutes + ":" + time.Seconds; + + additionalParams.Add("position", timeString); + + return SendCommandToPlayer("-1", additionalParams); + } + + /// <summary> + /// Pauses the internal. + /// </summary> + /// <returns>Task.</returns> + protected override Task PauseInternal() + { + return SendCommandToPlayer("888", new Dictionary<string, string>()); + } + + /// <summary> + /// Uns the pause internal. + /// </summary> + /// <returns>Task.</returns> + protected override Task UnPauseInternal() + { + return SendCommandToPlayer("887", new Dictionary<string, string>()); + } + + /// <summary> + /// Stops the internal. + /// </summary> + /// <returns>Task.</returns> + protected override Task StopInternal() + { + return SendCommandToPlayer("890", new Dictionary<string, string>()); + } + + /// <summary> + /// Closes the player. + /// </summary> + /// <returns>Task.</returns> + protected Task ClosePlayer() + { + return SendCommandToPlayer("816", new Dictionary<string, string>()); + } + + /// <summary> + /// Sends a command to MPC using the HTTP interface + /// http://www.autohotkey.net/~specter333/MPC/HTTP%20Commands.txt + /// </summary> + /// <param name="commandNumber">The command number.</param> + /// <param name="additionalParams">The additional params.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException">commandNumber</exception> + private async Task SendCommandToPlayer(string commandNumber, Dictionary<string, string> additionalParams) + { + if (string.IsNullOrEmpty(commandNumber)) + { + throw new ArgumentNullException("commandNumber"); + } + + if (additionalParams == null) + { + throw new ArgumentNullException("additionalParams"); + } + + var url = CommandUrl + "?wm_command=" + commandNumber; + + url = additionalParams.Keys.Aggregate(url, (current, name) => current + ("&" + name + "=" + additionalParams[name])); + + Logger.Info("Sending command to MPC: " + url); + + try + { + using (var stream = await UIKernel.Instance.HttpManager.Get(url, MpcHttpInterfaceResourcePool, HttpInterfaceCancellationTokenSource.Token).ConfigureAwait(false)) + { + } + } + catch (HttpRequestException ex) + { + Logger.ErrorException("Error connecting to MpcHc command interface", ex); + } + catch (OperationCanceledException) + { + // Manually cancelled by us + Logger.Info("Command request cancelled"); + } + } + + /// <summary> + /// Gets a value indicating whether this instance can pause. + /// </summary> + /// <value><c>true</c> if this instance can pause; otherwise, <c>false</c>.</value> + public override bool CanPause + { + get + { + return true; + } + } + + /// <summary> + /// Gets the server name that the http interface will be running on + /// </summary> + /// <value>The HTTP server.</value> + private string HttpServer + { + get + { + return "localhost"; + } + } + + /// <summary> + /// Gets the port that the web interface will be running on + /// </summary> + /// <value>The HTTP port.</value> + private string HttpPort + { + get + { + return "13579"; + } + } + + /// <summary> + /// Gets the url of that will be called to for status + /// </summary> + /// <value>The status URL.</value> + private string StatusUrl + { + get + { + return "http://" + HttpServer + ":" + HttpPort + "/status.html"; + } + } + + /// <summary> + /// Gets the url of that will be called to send commands + /// </summary> + /// <value>The command URL.</value> + private string CommandUrl + { + get + { + return "http://" + HttpServer + ":" + HttpPort + "/command.html"; + } + } + } +} diff --git a/MediaBrowser.Plugins.MpcHc/Plugin.cs b/MediaBrowser.Plugins.MpcHc/Plugin.cs new file mode 100644 index 000000000..ca8acc94e --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Plugin.cs @@ -0,0 +1,32 @@ +using MediaBrowser.Common.Plugins; +using MediaBrowser.Model.Plugins; +using System; +using System.ComponentModel.Composition; + +namespace MediaBrowser.Plugins.MpcHc +{ + /// <summary> + /// Class Plugin + /// </summary> + [Export(typeof(IPlugin))] + public class Plugin : BaseUiPlugin<BasePluginConfiguration> + { + /// <summary> + /// Gets the name of the plugin + /// </summary> + /// <value>The name.</value> + public override string Name + { + get { return "MPC-HC Integration"; } + } + + /// <summary> + /// Gets the minimum required UI version. + /// </summary> + /// <value>The minimum required UI version.</value> + public override Version MinimumRequiredUIVersion + { + get { return new Version("2.9.4782.23738"); } + } + } +} diff --git a/MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs b/MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..10442b136 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaBrowser.Plugins.MpcHc")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.Plugins.MpcHc")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file +//inside a <PropertyGroup>. For example, if you are using US english +//in your source files, set the <UICulture> to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + +[assembly: Guid("F6D17656-25FE-4564-9246-B4584F797348")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.*")] diff --git a/MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs b/MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs new file mode 100644 index 000000000..14f2a3ba2 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.18010 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace MediaBrowser.Plugins.MpcHc.Properties { + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.Plugins.MpcHc.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/MediaBrowser.Plugins.MpcHc/Properties/Resources.resx b/MediaBrowser.Plugins.MpcHc/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs b/MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs new file mode 100644 index 000000000..f64175f33 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.18010 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace MediaBrowser.Plugins.MpcHc.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/MediaBrowser.Plugins.MpcHc/Properties/Settings.settings b/MediaBrowser.Plugins.MpcHc/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file diff --git a/MediaBrowser.Plugins.MpcHc/app.config b/MediaBrowser.Plugins.MpcHc/app.config new file mode 100644 index 000000000..29abde1f6 --- /dev/null +++ b/MediaBrowser.Plugins.MpcHc/app.config @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration>
\ No newline at end of file |
