diff --git a/LibMpc/Mpc.cs b/LibMpc/Mpc.cs
index c241f69..5791c6c 100644
--- a/LibMpc/Mpc.cs
+++ b/LibMpc/Mpc.cs
@@ -1,1317 +1,1307 @@
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-
-namespace Libmpc
-{
- ///
- /// The delegate for the and events.
- ///
- /// The connection firing the event.
- public delegate void MpcEventDelegate(Mpc connection);
- ///
- /// The Mpc class implements all commands for the MPD. It takes care of command building
- /// and parsing the response into .net objects.
- ///
- public class Mpc
- {
- private const string TAG_ANY = "any";
- private const string TAG_FILENAME = "filename";
-
- private const string TAG_ARTIST = "artist";
- private const string TAG_ALBUM = "album";
- private const string TAG_TITLE = "title";
- private const string TAG_TRACK = "track";
- private const string TAG_NAME = "name";
- private const string TAG_GENRE = "genre";
- private const string TAG_DATE = "date";
- private const string TAG_COMPOSER = "composer";
- private const string TAG_PERFORMER = "performer";
- private const string TAG_COMMENT = "comment";
- private const string TAG_DISC = "disc";
-
- private static readonly Regex STATUS_AUDIO_REGEX = new Regex("^(?[0-9]*):(?[0-9]*):(?[0-9]*)$");
-
- private readonly MpcConnectionEventDelegate onMpcConnectionConnectedDelegate;
- private readonly MpcConnectionEventDelegate onMpcConnectionDisconnectedDelegate;
-
- private MpcConnection connection = null;
-
- ///
- /// Creates a new Mpc.
- ///
- public Mpc()
- {
- this.onMpcConnectionConnectedDelegate = new MpcConnectionEventDelegate(this.onMpcConnectionConnected);
- this.onMpcConnectionDisconnectedDelegate = new MpcConnectionEventDelegate(this.onMpcConnectionDisconnected);
- }
- ///
- /// Is fired when a connection to a MPD server is established.
- ///
- public event MpcEventDelegate OnConnected;
- ///
- /// Is fired when the connection to the MPD server is closed.
- ///
- public event MpcEventDelegate OnDisconnected;
- ///
- /// If the Mpc object has a connection that is connected to an MPD.
- ///
- public bool Connected
- {
- get { return this.connection == null ? false : this.connection.Connected; }
- }
- ///
- /// The MpcConnection used to talk to the server.
- ///
- public MpcConnection Connection
- {
- get { return this.connection; }
- set
- {
- if (this.connection != null)
- {
- this.connection.OnConnected -= this.onMpcConnectionConnectedDelegate;
- this.connection.OnDisconnected -= this.onMpcConnectionDisconnectedDelegate;
-
- if (this.connection.Connected)
- this.onMpcConnectionDisconnected( this.connection );
- }
-
- this.connection = value;
-
- if (this.connection != null)
- {
- this.connection.OnConnected += this.onMpcConnectionConnectedDelegate;
- this.connection.OnDisconnected += this.onMpcConnectionDisconnectedDelegate;
-
- if (this.connection.Connected)
- this.onMpcConnectionConnected(this.connection);
- }
- }
- }
-
- private MpcConnection getConnection()
- {
- MpcConnection ret = this.connection;
- if (ret == null)
- throw new NotConnectedException();
- else
- return ret;
- }
-
-
- private void onMpcConnectionConnected(MpcConnection connection)
- {
- if (this.OnConnected != null)
- this.OnConnected.Invoke(this);
- }
-
- private void onMpcConnectionDisconnected(MpcConnection connection)
- {
- if (this.OnDisconnected != null)
- this.OnDisconnected.Invoke(this);
- }
-
- #region Admin Commands
- ///
- /// Disables an MPD output.
- ///
- /// The id of the output.
- /// If the action was successful.
- public bool DisableOutput(int id)
- {
- return !this.getConnection().Exec("disableoutput", new string[] { id.ToString() }).IsError;
- }
- ///
- /// Enables an MPD output.
- ///
- /// The id of the output.
- /// If the action was successful.
- public bool EnableOutput(int id)
- {
- return !this.getConnection().Exec("enableoutput", new string[] { id.ToString() }).IsError;
- }
- ///
- /// Lists all outputs of the MPD.
- ///
- /// The list of all MPD outputs.
- public MpdOutput[] Outputs()
- {
- MpdResponse response = this.getConnection().Exec("outputs");
- if (response.Message.Count % 3 != 0)
- throw new InvalidMpdResponseException();
-
- MpdOutput[] ret = new MpdOutput[response.Message.Count / 3];
-
- for (int i = 0; i < ret.Length; i++)
- {
- int id;
- string name;
- int enabled;
-
- KeyValuePair idLine = response[i * 3];
- if (idLine.Key == null)
- throw new InvalidMpdResponseException("Invalid form of line " + (i * 3));
- if (!idLine.Key.Equals("outputid"))
- throw new InvalidMpdResponseException("Key of line " + (i * 3) + " is not 'outputid'");
- if( !int.TryParse(idLine.Value, out id) )
- throw new InvalidMpdResponseException("Value of line " + (i * 3) + " is not a number");
-
- KeyValuePair nameLine = response[i * 3 + 1];
- if (nameLine.Key == null)
- throw new InvalidMpdResponseException("Invalid form of line " + (i * 3 + 1));
- if (!nameLine.Key.Equals("outputname"))
- throw new InvalidMpdResponseException("Key of line " + (i * 3 + 1) + " is not 'outputname'");
- name = nameLine.Value;
-
- KeyValuePair enabledLine = response[i * 3 + 2];
- if (enabledLine.Key == null)
- throw new InvalidMpdResponseException("Invalid form of line " + (i * 3 + 2));
- if (!enabledLine.Key.Equals("outputenabled"))
- throw new InvalidMpdResponseException("Key of line " + (i * 3 + 2) + " is not 'outputenabled'");
- if (!int.TryParse(enabledLine.Value, out enabled))
- throw new InvalidMpdResponseException("Value of line " + (i * 3 + 2) + " is not a number");
-
- ret[i] = new MpdOutput(id, name, enabled > 0);
- }
-
- return ret;
- }
- ///
- /// Returns the list of tag types the MPD supports.
- ///
- /// The list of tag types the MPD supports.
- public string[] TagTypes()
- {
- MpdResponse response = this.getConnection().Exec("tagtypes");
-
- string[] ret = new string[response.Message.Count];
-
- for (int i = 0; i < ret.Length; i++)
- {
- KeyValuePair line = response[i];
- if (!line.Key.Equals("tagtype"))
- throw new InvalidMpdResponseException("Key of line " + (i) + " is not 'tagtype'");
- ret[i] = line.Value;
- }
-
- return ret;
- }
- ///
- /// Starts an update of the MPD database.
- ///
- /// An sequential number of the update process.
- public int Update()
- {
- MpdResponse response = this.getConnection().Exec("update");
-
- if( response.Message.Count != 1 )
- throw new InvalidMpdResponseException("Respose message has more than one line.");
-
- int ret;
-
- KeyValuePair line = response[0];
- if (!line.Key.Equals("updating_db"))
- throw new InvalidMpdResponseException("Key of line 0 is not 'updating_db'");
- if (!int.TryParse(line.Value, out ret))
- throw new InvalidMpdResponseException("Value of line 0 is not a number");
-
- return ret;
- }
-
- #endregion
-
- #region Database Commands
- ///
- /// Returns all files in the database who's attribute matches the given token. Works like the Search command but is case sensitive.
- ///
- /// Specifies the attribute to search for.
- /// The value the files attribute must have to be included in the result.
- /// All files in the database who's attribute matches the given token.
- public List Find(ScopeSpecifier scopeSpecifier, string token)
- {
- if (token == null)
- throw new ArgumentNullException("token");
-
- MpdResponse response = this.getConnection().Exec("find", new string[] { this.toTag(scopeSpecifier), token });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns all values found in files of the MPD for the given attribute.
- ///
- /// The attribute who's values are requested.
- /// All values found in files of the MPD for the given attribute.
- public List List(ScopeSpecifier scopeSpecifier)
- {
- MpdResponse response = this.getConnection().Exec("list", new string[] { this.toTag(scopeSpecifier) });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Returns all values for the given attribute found in files of the MPD where another attribute matches a given value.
- ///
- /// The attribute whos values are returns.
- /// The attribute whos value should match a given value for the file to be included in the result.
- /// The value the searchTag attribute must match for the file to be included in the result.
- /// All values found in files of the MPD for the given attribute.
- public List List(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue)
- {
- if (searchValue == null)
- throw new ArgumentNullException("searchValue");
-
- MpdResponse response = this.getConnection().Exec("list", new string[] { this.toTag(resultTag), this.toTag(searchTag), searchValue });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Returns the names of all files and directory found under the given path.
- ///
- /// The path whos subdirectories and their files are requested.
- /// The names of all files and directory found under the given path.
- public List ListAll(string path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
-
- MpdResponse response = this.getConnection().Exec("listall", new string[] { path });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Returns the information of all files found in the given path and its subdirectories.
- ///
- /// The path of which the file information is requested.
- /// The information of all files found in the given path and its subdirectories.
- public List ListAllInfo(string path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
-
- MpdResponse response = this.getConnection().Exec("listallinfo", new string[] { path });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns the directory listing of the root directory.
- ///
- /// The listing of the root directory.
- public MpdDirectoryListing LsInfo()
- {
- return this.LsInfo(null);
- }
- ///
- /// Returns the directory listing of the given path.
- ///
- /// The path whos listing is requested.
- /// The directory listing of the given path.
- public MpdDirectoryListing LsInfo(string path)
- {
- MpdResponse response;
- if (path == null)
- response = this.getConnection().Exec("lsinfo");
- else
- response = this.getConnection().Exec("lsinfo", new string[] { path });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return new MpdDirectoryListing(
- MpdFile.buildList(response),
- response.getAttributeValueList("directory"),
- response.getAttributeValueList("playlist"));
- }
- ///
- /// Returns all files in the database who's attribute matches the given token. Works like the Find command but is case insensitive.
- ///
- /// Specifies the attribute to search for.
- /// The value the files attribute must have to be included in the result.
- /// All files in the database who's attribute matches the given token.
- public List Search(ScopeSpecifier scopeSpecifier, string token)
- {
- if (token == null)
- throw new ArgumentNullException("token");
-
- MpdResponse response = this.getConnection().Exec("search", new string[] { this.toTag(scopeSpecifier), token });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
-
- #endregion
-
- #region Playlist Commands
- ///
- /// Adds a file to the playlist.
- ///
- /// The name and path of the file to add.
- public void Add(string filename)
- {
- if (filename == null)
- throw new ArgumentNullException("filename");
-
- MpdResponse response = this.getConnection().Exec("add", new string[] { filename });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Adds a file to the playlist and returns the id.
- ///
- /// The name and path of the file to add.
- /// The id of the file in the playlist.
- public int AddId(string filename)
- {
- if (filename == null)
- throw new ArgumentNullException("filename");
-
- MpdResponse response = this.getConnection().Exec("add", new string[] { filename });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- if (response.Count != 1)
- throw new InvalidMpdResponseException("Returned more than one line for command addid.");
-
- string id = response["Id"];
- if( id == null )
- throw new InvalidMpdResponseException("Tag Id missing in response to command addid.");
- int tryId = -1;
- if( !int.TryParse(id, out tryId) )
- throw new InvalidMpdResponseException("Tag Id in response to command addid does not contain an number.");
-
- return tryId;
- }
- ///
- /// Clears the playlist.
- ///
- public void Clear()
- {
- MpdResponse response = this.getConnection().Exec("clear");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Returns the information of the current song.
- ///
- /// The information of the current song.
- public MpdFile CurrentSong()
- {
- MpdResponse response = this.getConnection().Exec("currentsong");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.build(response);
- }
- ///
- /// Deletes the track with the given index from the current playlist.
- ///
- /// The index of the track to remove from the playlist.
- public void Delete(int nr)
- {
- MpdResponse response = this.getConnection().Exec("delete", new string[] { nr.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Deletes the track with the given id from the current playlist.
- ///
- /// The id of the track to remove from the playlist.
- public void DeleteId(int id)
- {
- MpdResponse response = this.getConnection().Exec("deleteid", new string[] { id.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Loads the playlist with the given name.
- ///
- /// The name of the playlist to load.
- public void Load( string name )
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("load", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Renames a playlist.
- ///
- /// The old name of the playlist.
- /// The new name of the playlist.
- public void Rename(string oldName, string newName)
- {
- if (oldName == null)
- throw new ArgumentNullException("oldName");
- if (newName == null)
- throw new ArgumentNullException("newName");
-
- MpdResponse response = this.getConnection().Exec("rename", new string[] { oldName, newName });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Moves a track within the playlist.
- ///
- /// The old index of the track in the playlist.
- /// The new index of the track in the playlist.
- public void Move(int oldNr, int newNr)
- {
- MpdResponse response = this.getConnection().Exec("move", new string[] { oldNr.ToString(), newNr.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Moves a track within the playlist.
- ///
- /// The id of the track to move.
- /// The new index of the track in the playlist.
- public void MoveId(int id, int nr)
- {
- MpdResponse response = this.getConnection().Exec("moveid", new string[] { id.ToString(), nr.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Returns the meta data of the items in the current playlist.
- ///
- /// The meta data of the items in the current playlist.
- public List PlaylistInfo()
- {
- MpdResponse response = this.getConnection().Exec("playlistinfo");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns the meta data of a track in the current playlist.
- ///
- /// The index of the track in the playlist.
- /// The meta data of the track in the current playlist.
- public MpdFile PlaylistInfo( int nr )
- {
- MpdResponse response = this.getConnection().Exec("playlistinfo", new string[] { nr.ToString() } );
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.build(response);
- }
- ///
- /// Returns the meta data of the items in the current playlist.
- ///
- /// The meta data of the items in the current playlist.
- public List PlaylistId()
- {
- MpdResponse response = this.getConnection().Exec("playlistid");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns the meta data of a track in the current playlist.
- ///
- /// The id of the track in the playlist.
- /// The meta data of the track in the current playlist.
- public MpdFile PlaylistId(int id)
- {
- MpdResponse response = this.getConnection().Exec("playlistid", new string[] { id.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.build(response);
- }
- ///
- /// Returns all changed tracks in the playlist since the given version.
- ///
- /// The version number.
- /// All changed songs in the playlist since the given version.
- public List Plchanges( int version )
- {
- MpdResponse response = this.getConnection().Exec("plchanges", new string[] {version.ToString()});
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns the ids and positions of the changed tracks in the playlist since the given version.
- ///
- ///
- ///
- /// The ids and positions of the changed tracks in the playlist since the given version as KeyValuePairs.
- /// The key is the index and the id is the value.
- ///
- public List> PlChangesPosId( int version )
- {
- MpdResponse response = this.getConnection().Exec("plchangesposid", new string[] { version.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- if (response.Count % 2 != 0)
- throw new InvalidMpdResponseException("Response to command plchangesposid contains an odd number of lines!");
-
- List> ret = new List>();
-
- for (int i = 0; i < response.Count; i += 2)
- {
- KeyValuePair posLine = response[i];
- KeyValuePair idLine = response[i+1];
-
- if ((posLine.Key == null) || (posLine.Value == null))
- throw new InvalidMpdResponseException("Invalid format of line " + i + "!");
- if ((idLine.Key == null) || (idLine.Value == null))
- throw new InvalidMpdResponseException("Invalid format of line " + (i + 1) + "!");
-
- if (!posLine.Key.Equals("cpos"))
- throw new InvalidMpdResponseException("Line " + i + " does not start with \"cpos\"!");
- if (!idLine.Key.Equals("Id"))
- throw new InvalidMpdResponseException("Line " + (i + 1) + " does not start with \"Id\"!");
-
- int tryPos = -1;
- if (!int.TryParse(posLine.Value, out tryPos))
- throw new InvalidMpdResponseException("Tag value on line " + i + " is not a number.");
- int tryId = -1;
- if (!int.TryParse(idLine.Value, out tryId))
- throw new InvalidMpdResponseException("Tag value on line " + (i + 1) + " is not a number.");
-
- ret.Add(new KeyValuePair(tryPos, tryId));
- }
-
-
- return ret;
- }
- ///
- /// Removes the playlist with the given name.
- ///
- /// The name of the playlist to remove.
- public void Rm(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("rm", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Saves the current playlist with the given name.
- ///
- /// The name to the save the currenty playlist.
- public void Save(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("save", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Shuffles the current playlist.
- ///
- public void Shuffle()
- {
- MpdResponse response = this.getConnection().Exec("shuffle");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Swaps the to tracks in the current playlist.
- ///
- /// The index of the first track.
- /// The index of the second track.
- public void Swap(int nr1, int nr2)
- {
- MpdResponse response = this.getConnection().Exec("swap", new string[] { nr1.ToString(), nr2.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Swaps the to tracks in the current playlist.
- ///
- /// The id of the first track.
- /// The id of the second track.
- public void SwapId(int id1, int id2)
- {
- MpdResponse response = this.getConnection().Exec("swapid", new string[] { id1.ToString(), id2.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Returns the filenames of the tracks in the given playlist.
- ///
- /// The playlist whos filename are requested.
- /// The filenames of the tracks in the given playlist.
- public List ListPlaylist(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("listplaylist", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Return the meta data of the tracks in the given playlist.
- ///
- /// The playlist whos files meta data are requested.
- /// The meta data of the tracks in the given playlist.
- public List ListPlaylistInfo(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("listplaylistinfo", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Add a file to a playlist.
- ///
- /// The name of the playlist.
- /// The path and name of the file to add.
- public void PlaylistAdd(string name, string file)
- {
- if (name == null)
- throw new ArgumentNullException("name");
- if (file == null)
- throw new ArgumentNullException("file");
-
- MpdResponse response = this.getConnection().Exec("playlistadd", new string[] { name, file });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Clears all tracks from a playlist.
- ///
- /// The name of the playlist to clear.
- public void PlaylistClear(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("playlistclear", new string[] { name });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Delete a file from a playlist.
- ///
- /// The name of the playlist
- /// The id of the track to delete.
- public void PlaylistDelete(string name, int id)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("playlistdelete", new string[] { name, id.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Moves a track in a playlist.
- ///
- /// The name of the playlist.
- /// The id of the track to move.
- /// The position to move the track to.
- public void PlaylistMove(string name, int id, int nr)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- MpdResponse response = this.getConnection().Exec("playlistmove", new string[] { id.ToString(), nr.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Returns the meta data for all tracks in the current playlist whos attribute equals the given value.
- ///
- /// The attribute to search for the given value.
- /// The value to search for in the given attribute.
- /// The meta data for all tracks in the current playlist whos attribute equals the given value.
- public List PlaylistFind(ScopeSpecifier scopeSpecifier, string token)
- {
- if (token == null)
- throw new ArgumentNullException("token");
-
- MpdResponse response = this.getConnection().Exec("playlistfind", new string[] { this.toTag(scopeSpecifier), token });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- ///
- /// Returns the meta data for all tracks in the current playlist whos attribute contains the given value.
- ///
- /// The attribute to search for the given value.
- /// The value to search for in the given attribute.
- /// The meta data for all tracks in the current playlist whos attribute contains the given value.
- public List PlaylistSearch(ScopeSpecifier scopeSpecifier, string token)
- {
- if (token == null)
- throw new ArgumentNullException("token");
-
- MpdResponse response = this.getConnection().Exec("playlistsearch", new string[] { this.toTag(scopeSpecifier), token });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return MpdFile.buildList(response);
- }
- #endregion
-
- #region Playback Commands
- ///
- /// Sets the seconds to crossfade between songs.
- ///
- /// The seconds to crossfade between songs.
- public void Crossfade(int seconds)
- {
- MpdResponse response = this.getConnection().Exec("crossfade", new string[] { seconds.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the next song in the playlist-
- ///
- public void Next()
- {
- MpdResponse response = this.getConnection().Exec("next");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Sets the MPD to pause or resume the playback.
- ///
- /// If the playback should be paused or resumed.
- public void Pause(bool pause)
- {
- MpdResponse response = this.getConnection().Exec("pause", new string[] { pause ? "1" : "0" });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the current item in the playlist.
- ///
- public void Play()
- {
- MpdResponse response = this.getConnection().Exec("play");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the item with the given index in the playlist.
- ///
- /// The index of the track in the playlist to start playing.
- public void Play(int nr)
- {
- MpdResponse response = this.getConnection().Exec("play", new string[] { nr.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the track in the playlist with the id 0.
- ///
- public void PlayId()
- {
- MpdResponse response = this.getConnection().Exec("playid");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the track in the playlist with the given id.
- ///
- /// The id of the track to start playing.
- public void PlayId(int id)
- {
- MpdResponse response = this.getConnection().Exec("playid", new string[] { id.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts the playback of the previous track in the playlist.
- ///
- public void Previous()
- {
- MpdResponse response = this.getConnection().Exec("previous");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Sets the MPD to random or sequential playback.
- ///
- /// If the MPD playlist should be played randomly.
- public void Random(bool random)
- {
- MpdResponse response = this.getConnection().Exec("random", new string[] { random ? "1" : "0" });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Sets if the MPD should repeat the playlist.
- ///
- /// If the MPD should repeat the playlist.
- public void Repeat(bool repeat)
- {
- MpdResponse response = this.getConnection().Exec("repeat", new string[] { repeat ? "1" : "0" });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts playback of a given song at the give position.
- ///
- /// The index of the song in the playlist.
- /// The number of seconds to start playback on.
- public void Seek(int nr, int time)
- {
- MpdResponse response = this.getConnection().Exec("seek", new string[] { nr.ToString(), time.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Starts playback of a given song at the give position.
- ///
- /// The id of the song in the playlist.
- /// The number of seconds to start playback on.
- public void SeekId(int id, int time)
- {
- MpdResponse response = this.getConnection().Exec("seekid", new string[] { id.ToString(), time.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Sets the output volume of the MPD.
- ///
- /// The output volume of the MPD between 0 and 100.
- public void SetVol(int vol)
- {
- if (vol < 0)
- throw new ArgumentException("vol < 0");
- if (vol > 100)
- throw new ArgumentException("vol > 100");
-
- MpdResponse response = this.getConnection().Exec("setvol", new string[] { vol.ToString() });
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
- ///
- /// Stops the playback of the MPD.
- ///
- public void Stop()
- {
- MpdResponse response = this.getConnection().Exec("stop");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
- }
-
- #endregion
-
- #region Misc Commands
- ///
- /// Clears the error message set in the MPD.
- ///
- public void ClearError()
- {
- this.getConnection().Exec("clearerror");
- }
- ///
- /// Returns which commands the current user has access to.
- ///
- /// The commands the current user has access to.
- public List Commands()
- {
- MpdResponse response = this.getConnection().Exec("commands");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Returns which commands the current user does has access to.
- ///
- /// The commands the current user does has access to.
- public List NotCommands()
- {
- MpdResponse response = this.getConnection().Exec("notcommands");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- return response.getValueList();
- }
- ///
- /// Send the password to the server allow access to the server if enabled in the MPD.
- ///
- /// The password to authorize to the server.
- /// If the password is valid.
- public bool Password(string password)
- {
- if (password == null)
- throw new ArgumentNullException("password");
-
- return this.getConnection().Exec("password", new string[] { password }).IsError;
- }
- ///
- /// Sends a ping command to the server and waits for the response.
- ///
- public void Ping()
- {
- this.getConnection().Exec("ping");
- }
- ///
- /// Requests the current statistics from the MPD,
- ///
- /// The current statistics fromt the MPD.
- public MpdStatistics Stats()
- {
- MpdResponse response = this.getConnection().Exec("stats");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- int artists = -1;
- int albums = -1;
- int songs = -1;
- int uptime = -1;
- int playtime = -1;
- int db_playtime = -1;
- int db_update = -1;
-
- foreach (KeyValuePair line in response)
- {
- if( ( line.Key != null ) && ( line.Value!=null ) )
- switch (line.Key)
- {
- case "artists":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- artists = tryValue;
- }
- break;
- case "albums":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- albums = tryValue;
- }
- break;
- case "songs":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- songs = tryValue;
- }
- break;
- case "uptime":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- uptime = tryValue;
- }
- break;
- case "playtime":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- playtime = tryValue;
- }
- break;
- case "db_playtime":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- db_playtime = tryValue;
- }
- break;
- case "db_update":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- db_update = tryValue;
- }
- break;
- }
- }
-
- return new MpdStatistics(artists, albums, songs, uptime, playtime, db_playtime, db_update);
- }
- ///
- /// Returns the current status of the MPD.
- ///
- /// The current status of the MPD.
- public MpdStatus Status()
- {
- MpdResponse response = this.getConnection().Exec("status");
-
- if (response.IsError)
- throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
-
- int volume = -1;
- bool repeat = false;
- bool random = false;
- int playlist = -1;
- int playlistLength = -1;
- int playlistQueue = -1;
- int xFade = -1;
- MpdState state = MpdState.Unknown;
- int song = -1;
- int songId = -1;
- int timeElapsed = -1;
- int timeTotal = -1;
- int bitrate = -1;
- int audioSampleRate = -1;
- int audioBits = -1;
- int audioChannels = -1;
- int updatingDb = -1;
- string error = null;
-
- foreach (KeyValuePair line in response)
- {
- if ( (line.Key != null) && (line.Value!=null) )
- switch (line.Key)
- {
- case "volume":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- {
- volume = tryValue;
- if (volume < 0)
- volume = 0;
- if (volume > 100)
- volume = 100;
- }
- }
- break;
- case "repeat":
- repeat = (line.Value != null) && (line.Value.Equals("1"));
- break;
- case "random":
- random = (line.Value != null) && (line.Value.Equals("1"));
- break;
- case "playlist":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- playlist = tryValue;
- }
- break;
- case "playlistlength":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- playlistLength = tryValue;
- }
- break;
- case "playlistqueue":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- playlistQueue = tryValue;
- }
- break;
- case "xfade":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- xFade = tryValue;
- }
- break;
- case "state":
- switch (line.Value)
- {
- case "play":
- state = MpdState.Play;
- break;
- case "pause":
- state = MpdState.Pause;
- break;
- case "stop":
- state = MpdState.Stop;
- break;
- }
- break;
- case "song":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- song = tryValue;
- }
- break;
- case "songid":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- songId = tryValue;
- }
- break;
- case "time":
- int index = line.Value.IndexOf(':');
- if (index >= 0)
- {
- int tryValue;
- if (int.TryParse(line.Value.Substring(0, index), out tryValue))
- timeElapsed = tryValue;
- if (int.TryParse(line.Value.Substring(index+1), out tryValue))
- timeTotal = tryValue;
- }
- break;
- case "bitrate":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- bitrate = tryValue;
- }
- break;
- case "audio":
- Match match = STATUS_AUDIO_REGEX.Match(line.Value);
- if (match.Success)
- {
- int tryValue;
- if (int.TryParse(match.Result("$sampleRate"), out tryValue))
- audioSampleRate = tryValue;
- if (int.TryParse(match.Result("$bits"), out tryValue))
- audioBits = tryValue;
- if (int.TryParse(match.Result("$channels"), out tryValue))
- audioChannels = tryValue;
- }
- break;
- case "updating_db":
- {
- int tryValue;
- if (int.TryParse(line.Value, out tryValue))
- updatingDb = tryValue;
- }
- break;
- case "error":
- error = line.Value;
- break;
- }
- }
-
- return new MpdStatus(
- volume,
- repeat,
- random,
- playlist,
- playlistLength,
- xFade,
- state,
- song,
- songId,
- timeElapsed,
- timeTotal,
- bitrate,
- audioSampleRate,
- audioBits,
- audioChannels,
- updatingDb,
- error
- );
- }
-
- #endregion
-
- private string toTag(ScopeSpecifier scopeSpecifier)
- {
- switch (scopeSpecifier)
- {
- default:
- throw new ArgumentException("scopeSpecifier");
- case ScopeSpecifier.Any:
- return TAG_ANY;
- case ScopeSpecifier.Filename:
- return TAG_FILENAME;
- case ScopeSpecifier.Artist:
- return TAG_ARTIST;
- case ScopeSpecifier.Album:
- return TAG_ALBUM;
- case ScopeSpecifier.Title:
- return TAG_TITLE;
- case ScopeSpecifier.Track:
- return TAG_TRACK;
- case ScopeSpecifier.Name:
- return TAG_NAME;
- case ScopeSpecifier.Genre:
- return TAG_GENRE;
- case ScopeSpecifier.Date:
- return TAG_DATE;
- case ScopeSpecifier.Composer:
- return TAG_COMPOSER;
- case ScopeSpecifier.Performer:
- return TAG_PERFORMER;
- case ScopeSpecifier.Comment:
- return TAG_COMMENT;
- case ScopeSpecifier.Disc:
- return TAG_DISC;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Text.RegularExpressions;
+
+namespace Libmpc
+{
+ public interface IMpc
+ {
+ bool IsConnected { get; }
+ bool Connect();
+
+ event EventHandler Connected;
+ event EventHandler Disconnected;
+
+ MpdOutput[] Outputs();
+ MpdStatistics Stats();
+ }
+
+ ///
+ /// The Mpc class implements all commands for the MPD. It takes care of command building
+ /// and parsing the response into .net objects.
+ ///
+ public class Mpc : IMpc
+ {
+ private const string TAG_ANY = "any";
+ private const string TAG_FILENAME = "filename";
+
+ private const string TAG_ARTIST = "artist";
+ private const string TAG_ALBUM = "album";
+ private const string TAG_TITLE = "title";
+ private const string TAG_TRACK = "track";
+ private const string TAG_NAME = "name";
+ private const string TAG_GENRE = "genre";
+ private const string TAG_DATE = "date";
+ private const string TAG_COMPOSER = "composer";
+ private const string TAG_PERFORMER = "performer";
+ private const string TAG_COMMENT = "comment";
+ private const string TAG_DISC = "disc";
+
+ private static readonly Regex STATUS_AUDIO_REGEX = new Regex("^(?[0-9]*):(?[0-9]*):(?[0-9]*)$");
+
+ private MpcConnection _connection;
+ private IPEndPoint _server;
+
+ public Mpc(IPEndPoint server)
+ {
+ _server = server;
+ }
+
+ ///
+ /// Is fired when a connection to a MPD server is established.
+ ///
+ public event EventHandler Connected
+ {
+ add { ConnectedRelayEvent += value; }
+ remove { ConnectedRelayEvent -= value; }
+ }
+
+ private event EventHandler ConnectedRelayEvent;
+
+ ///
+ /// Is fired when the connection to the MPD server is closed.
+ ///
+ public event EventHandler Disconnected
+ {
+ add { DisconnectedRelayEvent += value; }
+ remove { DisconnectedRelayEvent -= value; }
+ }
+
+ private event EventHandler DisconnectedRelayEvent;
+
+ ///
+ /// Connection status to MPD Server.
+ ///
+ public bool IsConnected => _connection?.IsConnected ?? false;
+
+ public bool Connect()
+ {
+ if (_connection == null)
+ {
+ _connection = new MpcConnection(_server);
+ _connection.Connected += OnConnected;
+ _connection.Disconnected += OnDisconnected;
+ }
+
+ if (!_connection.IsConnected)
+ {
+ _connection.Connect();
+ }
+
+ return _connection.IsConnected;
+ }
+
+ private void OnConnected(object sender, EventArgs e)
+ {
+ ConnectedRelayEvent?.Invoke(this, e);
+ }
+
+ private void OnDisconnected(object sender, EventArgs e)
+ {
+ DisconnectedRelayEvent?.Invoke(this, e);
+ }
+
+ #region Admin Commands
+ ///
+ /// Disables an MPD output.
+ ///
+ /// The id of the output.
+ /// If the action was successful.
+ public bool DisableOutput(int id)
+ {
+ return !_connection.Exec("disableoutput", new string[] { id.ToString() }).IsError;
+ }
+ ///
+ /// Enables an MPD output.
+ ///
+ /// The id of the output.
+ /// If the action was successful.
+ public bool EnableOutput(int id)
+ {
+ return !_connection.Exec("enableoutput", new string[] { id.ToString() }).IsError;
+ }
+ ///
+ /// Lists all outputs of the MPD.
+ ///
+ /// The list of all MPD outputs.
+ public MpdOutput[] Outputs()
+ {
+ MpdResponse response = _connection.Exec("outputs");
+ if (response.Message.Count % 3 != 0)
+ throw new InvalidMpdResponseException();
+
+ MpdOutput[] ret = new MpdOutput[response.Message.Count / 3];
+
+ for (int i = 0; i < ret.Length; i++)
+ {
+ int id;
+ string name;
+ int enabled;
+
+ KeyValuePair idLine = response[i * 3];
+ if (idLine.Key == null)
+ throw new InvalidMpdResponseException("Invalid form of line " + (i * 3));
+ if (!idLine.Key.Equals("outputid"))
+ throw new InvalidMpdResponseException("Key of line " + (i * 3) + " is not 'outputid'");
+ if (!int.TryParse(idLine.Value, out id))
+ throw new InvalidMpdResponseException("Value of line " + (i * 3) + " is not a number");
+
+ KeyValuePair nameLine = response[i * 3 + 1];
+ if (nameLine.Key == null)
+ throw new InvalidMpdResponseException("Invalid form of line " + (i * 3 + 1));
+ if (!nameLine.Key.Equals("outputname"))
+ throw new InvalidMpdResponseException("Key of line " + (i * 3 + 1) + " is not 'outputname'");
+ name = nameLine.Value;
+
+ KeyValuePair enabledLine = response[i * 3 + 2];
+ if (enabledLine.Key == null)
+ throw new InvalidMpdResponseException("Invalid form of line " + (i * 3 + 2));
+ if (!enabledLine.Key.Equals("outputenabled"))
+ throw new InvalidMpdResponseException("Key of line " + (i * 3 + 2) + " is not 'outputenabled'");
+ if (!int.TryParse(enabledLine.Value, out enabled))
+ throw new InvalidMpdResponseException("Value of line " + (i * 3 + 2) + " is not a number");
+
+ ret[i] = new MpdOutput(id, name, enabled > 0);
+ }
+
+ return ret;
+ }
+ ///
+ /// Returns the list of tag types the MPD supports.
+ ///
+ /// The list of tag types the MPD supports.
+ public string[] TagTypes()
+ {
+ MpdResponse response = _connection.Exec("tagtypes");
+
+ string[] ret = new string[response.Message.Count];
+
+ for (int i = 0; i < ret.Length; i++)
+ {
+ KeyValuePair line = response[i];
+ if (!line.Key.Equals("tagtype"))
+ throw new InvalidMpdResponseException("Key of line " + (i) + " is not 'tagtype'");
+ ret[i] = line.Value;
+ }
+
+ return ret;
+ }
+ ///
+ /// Starts an update of the MPD database.
+ ///
+ /// An sequential number of the update process.
+ public int Update()
+ {
+ MpdResponse response = _connection.Exec("update");
+
+ if (response.Message.Count != 1)
+ throw new InvalidMpdResponseException("Respose message has more than one line.");
+
+ int ret;
+
+ KeyValuePair line = response[0];
+ if (!line.Key.Equals("updating_db"))
+ throw new InvalidMpdResponseException("Key of line 0 is not 'updating_db'");
+ if (!int.TryParse(line.Value, out ret))
+ throw new InvalidMpdResponseException("Value of line 0 is not a number");
+
+ return ret;
+ }
+
+ #endregion
+
+ #region Database Commands
+ ///
+ /// Returns all files in the database who's attribute matches the given token. Works like the Search command but is case sensitive.
+ ///
+ /// Specifies the attribute to search for.
+ /// The value the files attribute must have to be included in the result.
+ /// All files in the database who's attribute matches the given token.
+ public List Find(ScopeSpecifier scopeSpecifier, string token)
+ {
+ if (token == null)
+ throw new ArgumentNullException("token");
+
+ MpdResponse response = _connection.Exec("find", new string[] { toTag(scopeSpecifier), token });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns all values found in files of the MPD for the given attribute.
+ ///
+ /// The attribute who's values are requested.
+ /// All values found in files of the MPD for the given attribute.
+ public List List(ScopeSpecifier scopeSpecifier)
+ {
+ MpdResponse response = _connection.Exec("list", new string[] { toTag(scopeSpecifier) });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Returns all values for the given attribute found in files of the MPD where another attribute matches a given value.
+ ///
+ /// The attribute whos values are returns.
+ /// The attribute whos value should match a given value for the file to be included in the result.
+ /// The value the searchTag attribute must match for the file to be included in the result.
+ /// All values found in files of the MPD for the given attribute.
+ public List List(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue)
+ {
+ if (searchValue == null)
+ throw new ArgumentNullException("searchValue");
+
+ MpdResponse response = _connection.Exec("list", new string[] { toTag(resultTag), toTag(searchTag), searchValue });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Returns the names of all files and directory found under the given path.
+ ///
+ /// The path whos subdirectories and their files are requested.
+ /// The names of all files and directory found under the given path.
+ public List ListAll(string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException("path");
+
+ MpdResponse response = _connection.Exec("listall", new string[] { path });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Returns the information of all files found in the given path and its subdirectories.
+ ///
+ /// The path of which the file information is requested.
+ /// The information of all files found in the given path and its subdirectories.
+ public List ListAllInfo(string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException("path");
+
+ MpdResponse response = _connection.Exec("listallinfo", new string[] { path });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns the directory listing of the root directory.
+ ///
+ /// The listing of the root directory.
+ public MpdDirectoryListing LsInfo()
+ {
+ return LsInfo(null);
+ }
+ ///
+ /// Returns the directory listing of the given path.
+ ///
+ /// The path whos listing is requested.
+ /// The directory listing of the given path.
+ public MpdDirectoryListing LsInfo(string path)
+ {
+ MpdResponse response;
+ if (path == null)
+ response = _connection.Exec("lsinfo");
+ else
+ response = _connection.Exec("lsinfo", new string[] { path });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return new MpdDirectoryListing(
+ MpdFile.buildList(response),
+ response.getAttributeValueList("directory"),
+ response.getAttributeValueList("playlist"));
+ }
+ ///
+ /// Returns all files in the database who's attribute matches the given token. Works like the Find command but is case insensitive.
+ ///
+ /// Specifies the attribute to search for.
+ /// The value the files attribute must have to be included in the result.
+ /// All files in the database who's attribute matches the given token.
+ public List Search(ScopeSpecifier scopeSpecifier, string token)
+ {
+ if (token == null)
+ throw new ArgumentNullException("token");
+
+ MpdResponse response = _connection.Exec("search", new string[] { toTag(scopeSpecifier), token });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+
+ #endregion
+
+ #region Playlist Commands
+ ///
+ /// Adds a file to the playlist.
+ ///
+ /// The name and path of the file to add.
+ public void Add(string filename)
+ {
+ if (filename == null)
+ throw new ArgumentNullException("filename");
+
+ MpdResponse response = _connection.Exec("add", new string[] { filename });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Adds a file to the playlist and returns the id.
+ ///
+ /// The name and path of the file to add.
+ /// The id of the file in the playlist.
+ public int AddId(string filename)
+ {
+ if (filename == null)
+ throw new ArgumentNullException("filename");
+
+ MpdResponse response = _connection.Exec("add", new string[] { filename });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ if (response.Count != 1)
+ throw new InvalidMpdResponseException("Returned more than one line for command addid.");
+
+ string id = response["Id"];
+ if (id == null)
+ throw new InvalidMpdResponseException("Tag Id missing in response to command addid.");
+ int tryId = -1;
+ if (!int.TryParse(id, out tryId))
+ throw new InvalidMpdResponseException("Tag Id in response to command addid does not contain an number.");
+
+ return tryId;
+ }
+ ///
+ /// Clears the playlist.
+ ///
+ public void Clear()
+ {
+ MpdResponse response = _connection.Exec("clear");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Returns the information of the current song.
+ ///
+ /// The information of the current song.
+ public MpdFile CurrentSong()
+ {
+ MpdResponse response = _connection.Exec("currentsong");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.build(response);
+ }
+ ///
+ /// Deletes the track with the given index from the current playlist.
+ ///
+ /// The index of the track to remove from the playlist.
+ public void Delete(int nr)
+ {
+ MpdResponse response = _connection.Exec("delete", new string[] { nr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Deletes the track with the given id from the current playlist.
+ ///
+ /// The id of the track to remove from the playlist.
+ public void DeleteId(int id)
+ {
+ MpdResponse response = _connection.Exec("deleteid", new string[] { id.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Loads the playlist with the given name.
+ ///
+ /// The name of the playlist to load.
+ public void Load(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("load", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Renames a playlist.
+ ///
+ /// The old name of the playlist.
+ /// The new name of the playlist.
+ public void Rename(string oldName, string newName)
+ {
+ if (oldName == null)
+ throw new ArgumentNullException("oldName");
+ if (newName == null)
+ throw new ArgumentNullException("newName");
+
+ MpdResponse response = _connection.Exec("rename", new string[] { oldName, newName });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Moves a track within the playlist.
+ ///
+ /// The old index of the track in the playlist.
+ /// The new index of the track in the playlist.
+ public void Move(int oldNr, int newNr)
+ {
+ MpdResponse response = _connection.Exec("move", new string[] { oldNr.ToString(), newNr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Moves a track within the playlist.
+ ///
+ /// The id of the track to move.
+ /// The new index of the track in the playlist.
+ public void MoveId(int id, int nr)
+ {
+ MpdResponse response = _connection.Exec("moveid", new string[] { id.ToString(), nr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Returns the meta data of the items in the current playlist.
+ ///
+ /// The meta data of the items in the current playlist.
+ public List PlaylistInfo()
+ {
+ MpdResponse response = _connection.Exec("playlistinfo");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns the meta data of a track in the current playlist.
+ ///
+ /// The index of the track in the playlist.
+ /// The meta data of the track in the current playlist.
+ public MpdFile PlaylistInfo(int nr)
+ {
+ MpdResponse response = _connection.Exec("playlistinfo", new string[] { nr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.build(response);
+ }
+ ///
+ /// Returns the meta data of the items in the current playlist.
+ ///
+ /// The meta data of the items in the current playlist.
+ public List PlaylistId()
+ {
+ MpdResponse response = _connection.Exec("playlistid");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns the meta data of a track in the current playlist.
+ ///
+ /// The id of the track in the playlist.
+ /// The meta data of the track in the current playlist.
+ public MpdFile PlaylistId(int id)
+ {
+ MpdResponse response = _connection.Exec("playlistid", new string[] { id.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.build(response);
+ }
+ ///
+ /// Returns all changed tracks in the playlist since the given version.
+ ///
+ /// The version number.
+ /// All changed songs in the playlist since the given version.
+ public List Plchanges(int version)
+ {
+ MpdResponse response = _connection.Exec("plchanges", new string[] { version.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns the ids and positions of the changed tracks in the playlist since the given version.
+ ///
+ ///
+ ///
+ /// The ids and positions of the changed tracks in the playlist since the given version as KeyValuePairs.
+ /// The key is the index and the id is the value.
+ ///
+ public List> PlChangesPosId(int version)
+ {
+ MpdResponse response = _connection.Exec("plchangesposid", new string[] { version.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ if (response.Count % 2 != 0)
+ throw new InvalidMpdResponseException("Response to command plchangesposid contains an odd number of lines!");
+
+ List> ret = new List>();
+
+ for (int i = 0; i < response.Count; i += 2)
+ {
+ KeyValuePair posLine = response[i];
+ KeyValuePair idLine = response[i + 1];
+
+ if ((posLine.Key == null) || (posLine.Value == null))
+ throw new InvalidMpdResponseException("Invalid format of line " + i + "!");
+ if ((idLine.Key == null) || (idLine.Value == null))
+ throw new InvalidMpdResponseException("Invalid format of line " + (i + 1) + "!");
+
+ if (!posLine.Key.Equals("cpos"))
+ throw new InvalidMpdResponseException("Line " + i + " does not start with \"cpos\"!");
+ if (!idLine.Key.Equals("Id"))
+ throw new InvalidMpdResponseException("Line " + (i + 1) + " does not start with \"Id\"!");
+
+ int tryPos = -1;
+ if (!int.TryParse(posLine.Value, out tryPos))
+ throw new InvalidMpdResponseException("Tag value on line " + i + " is not a number.");
+ int tryId = -1;
+ if (!int.TryParse(idLine.Value, out tryId))
+ throw new InvalidMpdResponseException("Tag value on line " + (i + 1) + " is not a number.");
+
+ ret.Add(new KeyValuePair(tryPos, tryId));
+ }
+
+
+ return ret;
+ }
+ ///
+ /// Removes the playlist with the given name.
+ ///
+ /// The name of the playlist to remove.
+ public void Rm(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("rm", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Saves the current playlist with the given name.
+ ///
+ /// The name to the save the currenty playlist.
+ public void Save(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("save", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Shuffles the current playlist.
+ ///
+ public void Shuffle()
+ {
+ MpdResponse response = _connection.Exec("shuffle");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Swaps the to tracks in the current playlist.
+ ///
+ /// The index of the first track.
+ /// The index of the second track.
+ public void Swap(int nr1, int nr2)
+ {
+ MpdResponse response = _connection.Exec("swap", new string[] { nr1.ToString(), nr2.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Swaps the to tracks in the current playlist.
+ ///
+ /// The id of the first track.
+ /// The id of the second track.
+ public void SwapId(int id1, int id2)
+ {
+ MpdResponse response = _connection.Exec("swapid", new string[] { id1.ToString(), id2.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Returns the filenames of the tracks in the given playlist.
+ ///
+ /// The playlist whos filename are requested.
+ /// The filenames of the tracks in the given playlist.
+ public List ListPlaylist(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("listplaylist", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Return the meta data of the tracks in the given playlist.
+ ///
+ /// The playlist whos files meta data are requested.
+ /// The meta data of the tracks in the given playlist.
+ public List ListPlaylistInfo(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("listplaylistinfo", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Add a file to a playlist.
+ ///
+ /// The name of the playlist.
+ /// The path and name of the file to add.
+ public void PlaylistAdd(string name, string file)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (file == null)
+ throw new ArgumentNullException("file");
+
+ MpdResponse response = _connection.Exec("playlistadd", new string[] { name, file });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Clears all tracks from a playlist.
+ ///
+ /// The name of the playlist to clear.
+ public void PlaylistClear(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("playlistclear", new string[] { name });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Delete a file from a playlist.
+ ///
+ /// The name of the playlist
+ /// The id of the track to delete.
+ public void PlaylistDelete(string name, int id)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("playlistdelete", new string[] { name, id.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Moves a track in a playlist.
+ ///
+ /// The name of the playlist.
+ /// The id of the track to move.
+ /// The position to move the track to.
+ public void PlaylistMove(string name, int id, int nr)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ MpdResponse response = _connection.Exec("playlistmove", new string[] { id.ToString(), nr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Returns the meta data for all tracks in the current playlist whos attribute equals the given value.
+ ///
+ /// The attribute to search for the given value.
+ /// The value to search for in the given attribute.
+ /// The meta data for all tracks in the current playlist whos attribute equals the given value.
+ public List PlaylistFind(ScopeSpecifier scopeSpecifier, string token)
+ {
+ if (token == null)
+ throw new ArgumentNullException("token");
+
+ MpdResponse response = _connection.Exec("playlistfind", new string[] { toTag(scopeSpecifier), token });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ ///
+ /// Returns the meta data for all tracks in the current playlist whos attribute contains the given value.
+ ///
+ /// The attribute to search for the given value.
+ /// The value to search for in the given attribute.
+ /// The meta data for all tracks in the current playlist whos attribute contains the given value.
+ public List PlaylistSearch(ScopeSpecifier scopeSpecifier, string token)
+ {
+ if (token == null)
+ throw new ArgumentNullException("token");
+
+ MpdResponse response = _connection.Exec("playlistsearch", new string[] { toTag(scopeSpecifier), token });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return MpdFile.buildList(response);
+ }
+ #endregion
+
+ #region Playback Commands
+ ///
+ /// Sets the seconds to crossfade between songs.
+ ///
+ /// The seconds to crossfade between songs.
+ public void Crossfade(int seconds)
+ {
+ MpdResponse response = _connection.Exec("crossfade", new string[] { seconds.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the next song in the playlist-
+ ///
+ public void Next()
+ {
+ MpdResponse response = _connection.Exec("next");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Sets the MPD to pause or resume the playback.
+ ///
+ /// If the playback should be paused or resumed.
+ public void Pause(bool pause)
+ {
+ MpdResponse response = _connection.Exec("pause", new string[] { pause ? "1" : "0" });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the current item in the playlist.
+ ///
+ public void Play()
+ {
+ MpdResponse response = _connection.Exec("play");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the item with the given index in the playlist.
+ ///
+ /// The index of the track in the playlist to start playing.
+ public void Play(int nr)
+ {
+ MpdResponse response = _connection.Exec("play", new string[] { nr.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the track in the playlist with the id 0.
+ ///
+ public void PlayId()
+ {
+ MpdResponse response = _connection.Exec("playid");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the track in the playlist with the given id.
+ ///
+ /// The id of the track to start playing.
+ public void PlayId(int id)
+ {
+ MpdResponse response = _connection.Exec("playid", new string[] { id.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts the playback of the previous track in the playlist.
+ ///
+ public void Previous()
+ {
+ MpdResponse response = _connection.Exec("previous");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Sets the MPD to random or sequential playback.
+ ///
+ /// If the MPD playlist should be played randomly.
+ public void Random(bool random)
+ {
+ MpdResponse response = _connection.Exec("random", new string[] { random ? "1" : "0" });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Sets if the MPD should repeat the playlist.
+ ///
+ /// If the MPD should repeat the playlist.
+ public void Repeat(bool repeat)
+ {
+ MpdResponse response = _connection.Exec("repeat", new string[] { repeat ? "1" : "0" });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts playback of a given song at the give position.
+ ///
+ /// The index of the song in the playlist.
+ /// The number of seconds to start playback on.
+ public void Seek(int nr, int time)
+ {
+ MpdResponse response = _connection.Exec("seek", new string[] { nr.ToString(), time.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Starts playback of a given song at the give position.
+ ///
+ /// The id of the song in the playlist.
+ /// The number of seconds to start playback on.
+ public void SeekId(int id, int time)
+ {
+ MpdResponse response = _connection.Exec("seekid", new string[] { id.ToString(), time.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Sets the output volume of the MPD.
+ ///
+ /// The output volume of the MPD between 0 and 100.
+ public void SetVol(int vol)
+ {
+ if (vol < 0)
+ throw new ArgumentException("vol < 0");
+ if (vol > 100)
+ throw new ArgumentException("vol > 100");
+
+ MpdResponse response = _connection.Exec("setvol", new string[] { vol.ToString() });
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+ ///
+ /// Stops the playback of the MPD.
+ ///
+ public void Stop()
+ {
+ MpdResponse response = _connection.Exec("stop");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+ }
+
+ #endregion
+
+ #region Misc Commands
+ ///
+ /// Clears the error message set in the MPD.
+ ///
+ public void ClearError()
+ {
+ _connection.Exec("clearerror");
+ }
+ ///
+ /// Returns which commands the current user has access to.
+ ///
+ /// The commands the current user has access to.
+ public List Commands()
+ {
+ MpdResponse response = _connection.Exec("commands");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Returns which commands the current user does has access to.
+ ///
+ /// The commands the current user does has access to.
+ public List NotCommands()
+ {
+ MpdResponse response = _connection.Exec("notcommands");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ return response.getValueList();
+ }
+ ///
+ /// Send the password to the server allow access to the server if enabled in the MPD.
+ ///
+ /// The password to authorize to the server.
+ /// If the password is valid.
+ public bool Password(string password)
+ {
+ if (password == null)
+ throw new ArgumentNullException("password");
+
+ return _connection.Exec("password", new string[] { password }).IsError;
+ }
+ ///
+ /// Sends a ping command to the server and waits for the response.
+ ///
+ public void Ping()
+ {
+ _connection.Exec("ping");
+ }
+ ///
+ /// Requests the current statistics from the MPD,
+ ///
+ /// The current statistics fromt the MPD.
+ public MpdStatistics Stats()
+ {
+ MpdResponse response = _connection.Exec("stats");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ int artists = -1;
+ int albums = -1;
+ int songs = -1;
+ int uptime = -1;
+ int playtime = -1;
+ int db_playtime = -1;
+ int db_update = -1;
+
+ foreach (KeyValuePair line in response)
+ {
+ if ((line.Key != null) && (line.Value != null))
+ switch (line.Key)
+ {
+ case "artists":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ artists = tryValue;
+ }
+ break;
+ case "albums":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ albums = tryValue;
+ }
+ break;
+ case "songs":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ songs = tryValue;
+ }
+ break;
+ case "uptime":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ uptime = tryValue;
+ }
+ break;
+ case "playtime":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ playtime = tryValue;
+ }
+ break;
+ case "db_playtime":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ db_playtime = tryValue;
+ }
+ break;
+ case "db_update":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ db_update = tryValue;
+ }
+ break;
+ }
+ }
+
+ return new MpdStatistics(artists, albums, songs, uptime, playtime, db_playtime, db_update);
+ }
+ ///
+ /// Returns the current status of the MPD.
+ ///
+ /// The current status of the MPD.
+ public MpdStatus Status()
+ {
+ MpdResponse response = _connection.Exec("status");
+
+ if (response.IsError)
+ throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
+
+ int volume = -1;
+ bool repeat = false;
+ bool random = false;
+ int playlist = -1;
+ int playlistLength = -1;
+ int playlistQueue = -1;
+ int xFade = -1;
+ MpdState state = MpdState.Unknown;
+ int song = -1;
+ int songId = -1;
+ int timeElapsed = -1;
+ int timeTotal = -1;
+ int bitrate = -1;
+ int audioSampleRate = -1;
+ int audioBits = -1;
+ int audioChannels = -1;
+ int updatingDb = -1;
+ string error = null;
+
+ foreach (KeyValuePair line in response)
+ {
+ if ((line.Key != null) && (line.Value != null))
+ switch (line.Key)
+ {
+ case "volume":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ {
+ volume = tryValue;
+ if (volume < 0)
+ volume = 0;
+ if (volume > 100)
+ volume = 100;
+ }
+ }
+ break;
+ case "repeat":
+ repeat = (line.Value != null) && (line.Value.Equals("1"));
+ break;
+ case "random":
+ random = (line.Value != null) && (line.Value.Equals("1"));
+ break;
+ case "playlist":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ playlist = tryValue;
+ }
+ break;
+ case "playlistlength":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ playlistLength = tryValue;
+ }
+ break;
+ case "playlistqueue":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ playlistQueue = tryValue;
+ }
+ break;
+ case "xfade":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ xFade = tryValue;
+ }
+ break;
+ case "state":
+ switch (line.Value)
+ {
+ case "play":
+ state = MpdState.Play;
+ break;
+ case "pause":
+ state = MpdState.Pause;
+ break;
+ case "stop":
+ state = MpdState.Stop;
+ break;
+ }
+ break;
+ case "song":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ song = tryValue;
+ }
+ break;
+ case "songid":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ songId = tryValue;
+ }
+ break;
+ case "time":
+ int index = line.Value.IndexOf(':');
+ if (index >= 0)
+ {
+ int tryValue;
+ if (int.TryParse(line.Value.Substring(0, index), out tryValue))
+ timeElapsed = tryValue;
+ if (int.TryParse(line.Value.Substring(index + 1), out tryValue))
+ timeTotal = tryValue;
+ }
+ break;
+ case "bitrate":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ bitrate = tryValue;
+ }
+ break;
+ case "audio":
+ Match match = STATUS_AUDIO_REGEX.Match(line.Value);
+ if (match.Success)
+ {
+ int tryValue;
+ if (int.TryParse(match.Result("$sampleRate"), out tryValue))
+ audioSampleRate = tryValue;
+ if (int.TryParse(match.Result("$bits"), out tryValue))
+ audioBits = tryValue;
+ if (int.TryParse(match.Result("$channels"), out tryValue))
+ audioChannels = tryValue;
+ }
+ break;
+ case "updating_db":
+ {
+ int tryValue;
+ if (int.TryParse(line.Value, out tryValue))
+ updatingDb = tryValue;
+ }
+ break;
+ case "error":
+ error = line.Value;
+ break;
+ }
+ }
+
+ return new MpdStatus(
+ volume,
+ repeat,
+ random,
+ playlist,
+ playlistLength,
+ xFade,
+ state,
+ song,
+ songId,
+ timeElapsed,
+ timeTotal,
+ bitrate,
+ audioSampleRate,
+ audioBits,
+ audioChannels,
+ updatingDb,
+ error
+ );
+ }
+
+ #endregion
+
+ private string toTag(ScopeSpecifier scopeSpecifier)
+ {
+ switch (scopeSpecifier)
+ {
+ default:
+ throw new ArgumentException("scopeSpecifier");
+ case ScopeSpecifier.Any:
+ return TAG_ANY;
+ case ScopeSpecifier.Filename:
+ return TAG_FILENAME;
+ case ScopeSpecifier.Artist:
+ return TAG_ARTIST;
+ case ScopeSpecifier.Album:
+ return TAG_ALBUM;
+ case ScopeSpecifier.Title:
+ return TAG_TITLE;
+ case ScopeSpecifier.Track:
+ return TAG_TRACK;
+ case ScopeSpecifier.Name:
+ return TAG_NAME;
+ case ScopeSpecifier.Genre:
+ return TAG_GENRE;
+ case ScopeSpecifier.Date:
+ return TAG_DATE;
+ case ScopeSpecifier.Composer:
+ return TAG_COMPOSER;
+ case ScopeSpecifier.Performer:
+ return TAG_PERFORMER;
+ case ScopeSpecifier.Comment:
+ return TAG_COMMENT;
+ case ScopeSpecifier.Disc:
+ return TAG_DISC;
+ }
+ }
+ }
+}
diff --git a/LibMpc/MpcConnection.cs b/LibMpc/MpcConnection.cs
index 88849de..65c2007 100644
--- a/LibMpc/MpcConnection.cs
+++ b/LibMpc/MpcConnection.cs
@@ -19,11 +19,11 @@ namespace Libmpc
///
/// Is fired when a connection to a MPD server is established.
///
- public event EventHandler OnConnected;
+ public event EventHandler Connected;
///
/// Is fired when the connection to the MPD server is closed.
///
- public event EventHandler OnDisconnected;
+ public event EventHandler Disconnected;
private static readonly string FIRST_LINE_PREFIX = "OK MPD ";
@@ -44,7 +44,7 @@ namespace Libmpc
///
/// If the connection to the MPD is connected.
///
- public bool Connected { get { return (_tcpClient != null) && _tcpClient.Connected; } }
+ public bool IsConnected { get { return (_tcpClient != null) && _tcpClient.Connected; } }
///
/// The version of the MPD.
///
@@ -67,7 +67,7 @@ namespace Libmpc
/// The IPEndPoint of the MPD server.
public MpcConnection(IPEndPoint server)
{
- Connect(server);
+ Server = server;
}
///
/// The IPEndPoint of the MPD server.
@@ -78,7 +78,7 @@ namespace Libmpc
get { return _ipEndPoint; }
set
{
- if (Connected)
+ if (IsConnected)
throw new AlreadyConnectedException();
_ipEndPoint = value;
@@ -86,15 +86,7 @@ namespace Libmpc
ClearConnectionFields();
}
}
- ///
- /// Connects to a MPD server.
- ///
- /// The IPEndPoint of the server.
- public void Connect(IPEndPoint server)
- {
- Server = server;
- Connect();
- }
+
///
/// Connects to the MPD server who's IPEndPoint was set in the Server property.
///
@@ -104,7 +96,7 @@ namespace Libmpc
if (_ipEndPoint == null)
throw new InvalidOperationException("Server IPEndPoint not set.");
- if (Connected)
+ if (IsConnected)
throw new AlreadyConnectedException();
@@ -131,7 +123,7 @@ namespace Libmpc
ReadResponse();
- OnConnected?.Invoke(this, EventArgs.Empty);
+ Connected?.Invoke(this, EventArgs.Empty);
}
///
/// Disconnects from the current MPD server.
@@ -145,7 +137,7 @@ namespace Libmpc
ClearConnectionFields();
- OnDisconnected?.Invoke(this, EventArgs.Empty);
+ Disconnected?.Invoke(this, EventArgs.Empty);
}
///
/// Executes a simple command without arguments on the MPD server and returns the response.
@@ -175,7 +167,7 @@ namespace Libmpc
{
try { Disconnect(); }
catch (Exception) { }
- throw;
+ return null; // TODO: Create Null Object for MpdResponse
}
}
///
@@ -228,7 +220,7 @@ namespace Libmpc
private void CheckConnected()
{
- if (!Connected)
+ if (!IsConnected)
{
if (_autoConnect)
Connect();