mirror of
https://github.com/ZetaKebab/MpcNET.git
synced 2025-01-14 22:18:43 +00:00
Various improvements
This commit is contained in:
parent
6426d98fc5
commit
a2c012dd7e
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,3 +14,5 @@
|
|||||||
/src/MpcNET.sln.DotSettings.user
|
/src/MpcNET.sln.DotSettings.user
|
||||||
/src/MpcNET.Test/MpcNET.Test.csproj.DotSettings
|
/src/MpcNET.Test/MpcNET.Test.csproj.DotSettings
|
||||||
/src/MpcNET/MpcNET.csproj.DotSettings
|
/src/MpcNET/MpcNET.csproj.DotSettings
|
||||||
|
/.vs
|
||||||
|
*.user
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
<AssemblyName>MpcNET.Test</AssemblyName>
|
<AssemblyName>MpcNET.Test</AssemblyName>
|
||||||
<PackageId>MpcNET.Test</PackageId>
|
<PackageId>MpcNET.Test</PackageId>
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
|
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||||
@ -25,9 +24,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="1.1.14" />
|
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="1.1.14" />
|
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using MpcNET.Commands;
|
||||||
using MpcNET.Tags;
|
using MpcNET.Tags;
|
||||||
|
|
||||||
namespace MpcNET.Test
|
namespace MpcNET.Test
|
||||||
@ -10,7 +11,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task ListAllTest()
|
public async Task ListAllTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Database.ListAll());
|
var response = await Mpc.SendAsync(Command.Database.ListAll());
|
||||||
|
|
||||||
TestOutput.WriteLine("ListAllTest Result:");
|
TestOutput.WriteLine("ListAllTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -21,7 +22,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task FindGenreTest()
|
public async Task FindGenreTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Database.Find(MpdTags.Genre, "soundfx"));
|
var response = await Mpc.SendAsync(Command.Database.Find(MpdTags.Genre, "soundfx"));
|
||||||
|
|
||||||
TestOutput.WriteLine("FindGenreTest Result:");
|
TestOutput.WriteLine("FindGenreTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using MpcNET.Commands;
|
||||||
|
|
||||||
namespace MpcNET.Test
|
namespace MpcNET.Test
|
||||||
{
|
{
|
||||||
@ -9,10 +10,10 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task DisableOutputTest()
|
public async Task DisableOutputTest()
|
||||||
{
|
{
|
||||||
var responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
||||||
|
|
||||||
var response = await Mpc.SendAsync(new Commands.Output.DisableOutput(0));
|
var response = await Mpc.SendAsync(Command.Output.DisableOutput(0));
|
||||||
|
|
||||||
TestOutput.WriteLine("DisableOutputTest Result:");
|
TestOutput.WriteLine("DisableOutputTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -20,18 +21,18 @@ namespace MpcNET.Test
|
|||||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||||
|
|
||||||
responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(0)).IsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task EnableOutputTest()
|
public async Task EnableOutputTest()
|
||||||
{
|
{
|
||||||
var responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
// By default should be disable from mpd.config
|
// By default should be disable from mpd.config
|
||||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
||||||
|
|
||||||
var response = await Mpc.SendAsync(new Commands.Output.EnableOutput(1));
|
var response = await Mpc.SendAsync(Command.Output.EnableOutput(1));
|
||||||
|
|
||||||
TestOutput.WriteLine("EnableOutputTest Result:");
|
TestOutput.WriteLine("EnableOutputTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -39,17 +40,17 @@ namespace MpcNET.Test
|
|||||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||||
|
|
||||||
responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(1)).IsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task ToggleOutputTest()
|
public async Task ToggleOutputTest()
|
||||||
{
|
{
|
||||||
var responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
var responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
Assert.IsTrue(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
||||||
|
|
||||||
var response = await Mpc.SendAsync(new Commands.Output.ToggleOutput(2));
|
var response = await Mpc.SendAsync(Command.Output.ToggleOutput(2));
|
||||||
|
|
||||||
TestOutput.WriteLine("ToggleOutputTest Result:");
|
TestOutput.WriteLine("ToggleOutputTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -57,14 +58,14 @@ namespace MpcNET.Test
|
|||||||
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
Assert.IsTrue(response.Response.Body.Equals(string.Empty));
|
||||||
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
Assert.IsTrue(response.Response.State.Status.Equals("OK"));
|
||||||
|
|
||||||
responseOutputs = await Mpc.SendAsync(new Commands.Output.Outputs());
|
responseOutputs = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
Assert.IsFalse(responseOutputs.Response.Body.Single(output => output.Id.Equals(2)).IsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task LisOutputsTest()
|
public async Task LisOutputsTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Output.Outputs());
|
var response = await Mpc.SendAsync(Command.Output.Outputs());
|
||||||
|
|
||||||
TestOutput.WriteLine("LisOutputsTest Result:");
|
TestOutput.WriteLine("LisOutputsTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using MpcNET.Commands;
|
||||||
|
|
||||||
namespace MpcNET.Test
|
namespace MpcNET.Test
|
||||||
{
|
{
|
||||||
@ -12,7 +13,7 @@ namespace MpcNET.Test
|
|||||||
[DataRow("_My Playlist", 5)]
|
[DataRow("_My Playlist", 5)]
|
||||||
public async Task ListPlaylistTest(string playlistName, int numberOfFiles)
|
public async Task ListPlaylistTest(string playlistName, int numberOfFiles)
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetContent(playlistName));
|
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetContent(playlistName));
|
||||||
|
|
||||||
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -26,7 +27,7 @@ namespace MpcNET.Test
|
|||||||
[DataRow("_My Playlist", 5)]
|
[DataRow("_My Playlist", 5)]
|
||||||
public async Task ListPlaylistInfoTest(string playlistName, int numberOfFiles)
|
public async Task ListPlaylistInfoTest(string playlistName, int numberOfFiles)
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetContentWithMetadata(playlistName));
|
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetContentWithMetadata(playlistName));
|
||||||
|
|
||||||
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
TestOutput.WriteLine($"ListPlaylistTest (playlistName: {playlistName}) Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -40,7 +41,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task ListPlaylistsTest()
|
public async Task ListPlaylistsTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(Commands.Playlists.Stored.GetAll());
|
var response = await Mpc.SendAsync(Command.Playlists.Stored.GetAll());
|
||||||
|
|
||||||
TestOutput.WriteLine($"ListPlaylistsTest Result:");
|
TestOutput.WriteLine($"ListPlaylistsTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -116,57 +117,57 @@ namespace MpcNET.Test
|
|||||||
|
|
||||||
private async Task Check_Empty_Queue()
|
private async Task Check_Empty_Queue()
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongsInfo());
|
var message = await Mpc.SendAsync(Command.Playlists.Current.GetAllSongsInfo());
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
Assert.IsFalse(message.Response.Body.Any());
|
Assert.IsFalse(message.Response.Body.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Load_Playlist(string playlistName)
|
private async Task Load_Playlist(string playlistName)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Stored.Load(playlistName));
|
var message = await Mpc.SendAsync(Command.Playlists.Stored.Load(playlistName));
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Clear_Queue()
|
private async Task Clear_Queue()
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.Clear());
|
var message = await Mpc.SendAsync(Command.Playlists.Current.Clear());
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Check_Queue_HasSongs(int nrOfSongs)
|
private async Task Check_Queue_HasSongs(int nrOfSongs)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongsInfo());
|
var message = await Mpc.SendAsync(Command.Playlists.Current.GetAllSongsInfo());
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
Assert.IsTrue(message.Response.Body.Count() == nrOfSongs);
|
Assert.IsTrue(message.Response.Body.Count() == nrOfSongs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Add_Directory(string directory)
|
private async Task Add_Directory(string directory)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.AddDirectory(directory));
|
var message = await Mpc.SendAsync(Command.Playlists.Current.AddDirectory(directory));
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Add_File(string file)
|
private async Task Add_File(string file)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.AddSong(file));
|
var message = await Mpc.SendAsync(Command.Playlists.Current.AddSong(file));
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Remove_Position(int position)
|
private async Task Remove_Position(int position)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.RemoveSongByPosition(position));
|
var message = await Mpc.SendAsync(Command.Playlists.Current.RemoveSongByPosition(position));
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Remove_Id(int songId)
|
private async Task Remove_Id(int songId)
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.RemoveSongById(songId));
|
var message = await Mpc.SendAsync(Command.Playlists.Current.RemoveSongById(songId));
|
||||||
Assert.IsTrue(message.HasSuccessResponse());
|
Assert.IsTrue(message.HasSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> Get_Song_Id()
|
private async Task<int> Get_Song_Id()
|
||||||
{
|
{
|
||||||
var message = await Mpc.SendAsync(Commands.Playlists.Current.GetAllSongMetadata());
|
var message = await Mpc.SendAsync(Command.Playlists.Current.GetAllSongMetadata());
|
||||||
return message.Response.Body.Single().Id;
|
return message.Response.Body.Single().Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using MpcNET.Commands;
|
||||||
|
|
||||||
namespace MpcNET.Test
|
namespace MpcNET.Test
|
||||||
{
|
{
|
||||||
@ -9,7 +10,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task CommandsTest()
|
public async Task CommandsTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Reflection.Commands());
|
var response = await Mpc.SendAsync(Command.Reflection.Commands());
|
||||||
|
|
||||||
TestOutput.WriteLine($"CommandsTest (commands: {response.Response.Body.Count()}) Result:");
|
TestOutput.WriteLine($"CommandsTest (commands: {response.Response.Body.Count()}) Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -27,7 +28,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task TagTypesTest()
|
public async Task TagTypesTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Reflection.TagTypes());
|
var response = await Mpc.SendAsync(Command.Reflection.TagTypes());
|
||||||
|
|
||||||
TestOutput.WriteLine("TagTypesTest Result:");
|
TestOutput.WriteLine("TagTypesTest Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -38,7 +39,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task UrlHandlersTest()
|
public async Task UrlHandlersTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Reflection.UrlHandlers());
|
var response = await Mpc.SendAsync(Command.Reflection.UrlHandlers());
|
||||||
|
|
||||||
TestOutput.WriteLine($"UrlHandlersTest (handlers: {response.Response.Body.Count()}) Result:");
|
TestOutput.WriteLine($"UrlHandlersTest (handlers: {response.Response.Body.Count()}) Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
@ -54,7 +55,7 @@ namespace MpcNET.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task DecodersTest()
|
public async Task DecodersTest()
|
||||||
{
|
{
|
||||||
var response = await Mpc.SendAsync(new Commands.Reflection.Decoders());
|
var response = await Mpc.SendAsync(Command.Reflection.Decoders());
|
||||||
|
|
||||||
TestOutput.WriteLine($"DecodersTest (decoders: {response.Response.Body.Count()}) Result:");
|
TestOutput.WriteLine($"DecodersTest (decoders: {response.Response.Body.Count()}) Result:");
|
||||||
TestOutput.WriteLine(response);
|
TestOutput.WriteLine(response);
|
||||||
|
@ -1,127 +1,33 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using MpcNET.Commands.Database;
|
||||||
using MpcNET.Tags;
|
using MpcNET.Tags;
|
||||||
using MpcNET.Types;
|
using MpcNET.Types;
|
||||||
|
|
||||||
namespace MpcNET
|
namespace MpcNET.Commands
|
||||||
{
|
{
|
||||||
public static partial class Commands
|
public static partial class Command
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://www.musicpd.org/doc/protocol/database.html
|
/// https://www.musicpd.org/doc/protocol/database.html
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Database
|
public static class Database
|
||||||
{
|
{
|
||||||
|
public static IMpcCommand<IEnumerable<IMpdFile>> Find(ITag tag, string searchText)
|
||||||
|
{
|
||||||
|
return new FindCommand(tag, searchText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IMpcCommand<string> Update(string uri = null)
|
||||||
|
{
|
||||||
|
return new UpdateCommand(uri);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: count
|
// TODO: count
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds songs in the database that is exactly "searchText".
|
|
||||||
/// </summary>
|
|
||||||
public class Find : IMpcCommand<IEnumerable<IMpdFile>>
|
|
||||||
{
|
|
||||||
private readonly ITag _tag;
|
|
||||||
private readonly string _searchText;
|
|
||||||
|
|
||||||
public Find(ITag tag, string searchText)
|
|
||||||
{
|
|
||||||
_tag = tag;
|
|
||||||
_searchText = searchText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "find", _tag.Value, _searchText);
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = new List<MpdFile>();
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("file"))
|
|
||||||
{
|
|
||||||
results.Add(new MpdFile(line.Value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
results.Last().AddTag(line.Key, line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class List : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly ITag _tag;
|
|
||||||
|
|
||||||
public List(ITag tag)
|
|
||||||
{
|
|
||||||
_tag = tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "list", _tag);
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
// TODO:
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: findadd
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lists all songs and directories in URI.
|
|
||||||
/// </summary>
|
|
||||||
public class ListAll : IMpcCommand<IEnumerable<MpdDirectory>>
|
|
||||||
{
|
|
||||||
public string Value => "listall";
|
|
||||||
|
|
||||||
public IEnumerable<MpdDirectory> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var rootDirectory = new List<MpdDirectory>
|
|
||||||
{
|
|
||||||
new MpdDirectory("/") // Add by default the root directory
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("file"))
|
|
||||||
{
|
|
||||||
rootDirectory.Last().AddFile(line.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.Key.Equals("directory"))
|
|
||||||
{
|
|
||||||
rootDirectory.Add(new MpdDirectory(line.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rootDirectory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: listallinfo
|
|
||||||
// TODO: listfiles
|
|
||||||
// TODO: lsinfo
|
|
||||||
// TODO: readcomments
|
|
||||||
// TODO: search
|
|
||||||
// TODO: searchadd
|
|
||||||
// TODO: searchaddpl
|
|
||||||
|
|
||||||
public class Update : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
// TODO: Extend command: < update [URI] >
|
|
||||||
public string Value => "update";
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
// TODO:
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: rescan
|
// TODO: rescan
|
||||||
|
public static IMpcCommand<IEnumerable<MpdDirectory>> ListAll()
|
||||||
|
{
|
||||||
|
return new ListAllCommand();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,100 +1,34 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Commands.Output;
|
||||||
using MpcNET.Types;
|
using MpcNET.Types;
|
||||||
|
|
||||||
namespace MpcNET
|
namespace MpcNET.Commands
|
||||||
{
|
{
|
||||||
public static partial class Commands
|
public static partial class Command
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://www.musicpd.org/doc/protocol/output_commands.html
|
/// https://www.musicpd.org/doc/protocol/output_commands.html
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Output
|
public class Output
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static IMpcCommand<IEnumerable<MpdOutput>> Outputs()
|
||||||
/// Turns an output off.
|
|
||||||
/// </summary>
|
|
||||||
public class DisableOutput : IMpcCommand<string>
|
|
||||||
{
|
{
|
||||||
private readonly int _outputId;
|
return new OutputsCommand();
|
||||||
|
|
||||||
public DisableOutput(int outputId)
|
|
||||||
{
|
|
||||||
_outputId = outputId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Value => string.Join(" ", "disableoutput", _outputId);
|
public static IMpcCommand<string> DisableOutput(int outputId)
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
{
|
||||||
// Response should be empty.
|
return new DisableOutputCommand(outputId);
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static IMpcCommand<string> EnableOutput(int outputId)
|
||||||
/// Turns an output on.
|
|
||||||
/// </summary>
|
|
||||||
public class EnableOutput : IMpcCommand<string>
|
|
||||||
{
|
{
|
||||||
private readonly int _outputId;
|
return new EnableOutputCommand(outputId);
|
||||||
|
|
||||||
public EnableOutput(int outputId)
|
|
||||||
{
|
|
||||||
_outputId = outputId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Value => string.Join(" ", "enableoutput", _outputId);
|
public static IMpcCommand<string> ToggleOutput(int outputId)
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
{
|
||||||
// Response should be empty.
|
return new ToggleOutputCommand(outputId);
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Turns an output on or off, depending on the current state.
|
|
||||||
/// </summary>
|
|
||||||
public class ToggleOutput : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly int _outputId;
|
|
||||||
|
|
||||||
public ToggleOutput(int outputId)
|
|
||||||
{
|
|
||||||
_outputId = outputId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "toggleoutput", _outputId);
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
// Response should be empty.
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows information about all outputs.
|
|
||||||
/// </summary>
|
|
||||||
public class Outputs : IMpcCommand<IEnumerable<MpdOutput>>
|
|
||||||
{
|
|
||||||
public string Value => "outputs";
|
|
||||||
|
|
||||||
public IEnumerable<MpdOutput> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = new List<MpdOutput>();
|
|
||||||
|
|
||||||
for (var i = 0; i < response.Count; i += 3)
|
|
||||||
{
|
|
||||||
var outputId = int.Parse(response[i].Value);
|
|
||||||
var outputName = response[i + 1].Value;
|
|
||||||
var outputEnabled = response[i + 2].Value == "1";
|
|
||||||
|
|
||||||
result.Add(new MpdOutput(outputId, outputName, outputEnabled));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/MpcNET/Commands/Commands.Playback.cs
Normal file
24
src/MpcNET/Commands/Commands.Playback.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using MpcNET.Commands.Playback;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands
|
||||||
|
{
|
||||||
|
public partial class Command
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// https://www.musicpd.org/doc/protocol/playback_commands.html
|
||||||
|
/// </summary>
|
||||||
|
public static class Playback
|
||||||
|
{
|
||||||
|
public static IMpcCommand<string> Next() => new NextCommand();
|
||||||
|
|
||||||
|
public static IMpcCommand<string> Previous() => new PreviousCommand();
|
||||||
|
|
||||||
|
public static IMpcCommand<string> PlayPause() => new PlayPauseCommand();
|
||||||
|
|
||||||
|
public static IMpcCommand<string> Play(IMpdFile mpdFile) => new PlayCommand(mpdFile);
|
||||||
|
|
||||||
|
public static IMpcCommand<string> Stop() => new StopCommand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using MpcNET.Commands.Playlist;
|
||||||
using MpcNET.Types;
|
using MpcNET.Types;
|
||||||
|
|
||||||
namespace MpcNET
|
namespace MpcNET.Commands
|
||||||
{
|
{
|
||||||
public static partial class Commands
|
public static partial class Command
|
||||||
{
|
{
|
||||||
public static class Playlists
|
public static class Playlists
|
||||||
{
|
{
|
||||||
@ -13,214 +13,45 @@ namespace MpcNET
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Current
|
public static class Current
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Adds the file URI to the playlist (directories add recursively). URI can also be a single file.
|
|
||||||
/// </summary>
|
|
||||||
private class AddImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly string _uri;
|
|
||||||
|
|
||||||
public AddImpl(string uri)
|
|
||||||
{
|
|
||||||
_uri = uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "add", $"\"{_uri}\"");
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: add
|
/// Command: add
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> AddDirectory(string directory) { return new AddImpl(directory); }
|
public static IMpcCommand<string> AddDirectory(string directory) { return new AddCommand(directory); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a song to the playlist (non-recursive) and returns the song id.
|
|
||||||
/// </summary>
|
|
||||||
private class AddIdImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly string _uri;
|
|
||||||
|
|
||||||
public AddIdImpl(string uri)
|
|
||||||
{
|
|
||||||
_uri = uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "addid", $"\"{_uri}\"");
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: addid
|
/// Command: addid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> AddSong(string songPath) { return new AddIdImpl(songPath); }
|
public static IMpcCommand<string> AddSong(string songPath) { return new AddIdCommand(songPath); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the current playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class ClearImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
public string Value => "clear";
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: clear
|
/// Command: clear
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> Clear() { return new ClearImpl(); }
|
public static IMpcCommand<string> Clear() { return new ClearCommand(); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Displays the current playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class PlaylistImpl : IMpcCommand<IEnumerable<IMpdFile>>
|
|
||||||
{
|
|
||||||
public string Value => "playlist";
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = response.Select(line => new MpdFile(line.Value) { Pos = int.Parse(line.Key) });
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: playlist
|
/// Command: playlist
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongsInfo() { return new PlaylistImpl(); }
|
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongsInfo() { return new PlaylistCommand(); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a song from the playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class DeleteImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly int _position;
|
|
||||||
|
|
||||||
public DeleteImpl(int position)
|
|
||||||
{
|
|
||||||
_position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "delete", _position);
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: delete
|
/// Command: delete
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> RemoveSongByPosition(int position) { return new DeleteImpl(position); }
|
public static IMpcCommand<string> RemoveSongByPosition(int position) { return new DeleteCommand(position); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the song SONGID from the playlist
|
|
||||||
/// </summary>
|
|
||||||
private class DeleteIdImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly int _songId;
|
|
||||||
|
|
||||||
public DeleteIdImpl(int songId)
|
|
||||||
{
|
|
||||||
_songId = songId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "deleteid", _songId);
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: deleteid
|
/// Command: deleteid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> RemoveSongById(int songId) { return new DeleteIdImpl(songId); }
|
public static IMpcCommand<string> RemoveSongById(int songId) { return new DeleteIdCommand(songId); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Displays song ID in the playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class PlaylistIdImpl : IMpcCommand<IEnumerable<IMpdFile>>
|
|
||||||
{
|
|
||||||
private readonly int _songId;
|
|
||||||
|
|
||||||
public PlaylistIdImpl(int songId)
|
|
||||||
{
|
|
||||||
_songId = songId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "playlistid", _songId);
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = new List<MpdFile>();
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("file"))
|
|
||||||
{
|
|
||||||
results.Add(new MpdFile(line.Value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
results.Last().AddTag(line.Key, line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: playlistid
|
/// Command: playlistid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<IMpdFile>> GetSongMetadata(int songId) { return new PlaylistIdImpl(songId); }
|
public static IMpcCommand<IEnumerable<IMpdFile>> GetSongMetadata(int songId) { return new PlaylistIdCommand(songId); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Displays a list of all songs in the playlist,
|
|
||||||
/// </summary>
|
|
||||||
private class PlaylistInfoImpl : IMpcCommand<IEnumerable<IMpdFile>>
|
|
||||||
{
|
|
||||||
public string Value => "playlistinfo";
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = new List<MpdFile>();
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("file"))
|
|
||||||
{
|
|
||||||
results.Add(new MpdFile(line.Value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
results.Last().AddTag(line.Key, line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: playlistinfo
|
/// Command: playlistinfo
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongMetadata() { return new PlaylistInfoImpl(); }
|
public static IMpcCommand<IEnumerable<IMpdFile>> GetAllSongMetadata() { return new PlaylistInfoCommand(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -228,128 +59,26 @@ namespace MpcNET
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Stored
|
public static class Stored
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Loads the playlist into the current queue.
|
|
||||||
/// </summary>
|
|
||||||
private class LoadImpl : IMpcCommand<string>
|
|
||||||
{
|
|
||||||
private readonly string _playlistName;
|
|
||||||
|
|
||||||
public LoadImpl(string playlistName)
|
|
||||||
{
|
|
||||||
_playlistName = playlistName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "load", $"\"{_playlistName}\"");
|
|
||||||
|
|
||||||
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
return string.Join(", ", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: load
|
/// Command: load
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<string> Load(string playlistName) { return new LoadImpl(playlistName); }
|
public static IMpcCommand<string> Load(string playlistName) { return new LoadCommand(playlistName); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lists the songs in the playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class ListPlaylistImpl : IMpcCommand<IEnumerable<IMpdFilePath>>
|
|
||||||
{
|
|
||||||
private readonly string _playlistName;
|
|
||||||
|
|
||||||
public ListPlaylistImpl(string playlistName)
|
|
||||||
{
|
|
||||||
_playlistName = playlistName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "listplaylist", $"\"{_playlistName}\"");
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFilePath> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = response.Where(line => line.Key.Equals("file")).Select(line => new MpdFile(line.Value));
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: listplaylist
|
/// Command: listplaylist
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<IMpdFilePath>> GetContent(string playlistName) { return new ListPlaylistImpl(playlistName); }
|
public static IMpcCommand<IEnumerable<IMpdFilePath>> GetContent(string playlistName) { return new ListPlaylistCommand(playlistName); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lists the songs with metadata in the playlist.
|
|
||||||
/// </summary>
|
|
||||||
private class ListPlaylistInfoImpl : IMpcCommand<IEnumerable<IMpdFile>>
|
|
||||||
{
|
|
||||||
private readonly string _playlistName;
|
|
||||||
|
|
||||||
public ListPlaylistInfoImpl(string playlistName)
|
|
||||||
{
|
|
||||||
_playlistName = playlistName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Value => string.Join(" ", "listplaylistinfo", $"\"{_playlistName}\"");
|
|
||||||
|
|
||||||
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var results = new List<MpdFile>();
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("file"))
|
|
||||||
{
|
|
||||||
results.Add(new MpdFile(line.Value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
results.Last().AddTag(line.Key, line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: listplaylistinfo
|
/// Command: listplaylistinfo
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<IMpdFile>> GetContentWithMetadata(string playlistName) { return new ListPlaylistInfoImpl(playlistName); }
|
public static IMpcCommand<IEnumerable<IMpdFile>> GetContentWithMetadata(string playlistName) { return new ListPlaylistInfoCommand(playlistName); }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Prints a list of the playlist directory.
|
|
||||||
/// </summary>
|
|
||||||
private class ListPlaylistsImpl : IMpcCommand<IEnumerable<MpdPlaylist>>
|
|
||||||
{
|
|
||||||
public string Value => "listplaylists";
|
|
||||||
|
|
||||||
public IEnumerable<MpdPlaylist> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = new List<MpdPlaylist>();
|
|
||||||
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("playlist"))
|
|
||||||
{
|
|
||||||
result.Add(new MpdPlaylist(line.Value));
|
|
||||||
}
|
|
||||||
else if (line.Key.Equals("Last-Modified"))
|
|
||||||
{
|
|
||||||
result.Last().AddLastModified(line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command: listplaylists
|
/// Command: listplaylists
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IMpcCommand<IEnumerable<MpdPlaylist>> GetAll() { return new ListPlaylistsImpl(); }
|
public static IMpcCommand<IEnumerable<MpdPlaylist>> GetAll() { return new ListPlaylistsCommand(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,102 +1,34 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using MpcNET.Commands.Reflection;
|
||||||
using MpcNET.Types;
|
using MpcNET.Types;
|
||||||
|
|
||||||
namespace MpcNET
|
namespace MpcNET.Commands
|
||||||
{
|
{
|
||||||
public static partial class Commands
|
public static partial class Command
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://www.musicpd.org/doc/protocol/reflection_commands.html
|
/// https://www.musicpd.org/doc/protocol/reflection_commands.html
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Reflection
|
public static class Reflection
|
||||||
{
|
{
|
||||||
// config : This command is only permitted to "local" clients (connected via UNIX domain socket).
|
public static IMpcCommand<IEnumerable<string>> Commands()
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows which commands the current user has access to.
|
|
||||||
/// </summary>
|
|
||||||
public class Commands : IMpcCommand<IEnumerable<string>>
|
|
||||||
{
|
{
|
||||||
public string Value => "commands";
|
return new CommandsCommand();
|
||||||
|
|
||||||
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = response.Where(item => item.Key.Equals("command")).Select(item => item.Value);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: notcommands : Shows which commands the current user does not have access to.
|
public static IMpcCommand<IEnumerable<string>> TagTypes()
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows a list of available song metadata.
|
|
||||||
/// </summary>
|
|
||||||
public class TagTypes : IMpcCommand<IEnumerable<string>>
|
|
||||||
{
|
{
|
||||||
public string Value => "tagtypes";
|
return new TagTypesCommand();
|
||||||
|
|
||||||
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = response.Where(item => item.Key.Equals("tagtype")).Select(item => item.Value);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static IMpcCommand<IEnumerable<string>> UrlHandlers()
|
||||||
/// Gets a list of available URL handlers.
|
|
||||||
/// </summary>
|
|
||||||
public class UrlHandlers : IMpcCommand<IEnumerable<string>>
|
|
||||||
{
|
{
|
||||||
public string Value => "urlhandlers";
|
return new UrlHandlersCommand();
|
||||||
|
|
||||||
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = response.Where(item => item.Key.Equals("handler")).Select(item => item.Value);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static IMpcCommand<IEnumerable<MpdDecoderPlugin>> Decoders()
|
||||||
/// Print a list of decoder plugins, followed by their supported suffixes and MIME types.
|
|
||||||
/// </summary>
|
|
||||||
public class Decoders : IMpcCommand<IEnumerable<MpdDecoderPlugin>>
|
|
||||||
{
|
{
|
||||||
public string Value => "decoders";
|
return new DecodersCommand();
|
||||||
|
|
||||||
public IEnumerable<MpdDecoderPlugin> FormatResponse(IList<KeyValuePair<string, string>> response)
|
|
||||||
{
|
|
||||||
var result = new List<MpdDecoderPlugin>();
|
|
||||||
|
|
||||||
var mpdDecoderPlugin = MpdDecoderPlugin.Empty;
|
|
||||||
foreach (var line in response)
|
|
||||||
{
|
|
||||||
if (line.Key.Equals("plugin"))
|
|
||||||
{
|
|
||||||
if (mpdDecoderPlugin.IsInitialized)
|
|
||||||
{
|
|
||||||
result.Add(mpdDecoderPlugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
mpdDecoderPlugin = new MpdDecoderPlugin(line.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.Key.Equals("suffix") && mpdDecoderPlugin.IsInitialized)
|
|
||||||
{
|
|
||||||
mpdDecoderPlugin.AddSuffix(line.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.Key.Equals("mime_type") && mpdDecoderPlugin.IsInitialized)
|
|
||||||
{
|
|
||||||
mpdDecoderPlugin.AddMediaType(line.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/MpcNET/Commands/Commands.Status.cs
Normal file
24
src/MpcNET/Commands/Commands.Status.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using MpcNET.Commands.Status;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands
|
||||||
|
{
|
||||||
|
public static partial class Command
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// https://www.musicpd.org/doc/protocol/command_reference.html#status_commands
|
||||||
|
/// </summary>
|
||||||
|
public static class Status
|
||||||
|
{
|
||||||
|
public static IMpcCommand<MpdStatus> GetStatus()
|
||||||
|
{
|
||||||
|
return new StatusCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IMpcCommand<IMpdFile> GetCurrentSong()
|
||||||
|
{
|
||||||
|
return new CurrentSongCommand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
src/MpcNET/Commands/Database/FindCommand.cs
Normal file
30
src/MpcNET/Commands/Database/FindCommand.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Tags;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Database
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Finds songs in the database that is exactly "searchText".
|
||||||
|
/// </summary>
|
||||||
|
internal class FindCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||||
|
{
|
||||||
|
private readonly ITag _tag;
|
||||||
|
private readonly string _searchText;
|
||||||
|
|
||||||
|
public FindCommand(ITag tag, string searchText)
|
||||||
|
{
|
||||||
|
_tag = tag;
|
||||||
|
_searchText = searchText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "find", _tag.Value, _searchText);
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return MpdFile.CreateList(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rescan
|
||||||
|
}
|
41
src/MpcNET/Commands/Database/ListAllCommand.cs
Normal file
41
src/MpcNET/Commands/Database/ListAllCommand.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Database
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists all songs and directories in URI.
|
||||||
|
/// </summary>
|
||||||
|
internal class ListAllCommand : IMpcCommand<IEnumerable<MpdDirectory>>
|
||||||
|
{
|
||||||
|
public string Value => "listall";
|
||||||
|
|
||||||
|
public IEnumerable<MpdDirectory> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var rootDirectory = new List<MpdDirectory>
|
||||||
|
{
|
||||||
|
new MpdDirectory("/") // Add by default the root directory
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var line in response)
|
||||||
|
{
|
||||||
|
if (line.Key.Equals("file"))
|
||||||
|
{
|
||||||
|
rootDirectory.Last().AddFile(line.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.Key.Equals("directory"))
|
||||||
|
{
|
||||||
|
rootDirectory.Add(new MpdDirectory(line.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootDirectory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: findadd
|
||||||
|
// TODO: rescan
|
||||||
|
}
|
25
src/MpcNET/Commands/Database/ListCommand.cs
Normal file
25
src/MpcNET/Commands/Database/ListCommand.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Tags;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Database
|
||||||
|
{
|
||||||
|
internal class ListCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly ITag _tag;
|
||||||
|
|
||||||
|
public ListCommand(ITag tag)
|
||||||
|
{
|
||||||
|
_tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "list", _tag);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
return response.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rescan
|
||||||
|
}
|
54
src/MpcNET/Commands/Database/UpdateCommand.cs
Normal file
54
src/MpcNET/Commands/Database/UpdateCommand.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Database
|
||||||
|
{
|
||||||
|
// TODO: listallinfo
|
||||||
|
// TODO: listfiles
|
||||||
|
// TODO: lsinfo
|
||||||
|
// TODO: readcomments
|
||||||
|
// TODO: search
|
||||||
|
// TODO: searchadd
|
||||||
|
// TODO: searchaddpl
|
||||||
|
|
||||||
|
public class UpdateCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly string uri;
|
||||||
|
|
||||||
|
public UpdateCommand(string uri)
|
||||||
|
{
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Extend command: < update [URI] >
|
||||||
|
public string Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(this.uri))
|
||||||
|
{
|
||||||
|
return "update";
|
||||||
|
}
|
||||||
|
|
||||||
|
var newUri = this.uri;
|
||||||
|
if (this.uri.StartsWith(@""""))
|
||||||
|
{
|
||||||
|
newUri = @"""" + this.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.uri.EndsWith(@""""))
|
||||||
|
{
|
||||||
|
newUri = this.uri + @"""";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join(" ", "update", newUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rescan
|
||||||
|
}
|
25
src/MpcNET/Commands/Output/DisableOutputCommand.cs
Normal file
25
src/MpcNET/Commands/Output/DisableOutputCommand.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Output
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Turns an output off.
|
||||||
|
/// </summary>
|
||||||
|
public class DisableOutputCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly int outputId;
|
||||||
|
|
||||||
|
public DisableOutputCommand(int outputId)
|
||||||
|
{
|
||||||
|
this.outputId = outputId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "disableoutput", this.outputId);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
// Response should be empty.
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/MpcNET/Commands/Output/EnableOutputCommand.cs
Normal file
25
src/MpcNET/Commands/Output/EnableOutputCommand.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Output
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Turns an output on.
|
||||||
|
/// </summary>
|
||||||
|
internal class EnableOutputCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly int _outputId;
|
||||||
|
|
||||||
|
public EnableOutputCommand(int outputId)
|
||||||
|
{
|
||||||
|
_outputId = outputId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "enableoutput", _outputId);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
// Response should be empty.
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
src/MpcNET/Commands/Output/OutputsCommand.cs
Normal file
29
src/MpcNET/Commands/Output/OutputsCommand.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Output
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Shows information about all outputs.
|
||||||
|
/// </summary>
|
||||||
|
public class OutputsCommand : IMpcCommand<IEnumerable<MpdOutput>>
|
||||||
|
{
|
||||||
|
public string Value => "outputs";
|
||||||
|
|
||||||
|
public IEnumerable<MpdOutput> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = new List<MpdOutput>();
|
||||||
|
|
||||||
|
for (var i = 0; i < response.Count; i += 3)
|
||||||
|
{
|
||||||
|
var outputId = int.Parse(response[i].Value);
|
||||||
|
var outputName = response[i + 1].Value;
|
||||||
|
var outputEnabled = response[i + 2].Value == "1";
|
||||||
|
|
||||||
|
result.Add(new MpdOutput(outputId, outputName, outputEnabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Output/ToggleOutputCommand.cs
Normal file
24
src/MpcNET/Commands/Output/ToggleOutputCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Output
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Turns an output on or off, depending on the current state.
|
||||||
|
/// </summary>
|
||||||
|
internal class ToggleOutputCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly int outputId;
|
||||||
|
|
||||||
|
public ToggleOutputCommand(int outputId)
|
||||||
|
{
|
||||||
|
this.outputId = outputId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "toggleoutput", outputId);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/MpcNET/Commands/Playback/NextCommand.cs
Normal file
14
src/MpcNET/Commands/Playback/NextCommand.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playback
|
||||||
|
{
|
||||||
|
internal class NextCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
public string Value => string.Join(" ", "next");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/MpcNET/Commands/Playback/PlayCommand.cs
Normal file
33
src/MpcNET/Commands/Playback/PlayCommand.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playback
|
||||||
|
{
|
||||||
|
internal class PlayCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly IMpdFile mpdFile;
|
||||||
|
|
||||||
|
public PlayCommand(IMpdFile mpdFile)
|
||||||
|
{
|
||||||
|
this.mpdFile = mpdFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.mpdFile.HasId)
|
||||||
|
{
|
||||||
|
return string.Join(" ", "playid", this.mpdFile.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join(" ", "play", this.mpdFile.Pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/MpcNET/Commands/Playback/PlayPauseCommand.cs
Normal file
14
src/MpcNET/Commands/Playback/PlayPauseCommand.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playback
|
||||||
|
{
|
||||||
|
internal class PlayPauseCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
public string Value => string.Join(" ", "pause");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/MpcNET/Commands/Playback/PreviousCommand.cs
Normal file
14
src/MpcNET/Commands/Playback/PreviousCommand.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playback
|
||||||
|
{
|
||||||
|
internal class PreviousCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
public string Value => string.Join(" ", "previous");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/MpcNET/Commands/Playback/StopCommand.cs
Normal file
14
src/MpcNET/Commands/Playback/StopCommand.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playback
|
||||||
|
{
|
||||||
|
internal class StopCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
public string Value => string.Join(" ", "stop");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Playlist/AddCommand.cs
Normal file
24
src/MpcNET/Commands/Playlist/AddCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the file URI to the playlist (directories add recursively). URI can also be a single file.
|
||||||
|
/// </summary>
|
||||||
|
internal class AddCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly string _uri;
|
||||||
|
|
||||||
|
public AddCommand(string uri)
|
||||||
|
{
|
||||||
|
_uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "add", $"\"{_uri}\"");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Playlist/AddIdCommand.cs
Normal file
24
src/MpcNET/Commands/Playlist/AddIdCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a song to the playlist (non-recursive) and returns the song id.
|
||||||
|
/// </summary>
|
||||||
|
internal class AddIdCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly string _uri;
|
||||||
|
|
||||||
|
public AddIdCommand(string uri)
|
||||||
|
{
|
||||||
|
_uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "addid", $"\"{_uri}\"");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
src/MpcNET/Commands/Playlist/ClearCommand.cs
Normal file
17
src/MpcNET/Commands/Playlist/ClearCommand.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class ClearCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
public string Value => "clear";
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Playlist/DeleteCommand.cs
Normal file
24
src/MpcNET/Commands/Playlist/DeleteCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes a song from the playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class DeleteCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly int position;
|
||||||
|
|
||||||
|
public DeleteCommand(int position)
|
||||||
|
{
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "delete", this.position);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Playlist/DeleteIdCommand.cs
Normal file
24
src/MpcNET/Commands/Playlist/DeleteIdCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes the song SONGID from the playlist
|
||||||
|
/// </summary>
|
||||||
|
internal class DeleteIdCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly int songId;
|
||||||
|
|
||||||
|
public DeleteIdCommand(int songId)
|
||||||
|
{
|
||||||
|
this.songId = songId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "deleteid", this.songId);
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/MpcNET/Commands/Playlist/ListPlaylistCommand.cs
Normal file
28
src/MpcNET/Commands/Playlist/ListPlaylistCommand.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Lists the songs in the playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class ListPlaylistCommand : IMpcCommand<IEnumerable<IMpdFilePath>>
|
||||||
|
{
|
||||||
|
private readonly string _playlistName;
|
||||||
|
|
||||||
|
public ListPlaylistCommand(string playlistName)
|
||||||
|
{
|
||||||
|
_playlistName = playlistName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "listplaylist", $"\"{_playlistName}\"");
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFilePath> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var results = response.Where(line => line.Key.Equals("file")).Select(line => new MpdFile(line.Value));
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/MpcNET/Commands/Playlist/ListPlaylistInfoCommand.cs
Normal file
25
src/MpcNET/Commands/Playlist/ListPlaylistInfoCommand.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Lists the songs with metadata in the playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class ListPlaylistInfoCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||||
|
{
|
||||||
|
private readonly string _playlistName;
|
||||||
|
|
||||||
|
public ListPlaylistInfoCommand(string playlistName)
|
||||||
|
{
|
||||||
|
_playlistName = playlistName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "listplaylistinfo", $"\"{_playlistName}\"");
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return MpdFile.CreateList(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/MpcNET/Commands/Playlist/ListPlaylistsCommand.cs
Normal file
33
src/MpcNET/Commands/Playlist/ListPlaylistsCommand.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Prints a list of the playlist directory.
|
||||||
|
/// </summary>
|
||||||
|
internal class ListPlaylistsCommand : IMpcCommand<IEnumerable<MpdPlaylist>>
|
||||||
|
{
|
||||||
|
public string Value => "listplaylists";
|
||||||
|
|
||||||
|
public IEnumerable<MpdPlaylist> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = new List<MpdPlaylist>();
|
||||||
|
|
||||||
|
foreach (var line in response)
|
||||||
|
{
|
||||||
|
if (line.Key.Equals("playlist"))
|
||||||
|
{
|
||||||
|
result.Add(new MpdPlaylist(line.Value));
|
||||||
|
}
|
||||||
|
else if (line.Key.Equals("Last-Modified"))
|
||||||
|
{
|
||||||
|
result.Last().AddLastModified(line.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/MpcNET/Commands/Playlist/LoadCommand.cs
Normal file
24
src/MpcNET/Commands/Playlist/LoadCommand.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the playlist into the current queue.
|
||||||
|
/// </summary>
|
||||||
|
internal class LoadCommand : IMpcCommand<string>
|
||||||
|
{
|
||||||
|
private readonly string _playlistName;
|
||||||
|
|
||||||
|
public LoadCommand(string playlistName)
|
||||||
|
{
|
||||||
|
_playlistName = playlistName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join(" ", "load", $"\"{_playlistName}\"");
|
||||||
|
|
||||||
|
public string FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return string.Join(", ", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/MpcNET/Commands/Playlist/PlaylistCommand.cs
Normal file
21
src/MpcNET/Commands/Playlist/PlaylistCommand.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Displays the current playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class PlaylistCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||||
|
{
|
||||||
|
public string Value => "playlist";
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var results = response.Select(line => MpdFile.Create(line.Value, int.Parse(line.Key)));
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/MpcNET/Commands/Playlist/PlaylistIdCommand.cs
Normal file
25
src/MpcNET/Commands/Playlist/PlaylistIdCommand.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Displays song ID in the playlist.
|
||||||
|
/// </summary>
|
||||||
|
internal class PlaylistIdCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||||
|
{
|
||||||
|
private readonly int _songId;
|
||||||
|
|
||||||
|
public PlaylistIdCommand(int songId)
|
||||||
|
{
|
||||||
|
_songId = songId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value => string.Join((string) " ", new[] {"playlistid"}, _songId);
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return MpdFile.CreateList(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/MpcNET/Commands/Playlist/PlaylistInfoCommand.cs
Normal file
18
src/MpcNET/Commands/Playlist/PlaylistInfoCommand.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Displays a list of all songs in the playlist,
|
||||||
|
/// </summary>
|
||||||
|
internal class PlaylistInfoCommand : IMpcCommand<IEnumerable<IMpdFile>>
|
||||||
|
{
|
||||||
|
public string Value => "playlistinfo";
|
||||||
|
|
||||||
|
public IEnumerable<IMpdFile> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return MpdFile.CreateList(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/MpcNET/Commands/Reflection/CommandsCommand.cs
Normal file
22
src/MpcNET/Commands/Reflection/CommandsCommand.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Reflection
|
||||||
|
{
|
||||||
|
// config : This command is only permitted to "local" clients (connected via UNIX domain socket).
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows which commands the current user has access to.
|
||||||
|
/// </summary>
|
||||||
|
public class CommandsCommand : IMpcCommand<IEnumerable<string>>
|
||||||
|
{
|
||||||
|
public string Value => "commands";
|
||||||
|
|
||||||
|
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = response.Where(item => item.Key.Equals("command")).Select(item => item.Value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
src/MpcNET/Commands/Reflection/DecodersCommand.cs
Normal file
44
src/MpcNET/Commands/Reflection/DecodersCommand.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Reflection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Print a list of decoder plugins, followed by their supported suffixes and MIME types.
|
||||||
|
/// </summary>
|
||||||
|
public class DecodersCommand : IMpcCommand<IEnumerable<MpdDecoderPlugin>>
|
||||||
|
{
|
||||||
|
public string Value => "decoders";
|
||||||
|
|
||||||
|
public IEnumerable<MpdDecoderPlugin> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = new List<MpdDecoderPlugin>();
|
||||||
|
|
||||||
|
var mpdDecoderPlugin = MpdDecoderPlugin.Empty;
|
||||||
|
foreach (var line in response)
|
||||||
|
{
|
||||||
|
if (line.Key.Equals("plugin"))
|
||||||
|
{
|
||||||
|
if (mpdDecoderPlugin.IsInitialized)
|
||||||
|
{
|
||||||
|
result.Add(mpdDecoderPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpdDecoderPlugin = new MpdDecoderPlugin(line.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.Key.Equals("suffix") && mpdDecoderPlugin.IsInitialized)
|
||||||
|
{
|
||||||
|
mpdDecoderPlugin.AddSuffix(line.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.Key.Equals("mime_type") && mpdDecoderPlugin.IsInitialized)
|
||||||
|
{
|
||||||
|
mpdDecoderPlugin.AddMediaType(line.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/MpcNET/Commands/Reflection/TagTypesCommand.cs
Normal file
22
src/MpcNET/Commands/Reflection/TagTypesCommand.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Reflection
|
||||||
|
{
|
||||||
|
// TODO: notcommands : Shows which commands the current user does not have access to.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows a list of available song metadata.
|
||||||
|
/// </summary>
|
||||||
|
public class TagTypesCommand : IMpcCommand<IEnumerable<string>>
|
||||||
|
{
|
||||||
|
public string Value => "tagtypes";
|
||||||
|
|
||||||
|
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = response.Where(item => item.Key.Equals("tagtype")).Select(item => item.Value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/MpcNET/Commands/Reflection/UrlHandlersCommand.cs
Normal file
20
src/MpcNET/Commands/Reflection/UrlHandlersCommand.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Reflection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of available URL handlers.
|
||||||
|
/// </summary>
|
||||||
|
public class UrlHandlersCommand : IMpcCommand<IEnumerable<string>>
|
||||||
|
{
|
||||||
|
public string Value => "urlhandlers";
|
||||||
|
|
||||||
|
public IEnumerable<string> FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var result = response.Where(item => item.Key.Equals("handler")).Select(item => item.Value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/MpcNET/Commands/Status/CurrentSongCommand.cs
Normal file
15
src/MpcNET/Commands/Status/CurrentSongCommand.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MpcNET.Types;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Status
|
||||||
|
{
|
||||||
|
internal class CurrentSongCommand : IMpcCommand<IMpdFile>
|
||||||
|
{
|
||||||
|
public string Value => "currentsong";
|
||||||
|
|
||||||
|
public IMpdFile FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
return MpdFile.Create(response, 0).mpdFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
132
src/MpcNET/Commands/Status/StatusCommand.cs
Normal file
132
src/MpcNET/Commands/Status/StatusCommand.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace MpcNET.Commands.Status
|
||||||
|
{
|
||||||
|
internal class StatusCommand : IMpcCommand<MpdStatus>
|
||||||
|
{
|
||||||
|
public string Value => "status";
|
||||||
|
|
||||||
|
public MpdStatus FormatResponse(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
int volume = -1;
|
||||||
|
bool repeat = false;
|
||||||
|
bool random = false;
|
||||||
|
bool single = false;
|
||||||
|
bool consume = false;
|
||||||
|
int playlist = -1;
|
||||||
|
int playlistLength = 0;
|
||||||
|
int playlistSong = -1;
|
||||||
|
int playlistSongId = -1;
|
||||||
|
int playlistNextSong = -1;
|
||||||
|
int playlistNextSongId = -1;
|
||||||
|
int bitrate = 0;
|
||||||
|
int audioSampleRate = -1;
|
||||||
|
int audioBits = -1;
|
||||||
|
int audioChannels = -1;
|
||||||
|
int crossfade = -1;
|
||||||
|
MpdState mpdState = MpdState.Unknown;
|
||||||
|
TimeSpan elapsed;
|
||||||
|
TimeSpan duration;
|
||||||
|
int updatingDb = -1;
|
||||||
|
string error = string.Empty;
|
||||||
|
foreach (var keyValuePair in response)
|
||||||
|
{
|
||||||
|
var value = keyValuePair.Value;
|
||||||
|
switch (keyValuePair.Key)
|
||||||
|
{
|
||||||
|
case "volume":
|
||||||
|
int.TryParse(value, out volume);
|
||||||
|
break;
|
||||||
|
case "repeat":
|
||||||
|
repeat = "1" == value;
|
||||||
|
break;
|
||||||
|
case "random":
|
||||||
|
random = "1" == value;
|
||||||
|
break;
|
||||||
|
case "single":
|
||||||
|
single = "1" == value;
|
||||||
|
break;
|
||||||
|
case "consume":
|
||||||
|
consume = "1" == value;
|
||||||
|
break;
|
||||||
|
case "playlist":
|
||||||
|
int.TryParse(value, out playlist);
|
||||||
|
break;
|
||||||
|
case "playlistlength":
|
||||||
|
int.TryParse(value, out playlistLength);
|
||||||
|
break;
|
||||||
|
case "song":
|
||||||
|
int.TryParse(value, out playlistSong);
|
||||||
|
break;
|
||||||
|
case "songid":
|
||||||
|
int.TryParse(value, out playlistSongId);
|
||||||
|
break;
|
||||||
|
case "nextsong":
|
||||||
|
int.TryParse(value, out playlistNextSong);
|
||||||
|
break;
|
||||||
|
case "nextsongid":
|
||||||
|
int.TryParse(value, out playlistNextSongId);
|
||||||
|
break;
|
||||||
|
case "bitrate":
|
||||||
|
int.TryParse(value, out bitrate);
|
||||||
|
break;
|
||||||
|
case "audio":
|
||||||
|
var audioFormat = value.Split(':');
|
||||||
|
int.TryParse(audioFormat[0], out audioSampleRate);
|
||||||
|
int.TryParse(audioFormat[1], out audioBits);
|
||||||
|
int.TryParse(audioFormat[2], out audioChannels);
|
||||||
|
break;
|
||||||
|
case "xfade":
|
||||||
|
int.TryParse(value, out crossfade);
|
||||||
|
break;
|
||||||
|
case "state":
|
||||||
|
Enum.TryParse(value, true, out mpdState);
|
||||||
|
break;
|
||||||
|
case "elapsed":
|
||||||
|
elapsed = ParseTime(value);
|
||||||
|
break;
|
||||||
|
case "duration":
|
||||||
|
duration = ParseTime(value);
|
||||||
|
break;
|
||||||
|
case "updating_db":
|
||||||
|
int.TryParse(value, out updatingDb);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Debug.WriteLine($"Unprocessed status: {keyValuePair.Key} - {keyValuePair.Value}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MpdStatus(
|
||||||
|
volume,
|
||||||
|
repeat,
|
||||||
|
random,
|
||||||
|
playlist,
|
||||||
|
playlistLength,
|
||||||
|
crossfade,
|
||||||
|
mpdState,
|
||||||
|
playlistSong,
|
||||||
|
playlistSongId,
|
||||||
|
playlistNextSong,
|
||||||
|
playlistNextSongId,
|
||||||
|
elapsed,
|
||||||
|
duration,
|
||||||
|
bitrate,
|
||||||
|
audioSampleRate,
|
||||||
|
audioBits,
|
||||||
|
audioChannels,
|
||||||
|
updatingDb,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TimeSpan ParseTime(string value)
|
||||||
|
{
|
||||||
|
var timeParts = value.Split(new[] { '.' }, 2);
|
||||||
|
int.TryParse(timeParts[0], out var seconds);
|
||||||
|
int.TryParse(timeParts[1], out var milliseconds);
|
||||||
|
return TimeSpan.FromSeconds(seconds) + TimeSpan.FromMilliseconds(milliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/MpcNET/Message/IMpdMessage.cs
Normal file
10
src/MpcNET/Message/IMpdMessage.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace MpcNET.Message
|
||||||
|
{
|
||||||
|
public interface IMpdMessage<T>
|
||||||
|
{
|
||||||
|
IMpdRequest<T> Request { get; }
|
||||||
|
IMpdResponse<T> Response { get; }
|
||||||
|
|
||||||
|
bool IsResponseValid { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -6,12 +6,6 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace MpcNET.Message
|
namespace MpcNET.Message
|
||||||
{
|
{
|
||||||
public interface IMpdMessage<T>
|
|
||||||
{
|
|
||||||
IMpdRequest<T> Request { get; }
|
|
||||||
IMpdResponse<T> Response { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerDisplay("Request: {Request.Command.Value} | Response Status: {Response.State.Status}")]
|
[DebuggerDisplay("Request: {Request.Command.Value} | Response Status: {Response.State.Status}")]
|
||||||
public class MpdMessage<T> : IMpdMessage<T>
|
public class MpdMessage<T> : IMpdMessage<T>
|
||||||
{
|
{
|
||||||
@ -30,8 +24,11 @@ namespace MpcNET.Message
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IMpdRequest<T> Request { get; }
|
public IMpdRequest<T> Request { get; }
|
||||||
|
|
||||||
public IMpdResponse<T> Response { get; }
|
public IMpdResponse<T> Response { get; }
|
||||||
|
|
||||||
|
public bool IsResponseValid => this.Response.State.Status == "OK";
|
||||||
|
|
||||||
private IList<KeyValuePair<string, string>> GetValuesFromResponse()
|
private IList<KeyValuePair<string, string>> GetValuesFromResponse()
|
||||||
{
|
{
|
||||||
var result = new List<KeyValuePair<string, string>>();
|
var result = new List<KeyValuePair<string, string>>();
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MpcNET.Message;
|
using MpcNET.Message;
|
||||||
using MpcNET.Utils;
|
using MpcNET.Utils;
|
||||||
@ -17,18 +18,20 @@ namespace MpcNET
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MpcConnection
|
public class MpcConnection
|
||||||
{
|
{
|
||||||
|
private readonly Encoding encoding = new UTF8Encoding();
|
||||||
private readonly IPEndPoint _server;
|
private readonly IPEndPoint _server;
|
||||||
|
|
||||||
private TcpClient _tcpClient;
|
private TcpClient _tcpClient;
|
||||||
private NetworkStream _networkStream;
|
private NetworkStream _networkStream;
|
||||||
private StreamReader _reader;
|
|
||||||
private StreamWriter _writer;
|
|
||||||
|
|
||||||
private string _version;
|
private string _version;
|
||||||
|
|
||||||
public MpcConnection(IPEndPoint server)
|
public MpcConnection(IPEndPoint server)
|
||||||
{
|
{
|
||||||
if (IsConnected) return;
|
if (this.IsConnected)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ClearConnectionFields();
|
ClearConnectionFields();
|
||||||
_server = server;
|
_server = server;
|
||||||
@ -52,17 +55,18 @@ namespace MpcNET
|
|||||||
_networkStream = _tcpClient.GetStream();
|
_networkStream = _tcpClient.GetStream();
|
||||||
|
|
||||||
// Encoding UTF8 has some problems with TcpClient: https://bugs.musicpd.org/view.php?id=4501
|
// Encoding UTF8 has some problems with TcpClient: https://bugs.musicpd.org/view.php?id=4501
|
||||||
_reader = new StreamReader(_networkStream);
|
using (var reader = new StreamReader(_networkStream, this.encoding, true, 512, true))
|
||||||
_writer = new StreamWriter(_networkStream) { NewLine = "\n" };
|
{
|
||||||
|
var firstLine = await reader.ReadLineAsync();
|
||||||
var firstLine = _reader.ReadLine();
|
|
||||||
if (!firstLine.StartsWith(Constants.FirstLinePrefix))
|
if (!firstLine.StartsWith(Constants.FirstLinePrefix))
|
||||||
{
|
{
|
||||||
await DisconnectAsync();
|
await DisconnectAsync();
|
||||||
throw new InvalidDataException("Response of mpd does not start with \"" + Constants.FirstLinePrefix + "\"." );
|
throw new InvalidDataException("Response of mpd does not start with \"" + Constants.FirstLinePrefix + "\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
_version = firstLine.Substring(Constants.FirstLinePrefix.Length);
|
_version = firstLine.Substring(Constants.FirstLinePrefix.Length);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task DisconnectAsync()
|
public Task DisconnectAsync()
|
||||||
{
|
{
|
||||||
@ -87,14 +91,28 @@ namespace MpcNET
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_writer.WriteLine(command.Value);
|
Console.WriteLine("Command: " + command.Value);
|
||||||
_writer.Flush();
|
// Encoding UTF8 has some problems with TcpClient: https://bugs.musicpd.org/view.php?id=4501
|
||||||
|
|
||||||
|
using (var writer = new StreamWriter(_networkStream, this.encoding, 512, true) { NewLine = "\n" })
|
||||||
|
{
|
||||||
|
writer.WriteLine(command.Value);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
response = await ReadResponseAsync();
|
response = await ReadResponseAsync();
|
||||||
}
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Exception:" + exception);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await DisconnectAsync();
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
try { await DisconnectAsync(); } catch (Exception) { }
|
}
|
||||||
|
|
||||||
return null; // TODO: Create Null Object for MpdResponse
|
return null; // TODO: Create Null Object for MpdResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,20 +134,28 @@ namespace MpcNET
|
|||||||
var response = new List<string>();
|
var response = new List<string>();
|
||||||
|
|
||||||
// Read response untli reach end token (OK or ACK)
|
// Read response untli reach end token (OK or ACK)
|
||||||
|
using (var reader = new StreamReader(_networkStream, this.encoding, true, 512, true))
|
||||||
|
{
|
||||||
string responseLine;
|
string responseLine;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
responseLine = await _reader.ReadLineAsync();
|
responseLine = await reader.ReadLineAsync();
|
||||||
|
Console.WriteLine("ReadLine:|" + responseLine + "|");
|
||||||
|
if (responseLine == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Received null");
|
||||||
|
responseLine = string.Empty;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
response.Add(responseLine);
|
response.Add(responseLine);
|
||||||
} while (!(responseLine.Equals(Constants.Ok) || responseLine.StartsWith(Constants.Ack)));
|
} while (!(responseLine.Equals(Constants.Ok) || responseLine.StartsWith(Constants.Ack)));
|
||||||
|
}
|
||||||
|
|
||||||
return response.Where(line => !string.IsNullOrEmpty(line)).ToArray();
|
return response.Where(line => !string.IsNullOrEmpty(line)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearConnectionFields()
|
private void ClearConnectionFields()
|
||||||
{
|
{
|
||||||
_writer?.Dispose();
|
|
||||||
_reader?.Dispose();
|
|
||||||
_networkStream?.Dispose();
|
_networkStream?.Dispose();
|
||||||
_tcpClient?.Dispose();
|
_tcpClient?.Dispose();
|
||||||
_version = string.Empty;
|
_version = string.Empty;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard1.6</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<AssemblyName>MpcNET</AssemblyName>
|
<AssemblyName>MpcNET</AssemblyName>
|
||||||
<PackageId>MpcNET</PackageId>
|
<PackageId>MpcNET</PackageId>
|
||||||
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
|
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
|
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
@ -17,7 +16,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
<None Include="Commands\Commands.Status.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||||
|
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
25
src/MpcNET/MpdState.cs
Normal file
25
src/MpcNET/MpdState.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace MpcNET
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The possible states of the MPD.
|
||||||
|
/// </summary>
|
||||||
|
public enum MpdState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The state of the MPD could not be translated into this enumeration.
|
||||||
|
/// </summary>
|
||||||
|
Unknown,
|
||||||
|
/// <summary>
|
||||||
|
/// The MPD is playing a track.
|
||||||
|
/// </summary>
|
||||||
|
Play,
|
||||||
|
/// <summary>
|
||||||
|
/// The MPD is not playing a track.
|
||||||
|
/// </summary>
|
||||||
|
Stop,
|
||||||
|
/// <summary>
|
||||||
|
/// The playback of the MPD is currently paused.
|
||||||
|
/// </summary>
|
||||||
|
Pause
|
||||||
|
}
|
||||||
|
}
|
@ -1,119 +1,13 @@
|
|||||||
using System.Text;
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace MpcNET
|
namespace MpcNET
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The possible states of the MPD.
|
|
||||||
/// </summary>
|
|
||||||
public enum MpdState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The state of the MPD could not be translated into this enumeration.
|
|
||||||
/// </summary>
|
|
||||||
Unknown,
|
|
||||||
/// <summary>
|
|
||||||
/// The MPD is playing a track.
|
|
||||||
/// </summary>
|
|
||||||
Play,
|
|
||||||
/// <summary>
|
|
||||||
/// The MPD is not playing a track.
|
|
||||||
/// </summary>
|
|
||||||
Stop,
|
|
||||||
/// <summary>
|
|
||||||
/// The playback of the MPD is currently paused.
|
|
||||||
/// </summary>
|
|
||||||
Pause
|
|
||||||
}
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The MpdStatus class contains all values describing the current status of the MPD.
|
/// The MpdStatus class contains all values describing the current status of the MPD.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MpdStatus
|
public class MpdStatus
|
||||||
{
|
{
|
||||||
private int volume;
|
|
||||||
private bool repeat;
|
|
||||||
private bool random;
|
|
||||||
private int playlist;
|
|
||||||
private int playlistLength;
|
|
||||||
private int xFade;
|
|
||||||
private MpdState state;
|
|
||||||
private int song;
|
|
||||||
private int songId;
|
|
||||||
private int timeElapsed;
|
|
||||||
private int timeTotal;
|
|
||||||
private int bitrate;
|
|
||||||
private int audioSampleRate;
|
|
||||||
private int audioBits;
|
|
||||||
private int audioChannels;
|
|
||||||
private int updatingDb;
|
|
||||||
private string error;
|
|
||||||
/// <summary>
|
|
||||||
/// The current volume of the output.
|
|
||||||
/// </summary>
|
|
||||||
public int Volume { get { return this.volume; } }
|
|
||||||
/// <summary>
|
|
||||||
/// If the playlist is repeated after finish.
|
|
||||||
/// </summary>
|
|
||||||
public bool Repeat { get { return this.repeat; } }
|
|
||||||
/// <summary>
|
|
||||||
/// If the playlist is played in random order.
|
|
||||||
/// </summary>
|
|
||||||
public bool Random { get { return this.random; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The version number of the playlist.
|
|
||||||
/// </summary>
|
|
||||||
public int Playlist { get { return this.playlist; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The length of the playlist.
|
|
||||||
/// </summary>
|
|
||||||
public int PlaylistLength { get { return this.playlistLength; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The number of seconds crossfaded between song changes.
|
|
||||||
/// </summary>
|
|
||||||
public int XFade { get { return this.xFade; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The state of the MPD.
|
|
||||||
/// </summary>
|
|
||||||
public MpdState State { get { return this.state; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The index of the currently played song in the playlist.
|
|
||||||
/// </summary>
|
|
||||||
public int Song { get { return this.song; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The id of the song currently played.
|
|
||||||
/// </summary>
|
|
||||||
public int SongId { get { return this.songId; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The number of seconds already played of the current song.
|
|
||||||
/// </summary>
|
|
||||||
public int TimeElapsed { get { return this.timeElapsed; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The length of the current song in seconds.
|
|
||||||
/// </summary>
|
|
||||||
public int TimeTotal { get { return this.timeTotal; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The bitrate of the current song.
|
|
||||||
/// </summary>
|
|
||||||
public int Bitrate { get { return this.bitrate; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The audio sample rate of the current song.
|
|
||||||
/// </summary>
|
|
||||||
public int AudioSampleRate { get { return this.audioSampleRate; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The audio bits of the current song.
|
|
||||||
/// </summary>
|
|
||||||
public int AudioBits { get { return this.audioBits; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The number of audio channels of the current song.
|
|
||||||
/// </summary>
|
|
||||||
public int AudioChannels { get { return this.audioChannels; } }
|
|
||||||
/// <summary>
|
|
||||||
/// The number of the update on the MPD database currently running.
|
|
||||||
/// </summary>
|
|
||||||
public int UpdatingDb { get { return this.updatingDb; } }
|
|
||||||
/// <summary>
|
|
||||||
/// An error message, if there is an error.
|
|
||||||
/// </summary>
|
|
||||||
public string Error { get { return this.error; } }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new MpdStatus object.
|
/// Creates a new MpdStatus object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -126,8 +20,10 @@ namespace MpcNET
|
|||||||
/// <param name="state">The state of the MPD.</param>
|
/// <param name="state">The state of the MPD.</param>
|
||||||
/// <param name="song">The index of the currently played song in the playlist.</param>
|
/// <param name="song">The index of the currently played song in the playlist.</param>
|
||||||
/// <param name="songId">The id of the song currently played.</param>
|
/// <param name="songId">The id of the song currently played.</param>
|
||||||
/// <param name="timeElapsed">The number of seconds already played of the current song.</param>
|
/// <param name="nextSong">The next song.</param>
|
||||||
/// <param name="timeTotal">The length of the current song in seconds.</param>
|
/// <param name="nextSongId">The next song identifier.</param>
|
||||||
|
/// <param name="elapsed">The elapsed.</param>
|
||||||
|
/// <param name="duration">The duration.</param>
|
||||||
/// <param name="bitrate">The bitrate of the current song.</param>
|
/// <param name="bitrate">The bitrate of the current song.</param>
|
||||||
/// <param name="audioSampleRate">The audio sample rate of the current song.</param>
|
/// <param name="audioSampleRate">The audio sample rate of the current song.</param>
|
||||||
/// <param name="audioBits">The audio bits of the current song.</param>
|
/// <param name="audioBits">The audio bits of the current song.</param>
|
||||||
@ -144,34 +40,126 @@ namespace MpcNET
|
|||||||
MpdState state,
|
MpdState state,
|
||||||
int song,
|
int song,
|
||||||
int songId,
|
int songId,
|
||||||
int timeElapsed,
|
int nextSong,
|
||||||
int timeTotal,
|
int nextSongId,
|
||||||
|
TimeSpan elapsed,
|
||||||
|
TimeSpan duration,
|
||||||
int bitrate,
|
int bitrate,
|
||||||
int audioSampleRate,
|
int audioSampleRate,
|
||||||
int audioBits,
|
int audioBits,
|
||||||
int audioChannels,
|
int audioChannels,
|
||||||
int updatingDb,
|
int updatingDb,
|
||||||
string error
|
string error)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
this.volume = volume;
|
this.Volume = volume;
|
||||||
this.repeat = repeat;
|
this.Repeat = repeat;
|
||||||
this.random = random;
|
this.Random = random;
|
||||||
this.playlist = playlist;
|
this.Playlist = playlist;
|
||||||
this.playlistLength = playlistLength;
|
this.PlaylistLength = playlistLength;
|
||||||
this.xFade = xFade;
|
this.XFade = xFade;
|
||||||
this.state = state;
|
this.State = state;
|
||||||
this.song = song;
|
this.Song = song;
|
||||||
this.songId = songId;
|
this.SongId = songId;
|
||||||
this.timeElapsed = timeElapsed;
|
NextSong = nextSong;
|
||||||
this.timeTotal = timeTotal;
|
NextSongId = nextSongId;
|
||||||
this.bitrate = bitrate;
|
this.Elapsed = elapsed;
|
||||||
this.audioSampleRate = audioSampleRate;
|
this.Duration = duration;
|
||||||
this.audioBits = audioBits;
|
this.Bitrate = bitrate;
|
||||||
this.audioChannels = audioChannels;
|
this.AudioSampleRate = audioSampleRate;
|
||||||
this.updatingDb = updatingDb;
|
this.AudioBits = audioBits;
|
||||||
this.error = error;
|
this.AudioChannels = audioChannels;
|
||||||
|
this.UpdatingDb = updatingDb;
|
||||||
|
this.Error = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current volume of the output.
|
||||||
|
/// </summary>
|
||||||
|
public int Volume { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the playlist is repeated after finish.
|
||||||
|
/// </summary>
|
||||||
|
public bool Repeat { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the playlist is played in random order.
|
||||||
|
/// </summary>
|
||||||
|
public bool Random { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The version number of the playlist.
|
||||||
|
/// </summary>
|
||||||
|
public int Playlist { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The length of the playlist.
|
||||||
|
/// </summary>
|
||||||
|
public int PlaylistLength { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of seconds crossfaded between song changes.
|
||||||
|
/// </summary>
|
||||||
|
public int XFade { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The state of the MPD.
|
||||||
|
/// </summary>
|
||||||
|
public MpdState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The index of the currently played song in the playlist.
|
||||||
|
/// </summary>
|
||||||
|
public int Song { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The id of the song currently played.
|
||||||
|
/// </summary>
|
||||||
|
public int SongId { get; }
|
||||||
|
|
||||||
|
public int NextSong { get; }
|
||||||
|
public int NextSongId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of seconds already played of the current song.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan Elapsed { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The length of the current song in seconds.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan Duration { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bitrate of the current song.
|
||||||
|
/// </summary>
|
||||||
|
public int Bitrate { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The audio sample rate of the current song.
|
||||||
|
/// </summary>
|
||||||
|
public int AudioSampleRate { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The audio bits of the current song.
|
||||||
|
/// </summary>
|
||||||
|
public int AudioBits { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of audio channels of the current song.
|
||||||
|
/// </summary>
|
||||||
|
public int AudioChannels { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of the update on the MPD database currently running.
|
||||||
|
/// </summary>
|
||||||
|
public int UpdatingDb { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An error message, if there is an error.
|
||||||
|
/// </summary>
|
||||||
|
public string Error { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a string representation of the object maily for debugging purpuses.
|
/// Returns a string representation of the object maily for debugging purpuses.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -180,13 +168,13 @@ namespace MpcNET
|
|||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
appendInt(builder, "volume", this.volume);
|
AppendInt(builder, "volume", this.Volume);
|
||||||
appendBool(builder, "repeat", this.repeat);
|
AppendBool(builder, "repeat", this.Repeat);
|
||||||
appendBool(builder, "random", this.random);
|
AppendBool(builder, "random", this.Random);
|
||||||
appendInt(builder, "playlist", this.playlist);
|
AppendInt(builder, "playlist", this.Playlist);
|
||||||
appendInt(builder, "playlistlength", this.playlistLength);
|
AppendInt(builder, "playlistlength", this.PlaylistLength);
|
||||||
appendInt(builder, "xfade", this.xFade);
|
AppendInt(builder, "xfade", this.XFade);
|
||||||
switch (this.state)
|
switch (this.State)
|
||||||
{
|
{
|
||||||
case MpdState.Play:
|
case MpdState.Play:
|
||||||
builder.AppendLine("state: play");
|
builder.AppendLine("state: play");
|
||||||
@ -198,38 +186,39 @@ namespace MpcNET
|
|||||||
builder.AppendLine("state: stop");
|
builder.AppendLine("state: stop");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
appendInt(builder, "song", this.song);
|
|
||||||
appendInt(builder, "songid", this.songId);
|
AppendInt(builder, "song", this.Song);
|
||||||
if ((this.timeElapsed >= 0) || (this.timeTotal >= 0))
|
AppendInt(builder, "songid", this.SongId);
|
||||||
|
if (this.Elapsed > TimeSpan.Zero || this.Duration > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
builder.Append("time: ");
|
builder.Append("time: ");
|
||||||
builder.Append(this.timeElapsed);
|
builder.Append(this.Elapsed);
|
||||||
builder.Append(":");
|
builder.Append(":");
|
||||||
builder.Append(this.timeTotal);
|
builder.Append(this.Duration);
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
}
|
}
|
||||||
appendInt(builder, "bitrate", this.bitrate);
|
AppendInt(builder, "bitrate", this.Bitrate);
|
||||||
if ((this.audioSampleRate >= 0) || (this.audioBits >= 0) || (this.audioChannels >= 0))
|
if ((AudioSampleRate >= 0) || (this.AudioBits >= 0) || (this.AudioChannels >= 0))
|
||||||
{
|
{
|
||||||
builder.Append("audio: ");
|
builder.Append("audio: ");
|
||||||
builder.Append(this.audioSampleRate);
|
builder.Append(this.AudioSampleRate);
|
||||||
builder.Append(":");
|
builder.Append(":");
|
||||||
builder.Append(this.audioBits);
|
builder.Append(this.AudioBits);
|
||||||
builder.Append(":");
|
builder.Append(":");
|
||||||
builder.Append(this.audioChannels);
|
builder.Append(this.AudioChannels);
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
}
|
}
|
||||||
appendInt(builder, "updating_db", this.updatingDb);
|
AppendInt(builder, "updating_db", this.UpdatingDb);
|
||||||
if (this.error != null)
|
if (this.Error != null)
|
||||||
{
|
{
|
||||||
builder.Append("error: ");
|
builder.Append("error: ");
|
||||||
builder.AppendLine(this.error);
|
builder.AppendLine(this.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendInt(StringBuilder builder, string name, int value)
|
private static void AppendInt(StringBuilder builder, string name, int value)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
return;
|
return;
|
||||||
@ -240,7 +229,7 @@ namespace MpcNET
|
|||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendBool(StringBuilder builder, string name, bool value)
|
private static void AppendBool(StringBuilder builder, string name, bool value)
|
||||||
{
|
{
|
||||||
builder.Append(name);
|
builder.Append(name);
|
||||||
builder.Append(": ");
|
builder.Append(": ");
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
@ -2,11 +2,6 @@
|
|||||||
|
|
||||||
namespace MpcNET.Types
|
namespace MpcNET.Types
|
||||||
{
|
{
|
||||||
public interface IMpdFilePath
|
|
||||||
{
|
|
||||||
string Path { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IMpdFile : IMpdFilePath
|
public interface IMpdFile : IMpdFilePath
|
||||||
{
|
{
|
||||||
int Time { get; }
|
int Time { get; }
|
||||||
@ -23,6 +18,76 @@ namespace MpcNET.Types
|
|||||||
int Disc { get; }
|
int Disc { get; }
|
||||||
int Pos { get; }
|
int Pos { get; }
|
||||||
int Id { get; }
|
int Id { get; }
|
||||||
IDictionary<string, string> UnknownMetadata { get; }
|
IReadOnlyDictionary<string, string> UnknownMetadata { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Time"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasTime { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Album"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasAlbum { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Artist"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasArtist { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Title"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasTitle { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Track"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasTrack { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Name"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Genre"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasGenre { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Date"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasDate { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Composer"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasComposer { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Performer"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasPerformer { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Comment"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasComment { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Disc"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasDisc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Pos"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasPos { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Id"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
bool HasId { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
7
src/MpcNET/Types/IMpdFilePath.cs
Normal file
7
src/MpcNET/Types/IMpdFilePath.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace MpcNET.Types
|
||||||
|
{
|
||||||
|
public interface IMpdFilePath
|
||||||
|
{
|
||||||
|
string Path { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MpcNET.Utils;
|
|
||||||
|
|
||||||
namespace MpcNET.Types
|
namespace MpcNET.Types
|
||||||
{
|
{
|
||||||
@ -8,97 +7,324 @@ namespace MpcNET.Types
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class MpdFile : IMpdFile
|
internal class MpdFile : IMpdFile
|
||||||
{
|
{
|
||||||
private const string TagTime = "Time";
|
internal const string TagFile = "file";
|
||||||
private const string TagArtist = "Artist";
|
internal const string TagTime = "Time";
|
||||||
private const string TagAlbum = "Album";
|
internal const string TagArtist = "Artist";
|
||||||
private const string TagTitle = "Title";
|
internal const string TagAlbum = "Album";
|
||||||
private const string TagTrack = "Track";
|
internal const string TagTitle = "Title";
|
||||||
private const string TagName = "Name";
|
internal const string TagTrack = "Track";
|
||||||
private const string TagGenre = "Genre";
|
internal const string TagName = "Name";
|
||||||
private const string TagDate = "Date";
|
internal const string TagGenre = "Genre";
|
||||||
private const string TagComposer = "Composer";
|
internal const string TagDate = "Date";
|
||||||
private const string TagPerformer = "Performer";
|
internal const string TagComposer = "Composer";
|
||||||
private const string TagComment = "Comment";
|
internal const string TagPerformer = "Performer";
|
||||||
private const string TagDisc = "Disc";
|
internal const string TagComment = "Comment";
|
||||||
private const string TagPos = "Pos";
|
internal const string TagDisc = "Disc";
|
||||||
private const string TagId = "Id";
|
internal const string TagPos = "Pos";
|
||||||
|
internal const string TagId = "Id";
|
||||||
|
|
||||||
private readonly IDictionary<string, string> _unknownMetadata = new Dictionary<string, string>();
|
internal const int NoTime = -1;
|
||||||
|
internal const string NoAlbum = null;
|
||||||
|
internal const string NoArtist = null;
|
||||||
|
internal const string NoTitle = null;
|
||||||
|
internal const string NoTrack = null;
|
||||||
|
internal const string NoName = null;
|
||||||
|
internal const string NoGenre = null;
|
||||||
|
internal const string NoDate = null;
|
||||||
|
internal const string NoComposer = null;
|
||||||
|
internal const string NoPerformer = null;
|
||||||
|
internal const string NoComment = null;
|
||||||
|
internal const int NoDisc = -1;
|
||||||
|
internal const int NoPos = -1;
|
||||||
|
internal const int NoId = -1;
|
||||||
|
|
||||||
internal MpdFile(string file)
|
internal MpdFile(
|
||||||
|
string path,
|
||||||
|
int time = NoTime,
|
||||||
|
string album = NoAlbum,
|
||||||
|
string artist = NoArtist,
|
||||||
|
string title = NoTitle,
|
||||||
|
string track = NoTrack,
|
||||||
|
string name = NoName,
|
||||||
|
string genre = NoGenre,
|
||||||
|
string date = NoDate,
|
||||||
|
string composer = NoComposer,
|
||||||
|
string performer = NoPerformer,
|
||||||
|
string comment = NoComment,
|
||||||
|
int disc = NoDisc,
|
||||||
|
int pos = NoPos,
|
||||||
|
int id = NoId,
|
||||||
|
IReadOnlyDictionary<string, string> unknownMetadata = null)
|
||||||
{
|
{
|
||||||
file.CheckNotNull();
|
this.Path = path;
|
||||||
|
this.Time = time;
|
||||||
Path = file;
|
this.Album = album;
|
||||||
|
this.Artist = artist;
|
||||||
|
this.Title = title;
|
||||||
|
this.Track = track;
|
||||||
|
this.Name = name;
|
||||||
|
this.Genre = genre;
|
||||||
|
this.Date = date;
|
||||||
|
this.Composer = composer;
|
||||||
|
this.Performer = performer;
|
||||||
|
this.Comment = comment;
|
||||||
|
this.Disc = disc;
|
||||||
|
this.Pos = pos;
|
||||||
|
this.Id = id;
|
||||||
|
this.UnknownMetadata = unknownMetadata ?? new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Path { get; }
|
public string Path { get; }
|
||||||
public int Time { get; private set; } = -1;
|
public int Time { get; }
|
||||||
public string Album { get; private set; } = string.Empty;
|
public string Album { get; }
|
||||||
public string Artist { get; private set; } = string.Empty;
|
public string Artist { get; }
|
||||||
public string Title { get; private set; } = string.Empty;
|
public string Title { get; }
|
||||||
public string Track { get; private set; } = string.Empty;
|
public string Track { get; }
|
||||||
public string Name { get; private set; } = string.Empty;
|
public string Name { get; }
|
||||||
public string Genre { get; private set; } = string.Empty;
|
public string Genre { get; }
|
||||||
public string Date { get; private set; } = string.Empty;
|
public string Date { get; }
|
||||||
public string Composer { get; private set; } = string.Empty;
|
public string Composer { get; }
|
||||||
public string Performer { get; private set; } = string.Empty;
|
public string Performer { get; }
|
||||||
public string Comment { get; private set; } = string.Empty;
|
public string Comment { get; }
|
||||||
public int Disc { get; private set; } = -1;
|
public int Disc { get; }
|
||||||
public int Pos { get; set; } = -1;
|
public int Pos { get; set; }
|
||||||
public int Id { get; private set; } = -1;
|
public int Id { get; }
|
||||||
public IDictionary<string, string> UnknownMetadata => _unknownMetadata;
|
public IReadOnlyDictionary<string, string> UnknownMetadata { get; }
|
||||||
|
|
||||||
internal void AddTag(string tag, string value)
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Time"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasTime => this.Time != NoTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Album"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasAlbum => this.Album != NoAlbum;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Artist"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasArtist => this.Artist != NoArtist;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Title"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasTitle => this.Title != NoTitle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Track"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasTrack => this.Track != NoTrack;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Name"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasName => this.Name != NoName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Genre"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasGenre => this.Genre != NoGenre;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Date"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasDate => this.Date != NoDate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Composer"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasComposer => this.Composer != NoComposer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Performer"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasPerformer => this.Performer != NoPerformer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Comment"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasComment => this.Comment != NoComment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Disc"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasDisc => this.Disc != NoDisc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Pos"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasPos => this.Pos != NoPos;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the MpdFile has the <see cref="Id"/> property set.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasId => this.Id != NoId;
|
||||||
|
|
||||||
|
internal static MpdFile Create(string path, int pos)
|
||||||
{
|
{
|
||||||
switch (tag)
|
return new MpdFile(path, pos: pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static (IMpdFile mpdFile, int index) Create(IList<KeyValuePair<string, string>> response, int startIndex)
|
||||||
{
|
{
|
||||||
|
string file;
|
||||||
|
if (response.Count <= startIndex)
|
||||||
|
{
|
||||||
|
return (null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileKeyValuePair = response[startIndex];
|
||||||
|
if (fileKeyValuePair.Key == "file")
|
||||||
|
{
|
||||||
|
file = fileKeyValuePair.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int time = NoTime;
|
||||||
|
string album = NoAlbum;
|
||||||
|
string artist = NoArtist;
|
||||||
|
string title = NoTitle;
|
||||||
|
string track = NoTrack;
|
||||||
|
string name = NoName;
|
||||||
|
string genre = NoGenre;
|
||||||
|
string date = NoDate;
|
||||||
|
string composer = NoComposer;
|
||||||
|
string performer = NoPerformer;
|
||||||
|
string comment = NoComment;
|
||||||
|
int disc = NoDisc;
|
||||||
|
int pos = NoPos;
|
||||||
|
int id = NoId;
|
||||||
|
var unknownMetadata = new Dictionary<string, string>();
|
||||||
|
for (var index = startIndex + 1; index < response.Count; index++)
|
||||||
|
{
|
||||||
|
var line = response[index];
|
||||||
|
if (line.Key != null)
|
||||||
|
{
|
||||||
|
switch (line.Key)
|
||||||
|
{
|
||||||
|
case TagFile:
|
||||||
|
return (new MpdFile(
|
||||||
|
file,
|
||||||
|
time,
|
||||||
|
album,
|
||||||
|
artist,
|
||||||
|
title,
|
||||||
|
track,
|
||||||
|
name,
|
||||||
|
genre,
|
||||||
|
date,
|
||||||
|
composer,
|
||||||
|
performer,
|
||||||
|
comment,
|
||||||
|
disc,
|
||||||
|
pos,
|
||||||
|
id), index - 1);
|
||||||
case TagTime:
|
case TagTime:
|
||||||
Time = int.Parse(value);
|
if (int.TryParse(line.Value, out int tryTime))
|
||||||
break;
|
{
|
||||||
case TagArtist:
|
time = tryTime;
|
||||||
Artist = value;
|
}
|
||||||
break;
|
break;
|
||||||
case TagAlbum:
|
case TagAlbum:
|
||||||
Album = value;
|
album = line.Value;
|
||||||
|
break;
|
||||||
|
case TagArtist:
|
||||||
|
artist = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagTitle:
|
case TagTitle:
|
||||||
Title = value;
|
title = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagTrack:
|
case TagTrack:
|
||||||
Track = value;
|
track = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagName:
|
case TagName:
|
||||||
Name = value;
|
name = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagGenre:
|
case TagGenre:
|
||||||
Genre = value;
|
genre = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagDate:
|
case TagDate:
|
||||||
Date = value;
|
date = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagComposer:
|
case TagComposer:
|
||||||
Composer = value;
|
composer = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagPerformer:
|
case TagPerformer:
|
||||||
Performer = value;
|
performer = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagComment:
|
case TagComment:
|
||||||
Comment = value;
|
comment = line.Value;
|
||||||
break;
|
break;
|
||||||
case TagDisc:
|
case TagDisc:
|
||||||
Disc = int.Parse(value);
|
if (int.TryParse(line.Value, out var tryDisc))
|
||||||
|
{
|
||||||
|
disc = tryDisc;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TagPos:
|
case TagPos:
|
||||||
Pos = int.Parse(value);
|
if (int.TryParse(line.Value, out var tryPos))
|
||||||
|
{
|
||||||
|
pos = tryPos;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TagId:
|
case TagId:
|
||||||
Id = int.Parse(value);
|
if (int.TryParse(line.Value, out var tryId))
|
||||||
|
{
|
||||||
|
id = tryId;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_unknownMetadata.Add(tag, value);
|
unknownMetadata.Add(line.Key, line.Value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (new MpdFile(
|
||||||
|
file,
|
||||||
|
time,
|
||||||
|
album,
|
||||||
|
artist,
|
||||||
|
title,
|
||||||
|
track,
|
||||||
|
name,
|
||||||
|
genre,
|
||||||
|
date,
|
||||||
|
composer,
|
||||||
|
performer,
|
||||||
|
comment,
|
||||||
|
disc,
|
||||||
|
pos,
|
||||||
|
id), response.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IMpdFile> CreateList(IList<KeyValuePair<string, string>> response)
|
||||||
|
{
|
||||||
|
var mpdFiles = new List<IMpdFile>();
|
||||||
|
for (var index = 0; index < response.Count; index++)
|
||||||
|
{
|
||||||
|
var (mpdFile, lastIndex) = Create(response, index);
|
||||||
|
if (mpdFile != null)
|
||||||
|
{
|
||||||
|
mpdFiles.Add(mpdFile);
|
||||||
|
index = lastIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mpdFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user