Merge branch 'main' into shuffle
This commit is contained in:
commit
3b55c79d30
@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.3.1
|
||||||
|
|
||||||
|
*Released: 03/11/2022*
|
||||||
|
|
||||||
|
* Update .NET version from 5.0 to 6.0
|
||||||
|
* Fix: simple patch to avoid a crash concerning GetAlbumCover
|
||||||
|
* Fix: connection change now working
|
||||||
|
|
||||||
## v1.3
|
## v1.3
|
||||||
|
|
||||||
*Released: 18/04/2022*
|
*Released: 18/04/2022*
|
||||||
|
@ -66,17 +66,19 @@ namespace unison
|
|||||||
private MpcConnection _connection;
|
private MpcConnection _connection;
|
||||||
private MpcConnection _commandConnection;
|
private MpcConnection _commandConnection;
|
||||||
private IPEndPoint _mpdEndpoint;
|
private IPEndPoint _mpdEndpoint;
|
||||||
private CancellationTokenSource _cancelToken;
|
|
||||||
|
private CancellationTokenSource _cancelCommand;
|
||||||
|
private CancellationTokenSource _cancelConnect;
|
||||||
|
|
||||||
public MPDHandler()
|
public MPDHandler()
|
||||||
{
|
{
|
||||||
Initialize(null, null);
|
Startup(null, null);
|
||||||
|
|
||||||
_stats = new Statistics();
|
_stats = new Statistics();
|
||||||
|
|
||||||
_retryTimer = new DispatcherTimer();
|
_retryTimer = new DispatcherTimer();
|
||||||
_retryTimer.Interval = TimeSpan.FromSeconds(5);
|
_retryTimer.Interval = TimeSpan.FromSeconds(5);
|
||||||
_retryTimer.Tick += Initialize;
|
_retryTimer.Tick += Startup;
|
||||||
|
|
||||||
_elapsedTimer = new System.Timers.Timer(500);
|
_elapsedTimer = new System.Timers.Timer(500);
|
||||||
_elapsedTimer.Elapsed += new System.Timers.ElapsedEventHandler(ElapsedTimer);
|
_elapsedTimer.Elapsed += new System.Timers.ElapsedEventHandler(ElapsedTimer);
|
||||||
@ -149,7 +151,7 @@ namespace unison
|
|||||||
|
|
||||||
public async Task<T> SafelySendCommandAsync<T>(IMpcCommand<T> command)
|
public async Task<T> SafelySendCommandAsync<T>(IMpcCommand<T> command)
|
||||||
{
|
{
|
||||||
if (_commandConnection == null)
|
if (_commandConnection == null || !IsConnected())
|
||||||
{
|
{
|
||||||
Trace.WriteLine("[SafelySendCommandAsync] no command connection");
|
Trace.WriteLine("[SafelySendCommandAsync] no command connection");
|
||||||
return default(T);
|
return default(T);
|
||||||
@ -177,21 +179,52 @@ namespace unison
|
|||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize(object sender, EventArgs e)
|
public async void Startup(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (!_connected)
|
await Initialize();
|
||||||
Connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Connect()
|
public async Task Initialize()
|
||||||
{
|
{
|
||||||
_cancelToken = new CancellationTokenSource();
|
Trace.WriteLine("Initializing");
|
||||||
CancellationToken token = _cancelToken.Token;
|
|
||||||
|
Disconnected();
|
||||||
|
|
||||||
|
if (!_connected)
|
||||||
|
await Connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnected()
|
||||||
|
{
|
||||||
|
_connected = false;
|
||||||
|
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
_commandConnection?.DisconnectAsync();
|
||||||
|
_connection?.DisconnectAsync();
|
||||||
|
|
||||||
|
_cancelConnect?.Cancel();
|
||||||
|
_cancelConnect = new CancellationTokenSource();
|
||||||
|
|
||||||
|
_cancelCommand?.Cancel();
|
||||||
|
_cancelCommand = new CancellationTokenSource();
|
||||||
|
|
||||||
|
_connection = null;
|
||||||
|
_commandConnection = null;
|
||||||
|
|
||||||
|
Trace.WriteLine("Disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Connect()
|
||||||
|
{
|
||||||
|
Trace.WriteLine("Connecting");
|
||||||
|
|
||||||
|
if (_cancelCommand.IsCancellationRequested || _cancelConnect.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_connection = await ConnectInternal(token);
|
_connection = await ConnectInternal(_cancelConnect.Token);
|
||||||
_commandConnection = await ConnectInternal(token);
|
_commandConnection = await ConnectInternal(_cancelCommand.Token);
|
||||||
}
|
}
|
||||||
catch (MpcNET.Exceptions.MpcConnectException e)
|
catch (MpcNET.Exceptions.MpcConnectException e)
|
||||||
{
|
{
|
||||||
@ -219,11 +252,14 @@ namespace unison
|
|||||||
await UpdateStatusAsync();
|
await UpdateStatusAsync();
|
||||||
await UpdateSongAsync();
|
await UpdateSongAsync();
|
||||||
|
|
||||||
Loop(token);
|
Loop(_cancelCommand.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<MpcConnection> ConnectInternal(CancellationToken token)
|
private async Task<MpcConnection> ConnectInternal(CancellationToken token)
|
||||||
{
|
{
|
||||||
|
if (token.IsCancellationRequested)
|
||||||
|
return null;
|
||||||
|
|
||||||
IPAddress.TryParse(Properties.Settings.Default.mpd_host, out _ipAddress);
|
IPAddress.TryParse(Properties.Settings.Default.mpd_host, out _ipAddress);
|
||||||
|
|
||||||
if (_ipAddress == null)
|
if (_ipAddress == null)
|
||||||
@ -263,18 +299,6 @@ namespace unison
|
|||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disconnected()
|
|
||||||
{
|
|
||||||
_connected = false;
|
|
||||||
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
|
|
||||||
if (_connection != null)
|
|
||||||
_connection = null;
|
|
||||||
|
|
||||||
if (_commandConnection != null)
|
|
||||||
_commandConnection = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Loop(CancellationToken token)
|
private void Loop(CancellationToken token)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
@ -283,8 +307,7 @@ namespace unison
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
if (token.IsCancellationRequested || _connection == null || !IsConnected())
|
||||||
if (token.IsCancellationRequested || _connection == null)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
IMpdMessage<string> idleChanges = await _connection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options update"));
|
IMpdMessage<string> idleChanges = await _connection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options update"));
|
||||||
@ -293,14 +316,17 @@ namespace unison
|
|||||||
await HandleIdleResponseAsync(idleChanges.Response.Content);
|
await HandleIdleResponseAsync(idleChanges.Response.Content);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error in Idle connection thread: {idleChanges.Response?.Content}");
|
Trace.WriteLine($"Error in Idle connection thread (1): {idleChanges.Response?.Content}");
|
||||||
throw new Exception(idleChanges.Response?.Content);
|
throw new Exception(idleChanges.Response?.Content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
if (token.IsCancellationRequested)
|
||||||
Disconnected();
|
Trace.WriteLine($"Idle connection cancelled.");
|
||||||
|
else
|
||||||
|
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
||||||
|
await Initialize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,6 +349,7 @@ namespace unison
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
||||||
|
await Initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +374,7 @@ namespace unison
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
||||||
|
await Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
_isUpdatingStatus = false;
|
_isUpdatingStatus = false;
|
||||||
@ -354,6 +382,8 @@ namespace unison
|
|||||||
|
|
||||||
private async Task UpdateSongAsync()
|
private async Task UpdateSongAsync()
|
||||||
{
|
{
|
||||||
|
Trace.WriteLine("Updating song");
|
||||||
|
|
||||||
if (_connection == null || _isUpdatingSong)
|
if (_connection == null || _isUpdatingSong)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -373,13 +403,17 @@ namespace unison
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
||||||
|
await Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
_isUpdatingSong = false;
|
_isUpdatingSong = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void GetAlbumCover(string path, CancellationToken token = default)
|
private async void GetAlbumCover(string path, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
if (token.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
List<byte> data = new List<byte>();
|
List<byte> data = new List<byte>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -392,7 +426,7 @@ namespace unison
|
|||||||
if (_connection == null)
|
if (_connection == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new ReadPictureCommand(path, currentSize));
|
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new AlbumArtCommand(path, currentSize));
|
||||||
if (!albumReq.IsResponseValid)
|
if (!albumReq.IsResponseValid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -414,7 +448,7 @@ namespace unison
|
|||||||
if (_connection == null)
|
if (_connection == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new AlbumArtCommand(path, currentSize));
|
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new ReadPictureCommand(path, currentSize));
|
||||||
if (!albumReq.IsResponseValid)
|
if (!albumReq.IsResponseValid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -430,6 +464,9 @@ namespace unison
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
if (token.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
Trace.WriteLine("Exception caught while getting albumart: " + e);
|
Trace.WriteLine("Exception caught while getting albumart: " + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -443,7 +480,7 @@ namespace unison
|
|||||||
{
|
{
|
||||||
_cover = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
_cover = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||||
}
|
}
|
||||||
catch (System.NotSupportedException)
|
catch
|
||||||
{
|
{
|
||||||
_cover = null;
|
_cover = null;
|
||||||
}
|
}
|
||||||
@ -478,7 +515,7 @@ namespace unison
|
|||||||
SongChanged?.Invoke(this, EventArgs.Empty);
|
SongChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
string uri = Regex.Escape(_currentSong.Path);
|
string uri = Regex.Escape(_currentSong.Path);
|
||||||
GetAlbumCover(uri);
|
GetAlbumCover(uri, _cancelCommand.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCover()
|
public void UpdateCover()
|
||||||
|
@ -4,14 +4,14 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release-Stable</Configuration>
|
||||||
<Platform>Any CPU</Platform>
|
<Platform>Any CPU</Platform>
|
||||||
<PublishDir>publish\</PublishDir>
|
<PublishDir>publish\</PublishDir>
|
||||||
<PublishProtocol>FileSystem</PublishProtocol>
|
<PublishProtocol>FileSystem</PublishProtocol>
|
||||||
<TargetFramework>net5.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<SelfContained>false</SelfContained>
|
<SelfContained>false</SelfContained>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<PublishSingleFile>True</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<PublishReadyToRun>False</PublishReadyToRun>
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
@ -111,14 +111,11 @@ namespace unison
|
|||||||
|
|
||||||
SaveSettings();
|
SaveSettings();
|
||||||
|
|
||||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
|
||||||
if (mpd.IsConnected())
|
|
||||||
mpd = new MPDHandler();
|
|
||||||
|
|
||||||
ConnectButton.IsEnabled = false;
|
ConnectButton.IsEnabled = false;
|
||||||
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusConnecting;
|
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusConnecting;
|
||||||
|
|
||||||
System.Threading.Tasks.Task.Run(() => { mpd.Connect(); });
|
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||||
|
System.Threading.Tasks.Task.Run(async () => { await mpd.Initialize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SnapcastReset_Clicked(object sender, RoutedEventArgs e)
|
private void SnapcastReset_Clicked(object sender, RoutedEventArgs e)
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net5.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<ApplicationIcon>Resources\icon-full.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\icon-full.ico</ApplicationIcon>
|
||||||
<Win32Resource></Win32Resource>
|
<Win32Resource></Win32Resource>
|
||||||
<StartupObject>unison.App</StartupObject>
|
<StartupObject>unison.App</StartupObject>
|
||||||
<Version>1.3</Version>
|
<Version>1.3.1</Version>
|
||||||
<Company />
|
<Company />
|
||||||
<Authors>Théo Marchal</Authors>
|
<Authors>Théo Marchal</Authors>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
|
Loading…
Reference in New Issue
Block a user