Another .NET API client for Snapcast. The current implementation uses a raw TCP connection to communicate with the Snapcast server. All serialisation and deserialisation of data is handled within the client.
**Note (2025/08/02): This is a fork of https://gitlab.com/sturd/snapcast-net implementing the missing functionality. I eventually create a PR for this, but this needs testing first. **
# Add GitHub Packages source
dotnet nuget add source https://nuget.pkg.github.com/metaneutrons/index.json --name github-snapcast-client
# Install the package
dotnet add package SnapcastClient --source github-snapcast-clientSee PACKAGE.md for detailed installation instructions and authentication setup.
SnapcastClient includes enterprise-grade features for production use:
- Connection Resilience: Automatic reconnection with exponential backoff
- Health Monitoring: Periodic connection health checks
- Comprehensive Logging: Structured logging with Microsoft.Extensions.Logging
- Dependency Injection: Full DI container integration
- Configuration Management: Options pattern support
See ENTERPRISE_FEATURES.md for detailed documentation and examples.
using SnapcastClient;
var connection = new TcpConnection("127.0.0.1", 1705);
var client = new Client(connection);
var result = await client.ServerGetRpcVersionAsync();
// result = {
// Major: 2,
// Minor: 0,
// Patch: 0
// }using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SnapcastClient;
var services = new ServiceCollection();
services.AddLogging(logging => logging.AddConsole());
// Add resilient Snapcast client
services.AddSnapcastClient("127.0.0.1", 1705, options =>
{
options.EnableAutoReconnect = true;
options.MaxRetryAttempts = 5;
options.HealthCheckIntervalMs = 30000;
});
var serviceProvider = services.BuildServiceProvider();
var client = serviceProvider.GetRequiredService<IClient>();
var result = await client.ServerGetRpcVersionAsync();- Client.GetStatus
- Client.SetVolume
- Client.SetLatency
- Client.SetName
- Group.GetStatus
- Group.SetMute
- Group.SetStream
- Group.SetClients
- Group.SetName
- Server.GetRPCVersion
- Server.GetStatus
- Server.DeleteClient
- Stream.AddStream
- Stream.RemoveStream
- Stream.Control
- Stream.SetProperty
- Client.OnConnect
- Client.OnDisconnect
- Client.OnVolumeChanged
- Client.OnLatencyChanged
- Client.OnNameChanged
- Group.OnMute
- Group.OnStreamChanged
- Group.OnNameChanged
- Stream.OnProperties
- Stream.OnUpdate
- Server.OnUpdate
The library provides convenient methods for common stream control operations:
StreamPlayAsync(streamId)- Play a streamStreamPauseAsync(streamId)- Pause a streamStreamNextAsync(streamId)- Skip to next trackStreamPreviousAsync(streamId)- Skip to previous trackStreamSeekAsync(streamId, position)- Seek to specific positionStreamSeekByOffsetAsync(streamId, offset)- Seek by offset
StreamSetVolumeAsync(streamId, volume)- Set stream volume (0-100)StreamSetMuteAsync(streamId, mute)- Mute/unmute streamStreamSetShuffleAsync(streamId, shuffle)- Enable/disable shuffleStreamSetLoopStatusAsync(streamId, loopStatus)- Set loop mode ("none", "track", "playlist")StreamSetRateAsync(streamId, rate)- Set playback rate (1.0 = normal speed)
Subscribe to notifications to receive real-time updates:
// Client events
client.OnClientConnect = (client) => Console.WriteLine($"Client connected: {client.Id}");
client.OnClientDisconnect = (client) => Console.WriteLine($"Client disconnected: {client.Id}");
client.OnClientVolumeChanged = (volumeChange) => Console.WriteLine($"Volume changed: {volumeChange.Volume.Percent}%");
// Group events
client.OnGroupMute = (muteChange) => Console.WriteLine($"Group {muteChange.Id} muted: {muteChange.Mute}");
client.OnGroupStreamChanged = (streamChange) => Console.WriteLine($"Group {streamChange.Id} stream: {streamChange.StreamId}");
// Stream events
client.OnStreamUpdate = async (stream) => Console.WriteLine($"Stream updated: {stream.Id}");
client.OnStreamProperties = (properties) => Console.WriteLine($"Stream properties: {properties.Id}");
// Server events
client.OnServerUpdate = (server) => Console.WriteLine("Server updated");For advanced control, you can use the low-level StreamControlAsync and StreamSetPropertyAsync methods:
// Direct stream control with custom parameters
await client.StreamControlAsync("Spotify", "seek", new Dictionary<string, object> { { "offset", 30 } });
// Set custom stream properties
await client.StreamSetPropertyAsync("Spotify", "volume", 75);
await client.StreamSetPropertyAsync("Spotify", "loopStatus", "playlist");// Basic playback control
await client.StreamPlayAsync("Spotify");
await client.StreamPauseAsync("Spotify");
await client.StreamNextAsync("Spotify");
await client.StreamPreviousAsync("Spotify");
// Seeking
await client.StreamSeekAsync("Spotify", 120.5); // Seek to 2 minutes 30 seconds
await client.StreamSeekByOffsetAsync("Spotify", 30); // Skip forward 30 seconds
// Stream properties
await client.StreamSetVolumeAsync("Spotify", 80); // Set volume to 80%
await client.StreamSetMuteAsync("Spotify", true); // Mute the stream
await client.StreamSetShuffleAsync("Spotify", true); // Enable shuffle
await client.StreamSetLoopStatusAsync("Spotify", "track"); // Loop current track
await client.StreamSetRateAsync("Spotify", 1.5); // Play at 1.5x speed