/SnapcastClient

Primary LanguageC#GNU General Public License v3.0GPL-3.0

SnapcastClient

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. **

Installation

From GitHub Packages

# 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-client

See PACKAGE.md for detailed installation instructions and authentication setup.

Enterprise Features

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.

Usage

Basic Usage

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
// }

Enterprise Usage with Dependency Injection

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();

Implemented Commands

  • 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

Implemented Notifications

  • Client.OnConnect
  • Client.OnDisconnect
  • Client.OnVolumeChanged
  • Client.OnLatencyChanged
  • Client.OnNameChanged
  • Group.OnMute
  • Group.OnStreamChanged
  • Group.OnNameChanged
  • Stream.OnProperties
  • Stream.OnUpdate
  • Server.OnUpdate

Stream Control Convenience Methods

The library provides convenient methods for common stream control operations:

Playback Control

  • StreamPlayAsync(streamId) - Play a stream
  • StreamPauseAsync(streamId) - Pause a stream
  • StreamNextAsync(streamId) - Skip to next track
  • StreamPreviousAsync(streamId) - Skip to previous track
  • StreamSeekAsync(streamId, position) - Seek to specific position
  • StreamSeekByOffsetAsync(streamId, offset) - Seek by offset

Stream Properties

  • StreamSetVolumeAsync(streamId, volume) - Set stream volume (0-100)
  • StreamSetMuteAsync(streamId, mute) - Mute/unmute stream
  • StreamSetShuffleAsync(streamId, shuffle) - Enable/disable shuffle
  • StreamSetLoopStatusAsync(streamId, loopStatus) - Set loop mode ("none", "track", "playlist")
  • StreamSetRateAsync(streamId, rate) - Set playback rate (1.0 = normal speed)

Event Handling

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");

Advanced Stream Control

Direct Stream Control

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");

Stream Control Examples

// 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