Working mpd handling, even if I'm not a big fan of it

This commit is contained in:
Théo Marchal 2021-08-19 22:00:25 +02:00
parent 5d29938589
commit 0bc80ef23b
8 changed files with 294 additions and 155 deletions

View File

@ -1,6 +1,16 @@
using System.Windows; using System;
using System.Diagnostics;
using System.Windows;
using Hardcodet.Wpf.TaskbarNotification; using Hardcodet.Wpf.TaskbarNotification;
// todo:
//
// * finish correct refresh of mpd
// * show mpd version
// * change volume offset
// * fix window resize
// * show covers
namespace unison namespace unison
{ {
public partial class App : Application public partial class App : Application
@ -14,19 +24,21 @@ namespace unison
{ {
base.OnStartup(e); base.OnStartup(e);
Hotkeys = new HotkeyHandler();
Current.Properties["hotkeys"] = Hotkeys;
Snapcast = new SnapcastHandler(); Snapcast = new SnapcastHandler();
Current.Properties["snapcast"] = Snapcast; Current.Properties["snapcast"] = Snapcast;
MPD = new MPDHandler(); MPD = new MPDHandler();
Current.Properties["mpd"] = MPD; Current.Properties["mpd"] = MPD;
Hotkeys = new HotkeyHandler();
Current.Properties["hotkeys"] = Hotkeys;
Current.MainWindow = new MainWindow(); Current.MainWindow = new MainWindow();
Systray = (TaskbarIcon)FindResource("SystrayTaskbar"); Systray = (TaskbarIcon)FindResource("SystrayTaskbar");
Current.Properties["systray"] = Systray; Current.Properties["systray"] = Systray;
MPD.Start();
} }
protected override void OnExit(ExitEventArgs e) protected override void OnExit(ExitEventArgs e)

View File

@ -1,6 +1,8 @@
using System.Collections.Generic; using System;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using MPDCtrl.Models; using MPDCtrl.Models;
namespace unison namespace unison
@ -19,74 +21,236 @@ namespace unison
private Status _currentStatus = null; private Status _currentStatus = null;
private SongInfoEx _currentSong = null; private SongInfoEx _currentSong = null;
private AlbumImage _currentAlbumCover = null;
public MPDHandler() public double _elapsed;
{ private double _time;
}
public async void Connect() private readonly System.Timers.Timer _elapsedTimer;
private async void ElapsedTimer(object sender, System.Timers.ElapsedEventArgs e)
{ {
_connected = await _mpd.MpdCommandConnectionStart(Properties.Settings.Default.mpd_host, Properties.Settings.Default.mpd_port, Properties.Settings.Default.mpd_password); if ((_elapsed < _time) && (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Play))
if (_connected)
{ {
await _mpd.MpdQueryStatus(); _elapsed += 0.5;
await Task.Delay(5); await Task.Delay(5);
_currentVolume = _mpd.MpdStatus.MpdVolume; }
_currentRandom = _mpd.MpdStatus.MpdRandom; else
_currentRepeat = _mpd.MpdStatus.MpdRepeat; {
_currentSingle = _mpd.MpdStatus.MpdSingle; _elapsedTimer.Stop();
_currentConsume = _mpd.MpdStatus.MpdConsume;
_currentElapsed = _mpd.MpdStatus.MpdSongElapsed;
} }
} }
public void CheckStatus<T>(ref T a, T b) bool IsBusy = false;
public MPDHandler()
{ {
if (Comparer<T>.Default.Compare(a, b) != 0) _mpd.IsBusy += new MPC.IsBusyEvent(OnMpcIsBusy);
a = b;
_mpd.MpdIdleConnected += new MPC.IsMpdIdleConnectedEvent(OnMpdIdleConnected);
_mpd.ConnectionStatusChanged += new MPC.ConnectionStatusChangedEvent(OnConnectionStatusChanged);
_mpd.ConnectionError += new MPC.ConnectionErrorEvent(OnConnectionError);
_mpd.MpdPlayerStatusChanged += new MPC.MpdPlayerStatusChangedEvent(OnMpdPlayerStatusChanged);
_mpd.MpdCurrentQueueChanged += new MPC.MpdCurrentQueueChangedEvent(OnMpdCurrentQueueChanged);
_mpd.MpdAlbumArtChanged += new MPC.MpdAlbumArtChangedEvent(OnAlbumArtChanged);
_elapsedTimer = new System.Timers.Timer(500);
_elapsedTimer.Elapsed += new System.Timers.ElapsedEventHandler(ElapsedTimer);
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += QueryStatus;
timer.Start();
} }
public async void Loop() private void OnMpcIsBusy(MPC sender, bool on)
{
IsBusy = on;
}
public void Start()
{
Task.Run(() => _mpd.MpdIdleConnect(Properties.Settings.Default.mpd_host, Properties.Settings.Default.mpd_port));
}
private void OnMpdIdleConnected(MPC sender)
{
Trace.WriteLine($"Connection to mpd {_mpd.MpdVerText}...");
LoadInitialData();
}
private void OnConnectionStatusChanged(MPC sender, MPC.ConnectionStatus status)
{
Trace.WriteLine("Connection changed...");
}
private void OnConnectionError(MPC sender, string msg)
{
Trace.WriteLine("Connection ERROR!");
LoadInitialData();
}
private void OnMpdPlayerStatusChanged(MPC sender)
{
Trace.WriteLine("Status changed...");
UpdateStatus();
}
private void OnMpdCurrentQueueChanged(MPC sender)
{
Trace.WriteLine("Queue changed...");
UpdateStatus();
}
private void OnAlbumArtChanged(MPC sender)
{
// AlbumArt
if (Application.Current == null) { return; }
Application.Current.Dispatcher.Invoke(() =>
{
if ((!_mpd.AlbumCover.IsDownloading) && _mpd.AlbumCover.IsSuccess)
{
if ((_mpd.MpdCurrentSong != null) && (_mpd.AlbumCover.AlbumImageSource != null))
{
if (!String.IsNullOrEmpty(_mpd.MpdCurrentSong.File))
{
if (_mpd.MpdCurrentSong.File == _mpd.AlbumCover.SongFilePath)
{
Trace.WriteLine("found cover");
_currentAlbumCover = _mpd.AlbumCover;
}
}
}
}
});
}
public async void LoadInitialData()
{
//todo : test if the password works
IsBusy = true;
await Task.Delay(5);
CommandResult result = await _mpd.MpdIdleSendPassword(Properties.Settings.Default.mpd_password);
if (result.IsSuccess)
{
_connected = await _mpd.MpdCommandConnectionStart(Properties.Settings.Default.mpd_host, Properties.Settings.Default.mpd_port, Properties.Settings.Default.mpd_password);
if (_connected)
{
await _mpd.MpdSendUpdate();
result = await _mpd.MpdIdleQueryStatus();
await Task.Delay(5);
if (result.IsSuccess)
{
_currentVolume = _mpd.MpdStatus.MpdVolume;
_currentRandom = _mpd.MpdStatus.MpdRandom;
_currentRepeat = _mpd.MpdStatus.MpdRepeat;
_currentSingle = _mpd.MpdStatus.MpdSingle;
_currentConsume = _mpd.MpdStatus.MpdConsume;
_currentElapsed = _mpd.MpdStatus.MpdSongElapsed;
}
await Task.Delay(5);
CommandResult song = await _mpd.MpdIdleQueryCurrentSong();
await Task.Delay(5);
if (song != null)
_currentSong = _mpd.MpdCurrentSong;
await Task.Delay(5);
_mpd.MpdIdleStart();
await Task.Delay(5);
UpdateStatus();
}
}
}
public async void QueryStatus(object sender, EventArgs e)
{
if (IsBusy)
return;
Trace.WriteLine("Querying status...");
CommandResult result = await _mpd.MpdQueryStatus();
await Task.Delay(5);
if (result.IsSuccess)
{
result = await _mpd.MpdQueryCurrentSong();
await Task.Delay(5);
if (result.IsSuccess)
{
UpdateStatus();
}
}
}
public async void UpdateStatus()
{ {
if (!_connected) if (!_connected)
return; return;
CommandResult status = await _mpd.MpdQueryStatus(); await Task.Delay(50);
//Trace.WriteLine(status.ResultText);
await Task.Delay(5);
if (status != null)
{
_currentStatus = _mpd.MpdStatus;
CheckStatus(ref _currentVolume, _mpd.MpdStatus.MpdVolume); _currentStatus = _mpd.MpdStatus;
CheckStatus(ref _currentRandom, _mpd.MpdStatus.MpdRandom);
CheckStatus(ref _currentRepeat, _mpd.MpdStatus.MpdRepeat); _currentRandom = _mpd.MpdStatus.MpdRandom;
CheckStatus(ref _currentSingle, _mpd.MpdStatus.MpdSingle); _currentRepeat = _mpd.MpdStatus.MpdRepeat;
CheckStatus(ref _currentConsume, _mpd.MpdStatus.MpdConsume); _currentConsume = _mpd.MpdStatus.MpdConsume;
CheckStatus(ref _currentElapsed, _mpd.MpdStatus.MpdSongElapsed); _currentSingle = _mpd.MpdStatus.MpdSingle;
_currentVolume = _mpd.MpdStatus.MpdVolume;
_currentElapsed = _mpd.MpdStatus.MpdSongElapsed;
_currentSong = _mpd.MpdCurrentSong;
_time = _mpd.MpdStatus.MpdSongTime;
_elapsed = _mpd.MpdStatus.MpdSongElapsed;
if (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Play)
{
if (!_elapsedTimer.Enabled)
_elapsedTimer.Start();
}
else
{
_elapsedTimer.Stop();
} }
CommandResult song = await _mpd.MpdQueryCurrentSong(); await _mpd.MpdQueryAlbumArt(_currentSong.File, false);
await Task.Delay(5);
if (song != null)
_currentSong = _mpd.MpdCurrentSong;
} }
public SongInfoEx GetCurrentSong() => _currentSong; public SongInfoEx GetCurrentSong() => _currentSong;
public Status GetStatus() => _currentStatus; public Status GetStatus() => _currentStatus;
public AlbumImage GetCover() => _currentAlbumCover;
public async void Prev() public async void Prev()
{ {
await _mpd.MpdPlaybackPrev(_currentVolume); if (!IsBusy)
await _mpd.MpdPlaybackPrev(_currentVolume);
} }
public async void Next() public async void Next()
{ {
await _mpd.MpdPlaybackNext(_currentVolume); if (!IsBusy)
await _mpd.MpdPlaybackNext(_currentVolume);
} }
public async void PlayPause() public async void PlayPause()
{ {
if (IsBusy)
return;
if (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Play) if (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Play)
await _mpd.MpdPlaybackPause(); await _mpd.MpdPlaybackPause();
else if (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Pause) else if (_mpd.MpdStatus.MpdState == Status.MpdPlayState.Pause)
@ -95,34 +259,37 @@ namespace unison
public async void Random() public async void Random()
{ {
await _mpd.MpdSetRandom(!_currentRandom); if (!IsBusy)
await _mpd.MpdSetRandom(!_currentRandom);
} }
public async void Repeat() public async void Repeat()
{ {
await _mpd.MpdSetRepeat(!_currentRepeat); if (!IsBusy)
await _mpd.MpdSetRepeat(!_currentRepeat);
} }
public async void Single() public async void Single()
{ {
await _mpd.MpdSetSingle(!_currentSingle); if (!IsBusy)
await _mpd.MpdSetSingle(!_currentSingle);
} }
public async void Consume() public async void Consume()
{ {
await _mpd.MpdSetConsume(!_currentConsume); if (!IsBusy)
await _mpd.MpdSetConsume(!_currentConsume);
} }
public async void SetVolume(int value) public async void SetVolume(int value)
{ {
await _mpd.MpdSetVolume(value); if (!IsBusy)
await _mpd.MpdSetVolume(value);
} }
public bool IsPlaying() => _currentStatus?.MpdState == MPDCtrl.Models.Status.MpdPlayState.Play; public bool IsPlaying()
{
return _currentStatus?.MpdState == MPDCtrl.Models.Status.MpdPlayState.Play;
}
} }
} }

View File

@ -103,19 +103,22 @@ namespace MPDCtrl.Models
string response = await _binaryReader.ReadLineAsync(); string response = await _binaryReader.ReadLineAsync();
if (response.StartsWith("OK MPD ")) if (response != null)
{ {
MpdVersion = response.Replace("OK MPD ", string.Empty).Trim(); if (response.StartsWith("OK MPD "))
{
MpdVersion = response.Replace("OK MPD ", string.Empty).Trim();
//Debug.WriteLine("TCP Binary Connection: Connected. MPD " + VerText); //Debug.WriteLine("TCP Binary Connection: Connected. MPD " + VerText);
//DebugCommandOutput?.Invoke(this, "<<<<" + response.Trim() + "\n" + "\n"); //DebugCommandOutput?.Invoke(this, "<<<<" + response.Trim() + "\n" + "\n");
//IsMpdCommandConnected = true; //IsMpdCommandConnected = true;
result.IsSuccess = true; result.IsSuccess = true;
// Done for now. // Done for now.
}
} }
else else
{ {

View File

@ -10,6 +10,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using unison;
namespace MPDCtrl.Models namespace MPDCtrl.Models
{ {
@ -188,8 +189,8 @@ namespace MPDCtrl.Models
public delegate void MpdCurrentQueueChangedEvent(MPC sender); public delegate void MpdCurrentQueueChangedEvent(MPC sender);
public event MpdCurrentQueueChangedEvent MpdCurrentQueueChanged; public event MpdCurrentQueueChangedEvent MpdCurrentQueueChanged;
public delegate void MpdPlaylistsChangedEvent(MPC sender); //public delegate void MpdPlaylistsChangedEvent(MPC sender);
public event MpdPlaylistsChangedEvent MpdPlaylistsChanged; //public event MpdPlaylistsChangedEvent MpdPlaylistsChanged;
public delegate void MpdAlbumArtChangedEvent(MPC sender); public delegate void MpdAlbumArtChangedEvent(MPC sender);
public event MpdAlbumArtChangedEvent MpdAlbumArtChanged; public event MpdAlbumArtChangedEvent MpdAlbumArtChanged;
@ -920,7 +921,7 @@ namespace MPDCtrl.Models
{ {
bool isPlayer = false; bool isPlayer = false;
bool isCurrentQueue = false; bool isCurrentQueue = false;
bool isStoredPlaylist = false; //bool isStoredPlaylist = false;
foreach (string line in SubSystems) foreach (string line in SubSystems)
{ {
@ -947,7 +948,7 @@ namespace MPDCtrl.Models
if (line.ToLower() == "changed: stored_playlist") if (line.ToLower() == "changed: stored_playlist")
{ {
// stored_playlist: a stored playlist has been modified, renamed, created or deleted // stored_playlist: a stored playlist has been modified, renamed, created or deleted
isStoredPlaylist = true; //isStoredPlaylist = true;
} }
} }
@ -960,7 +961,18 @@ namespace MPDCtrl.Models
} }
} }
// custom test
if (isCurrentQueue) if (isCurrentQueue)
{
CommandResult idleResult = await MpdIdleQueryCurrentSong();
if (idleResult.IsSuccess)
{
MpdCurrentQueueChanged?.Invoke(this);
}
}
// takes lot of time
/*if (isCurrentQueue)
{ {
CommandResult idleResult = await MpdIdleQueryCurrentQueue(); CommandResult idleResult = await MpdIdleQueryCurrentQueue();
if (idleResult.IsSuccess) if (idleResult.IsSuccess)
@ -976,7 +988,7 @@ namespace MPDCtrl.Models
{ {
MpdPlaylistsChanged?.Invoke(this); MpdPlaylistsChanged?.Invoke(this);
} }
} }*/
//MpcProgress?.Invoke(this, ""); //MpcProgress?.Invoke(this, "");
@ -2609,15 +2621,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Exception@ParseStatus:" + ex.Message); Debug.WriteLine("Exception@ParseStatus:" + ex.Message);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParseStatus", ex.Message);*/
});
}
IsBusy?.Invoke(this, false); IsBusy?.Invoke(this, false);
return Task.FromResult(false); return Task.FromResult(false);
} }
@ -2696,15 +2699,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@ParseCurrentSong: " + ex.Message); Debug.WriteLine("Error@ParseCurrentSong: " + ex.Message);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParseCurrentSong", ex.Message);*/
});
}
return Task.FromResult(false); return Task.FromResult(false);
} }
finally finally
@ -2917,15 +2911,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Exception@ParsePlaylistInfo: " + ex.Message); Debug.WriteLine("Exception@ParsePlaylistInfo: " + ex.Message);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParsePlaylistInfo", ex.Message);*/
});
}
return Task.FromResult(false); return Task.FromResult(false);
} }
finally finally
@ -3069,15 +3054,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@FillSongInfoEx: " + e.ToString()); Debug.WriteLine("Error@FillSongInfoEx: " + e.ToString());
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@FillSongInfoEx", e.Message);*/
});
}
return null; return null;
} }
} }
@ -3182,15 +3158,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@ParsePlaylists: " + e.ToString()); Debug.WriteLine("Error@ParsePlaylists: " + e.ToString());
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParsePlaylists", e.Message);*/
});
}
IsBusy?.Invoke(this, false); IsBusy?.Invoke(this, false);
return Task.FromResult(false); return Task.FromResult(false);
} }
@ -3277,15 +3244,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@ParseListAll: " + e.ToString()); Debug.WriteLine("Error@ParseListAll: " + e.ToString());
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParseListAll", e.Message);*/
});
}
IsBusy?.Invoke(this, false); IsBusy?.Invoke(this, false);
return Task.FromResult(false); ; return Task.FromResult(false); ;
} }
@ -3424,15 +3382,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@ParseSearchResult: " + ex.Message); Debug.WriteLine("Error@ParseSearchResult: " + ex.Message);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParseSearchResult", ex.Message);*/
});
}
IsBusy?.Invoke(this, false); IsBusy?.Invoke(this, false);
return Task.FromResult(false); return Task.FromResult(false);
} }
@ -3565,15 +3514,6 @@ namespace MPDCtrl.Models
{ {
Debug.WriteLine("Error@ParsePlaylistSongsResult: " + ex.Message); Debug.WriteLine("Error@ParsePlaylistSongsResult: " + ex.Message);
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
/*App app = App.Current as App;
app.AppendErrorLog("Exception@MPC@ParsePlaylistSongsResult", ex.Message);*/
});
}
return songList; return songList;
} }

View File

@ -25,7 +25,7 @@
<TextBlock x:Name="SongTitle" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" FontSize="20" Text="Title"/> <TextBlock x:Name="SongTitle" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" FontSize="20" Text="Title"/>
<TextBlock x:Name="SongArtist" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Bold" FontSize="18" Text="Artist"/> <TextBlock x:Name="SongArtist" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Bold" FontSize="18" Text="Artist"/>
<TextBlock x:Name="SongAlbum" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" FontSize="16" Text="Album"/> <TextBlock x:Name="SongAlbum" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" FontSize="16" Text="Album"/>
<TextBlock x:Name="Bitrate" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" Text="Bitrate"/> <TextBlock x:Name="Bitrate" TextWrapping="Wrap" TextAlignment="Center" FontWeight="Normal" Text="Bitrate" Foreground="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
<Grid x:Name="Controls" VerticalAlignment="Top" Margin="10,106,10,0"> <Grid x:Name="Controls" VerticalAlignment="Top" Margin="10,106,10,0">
@ -93,7 +93,8 @@
<StackPanel.OpacityMask> <StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/> <VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask> </StackPanel.OpacityMask>
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="/images/nocover.png" /> <Image x:Name="Cover" HorizontalAlignment="Center" VerticalAlignment="Center" Source="/images/nocover.png" Visibility="Collapsed" />
<Image x:Name="NoCover" HorizontalAlignment="Center" VerticalAlignment="Center" Source="/images/nocover.png" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border> </Border>

View File

@ -1,20 +1,17 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.ComponentModel; using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Threading; using System.Windows.Threading;
using System.Windows.Interop; using System.Windows.Interop;
using System.Diagnostics;
namespace unison namespace unison
{ {
public partial class MainWindow : Window public partial class MainWindow : Window, INotifyPropertyChanged
{ {
private readonly Settings SettingsWindow = new Settings(); private readonly Settings SettingsWindow = new Settings();
private readonly MPDHandler mpd; private MPDHandler mpd;
Thickness SelectedThickness; Thickness SelectedThickness;
Thickness BaseThickness; Thickness BaseThickness;
@ -27,10 +24,9 @@ namespace unison
WindowState = WindowState.Minimized; WindowState = WindowState.Minimized;
mpd = (MPDHandler)Application.Current.Properties["mpd"]; mpd = (MPDHandler)Application.Current.Properties["mpd"];
mpd.Connect();
DispatcherTimer timer = new DispatcherTimer(); DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(0.2); timer.Interval = TimeSpan.FromSeconds(0.5);
timer.Tick += Timer_Tick; timer.Tick += Timer_Tick;
timer.Start(); timer.Start();
@ -41,9 +37,6 @@ namespace unison
private void Timer_Tick(object sender, EventArgs e) private void Timer_Tick(object sender, EventArgs e)
{ {
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
mpd.Loop();
UpdateInterface(); UpdateInterface();
} }
@ -63,7 +56,7 @@ namespace unison
public void UpdateInterface() public void UpdateInterface()
{ {
if (mpd.GetCurrentSong() != null) if (mpd.GetCurrentSong() != null && mpd.GetStatus() != null)
{ {
SongTitle.Text = mpd.GetCurrentSong().Title; SongTitle.Text = mpd.GetCurrentSong().Title;
SongTitle.ToolTip = mpd.GetCurrentSong().File; SongTitle.ToolTip = mpd.GetCurrentSong().File;
@ -74,11 +67,11 @@ namespace unison
Bitrate.Text = mpd.GetCurrentSong().File.Substring(mpd.GetCurrentSong().File.LastIndexOf(".") + 1) + " "; Bitrate.Text = mpd.GetCurrentSong().File.Substring(mpd.GetCurrentSong().File.LastIndexOf(".") + 1) + " ";
Bitrate.Text += mpd.GetStatus().MpdBitrate + "kbps"; Bitrate.Text += mpd.GetStatus().MpdBitrate + "kbps";
CurrentTime.Text = FormatSeconds(mpd._currentElapsed); CurrentTime.Text = FormatSeconds(mpd._elapsed);
EndTime.Text = FormatSeconds(mpd.GetStatus().MpdSongTime); EndTime.Text = FormatSeconds(mpd.GetStatus().MpdSongTime);
if (!System.Double.IsNaN(mpd.GetCurrentSong().TimeSort)) if (!System.Double.IsNaN(mpd.GetCurrentSong().TimeSort))
TimeSlider.Value = mpd._currentElapsed / mpd.GetCurrentSong().TimeSort * 100; TimeSlider.Value = mpd._elapsed / mpd.GetCurrentSong().TimeSort * 100;
} }
if (VolumeSlider.Value != mpd._currentVolume) if (VolumeSlider.Value != mpd._currentVolume)
@ -104,11 +97,28 @@ namespace unison
UpdateButton(ref BorderRepeat, mpd._currentRepeat); UpdateButton(ref BorderRepeat, mpd._currentRepeat);
UpdateButton(ref BorderSingle, mpd._currentSingle); UpdateButton(ref BorderSingle, mpd._currentSingle);
UpdateButton(ref BorderConsume, mpd._currentConsume); UpdateButton(ref BorderConsume, mpd._currentConsume);
if (mpd.GetCover() != null)
{
if ((!mpd.GetCover().IsDownloading) && mpd.GetCover().IsSuccess)
{
if (mpd.GetCurrentSong().File == mpd.GetCover().SongFilePath)
{
Cover.Source = mpd.GetCover().AlbumImageSource;
Cover.Visibility = Visibility.Visible;
NoCover.Visibility = Visibility.Collapsed;
return;
}
}
}
NoCover.Visibility = Visibility.Visible;
Cover.Visibility = Visibility.Collapsed;
} }
public void Pause_Clicked(object sender, RoutedEventArgs e) => mpd.PlayPause(); public void Pause_Clicked(object sender, RoutedEventArgs e) => mpd.PlayPause();
public void Previous_Clicked(object sender, RoutedEventArgs e) => mpd.Prev(); public void Previous_Clicked(object sender, RoutedEventArgs e) => mpd.Prev();
public void Next_Clicked(object sender, RoutedEventArgs e) => mpd.Next(); public void Next_Clicked(object sender, RoutedEventArgs e) => mpd.Next();
public void Random_Clicked(object sender, RoutedEventArgs e) => mpd.Random(); public void Random_Clicked(object sender, RoutedEventArgs e) => mpd.Random();
public void Repeat_Clicked(object sender, RoutedEventArgs e) => mpd.Repeat(); public void Repeat_Clicked(object sender, RoutedEventArgs e) => mpd.Repeat();
public void Single_Clicked(object sender, RoutedEventArgs e) => mpd.Single(); public void Single_Clicked(object sender, RoutedEventArgs e) => mpd.Single();
@ -152,5 +162,12 @@ namespace unison
WindowInteropHelper helper = new(this); WindowInteropHelper helper = new(this);
helper.EnsureHandle(); helper.EnsureHandle();
} }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }

View File

@ -46,7 +46,7 @@ namespace unison
MpdHost.Text = Properties.Settings.Default.mpd_host; MpdHost.Text = Properties.Settings.Default.mpd_host;
MpdPort.Text = Properties.Settings.Default.mpd_port.ToString(); MpdPort.Text = Properties.Settings.Default.mpd_port.ToString();
MpdPassword.Text = Properties.Settings.Default.mpd_password; MpdPassword.Text = null; //Properties.Settings.Default.mpd_password;
SnapcastStartup.IsChecked = Properties.Settings.Default.snapcast_startup; SnapcastStartup.IsChecked = Properties.Settings.Default.snapcast_startup;
SnapcastPath.Text = Properties.Settings.Default.snapcast_path; SnapcastPath.Text = Properties.Settings.Default.snapcast_path;
SnapcastPort.Text = Properties.Settings.Default.snapcast_port.ToString(); SnapcastPort.Text = Properties.Settings.Default.snapcast_port.ToString();
@ -70,7 +70,7 @@ namespace unison
{ {
SaveSettings(); SaveSettings();
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"]; MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
mpd.Connect(); //mpd.Connect();
} }
private void SnapcastReset_Clicked(object sender, RoutedEventArgs e) private void SnapcastReset_Clicked(object sender, RoutedEventArgs e)
@ -83,7 +83,7 @@ namespace unison
{ {
Properties.Settings.Default.mpd_host = MpdHost.Text; Properties.Settings.Default.mpd_host = MpdHost.Text;
Properties.Settings.Default.mpd_port = int.Parse(MpdPort.Text, CultureInfo.InvariantCulture); Properties.Settings.Default.mpd_port = int.Parse(MpdPort.Text, CultureInfo.InvariantCulture);
Properties.Settings.Default.mpd_password = MpdPassword.Text; Properties.Settings.Default.mpd_password = null;//MpdPassword.Text;
Properties.Settings.Default.snapcast_startup = (bool)SnapcastStartup.IsChecked; Properties.Settings.Default.snapcast_startup = (bool)SnapcastStartup.IsChecked;
Properties.Settings.Default.snapcast_path = SnapcastPath.Text; Properties.Settings.Default.snapcast_path = SnapcastPath.Text;
Properties.Settings.Default.snapcast_port = int.Parse(SnapcastPort.Text, CultureInfo.InvariantCulture); Properties.Settings.Default.snapcast_port = int.Parse(SnapcastPort.Text, CultureInfo.InvariantCulture);

View File

@ -12,7 +12,6 @@
<ItemGroup> <ItemGroup>
<None Remove="images\nocover-test.png" /> <None Remove="images\nocover-test.png" />
<None Remove="images\nocover.png" />
<None Remove="images\unison.ico" /> <None Remove="images\unison.ico" />
<None Remove="LICENSE" /> <None Remove="LICENSE" />
<None Remove="snapclient_0.25.0-1_win64\FLAC.dll" /> <None Remove="snapclient_0.25.0-1_win64\FLAC.dll" />