Sharpcaster 2.0.3
dotnet add package Sharpcaster --version 2.0.3
NuGet\Install-Package Sharpcaster -Version 2.0.3
<PackageReference Include="Sharpcaster" Version="2.0.3" />
<PackageVersion Include="Sharpcaster" Version="2.0.3" />
<PackageReference Include="Sharpcaster" />
paket add Sharpcaster --version 2.0.3
#r "nuget: Sharpcaster, 2.0.3"
#:package Sharpcaster@2.0.3
#addin nuget:?package=Sharpcaster&version=2.0.3
#tool nuget:?package=Sharpcaster&version=2.0.3
SharpCaster
SharpCaster is a cross-platform C# SDK for communicating with Google Chromecast devices. It enables .NET applications to discover, connect, launch apps, and control media playback on Chromecast devices with support for both .NET Standard 2.0 and .NET 9 (including AOT compilation).
Table of Contents
- Features
- Installation
- Quick Start
- Comprehensive Examples
- Media Queue Management
- Volume Control
- Event Handling
- Custom Chromecast Channels
- Troubleshooting
- Contributing
- License
Features
✅ Device Discovery: Automatic discovery of Chromecast devices on your local network using mDNS
✅ Media Control: Complete media playback control (play, pause, stop, seek, volume)
✅ Queue Management: Support for media queues with navigation (next, previous, shuffle, repeat)
✅ Application Management: Launch and manage Chromecast applications
✅ Custom Channels: Extensible architecture for custom Chromecast channels
✅ Cross-Platform: Compatible with .NET Standard 2.0 and .NET 9
✅ AOT Ready: Full support for Native AOT compilation in .NET 9
✅ Async/Await: Modern async programming model throughout
✅ Event-Driven: Rich event system for real-time status updates
Installation
Install via NuGet Package Manager:
Install-Package SharpCaster
Or via .NET CLI:
dotnet add package SharpCaster
Quick Start
1. Discover and Connect to Chromecast
using Sharpcaster;
using Sharpcaster.Models;
using Sharpcaster.Models.Media;
// Discover Chromecast devices
var locator = new MdnsChromecastLocator();
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token;
var chromecasts = await locator.FindReceiversAsync(cancellationToken);
if (!chromecasts.Any())
{
Console.WriteLine("No Chromecast devices found");
return;
}
// Connect to first found device
var chromecast = chromecasts.First();
var client = new ChromecastClient();
await client.ConnectChromecast(chromecast);
Console.WriteLine($"Connected to {chromecast.Name}");
2. Launch Application and Play Media
// Launch the default media receiver app
await client.LaunchApplicationAsync("CC1AD845"); // Default Media Receiver
// Create and load media
var media = new Media
{
ContentUrl = "https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4",
ContentType = "video/mp4",
Metadata = new MediaMetadata
{
Title = "Sample Video",
SubTitle = "A demonstration video"
}
};
var mediaStatus = await client.MediaChannel.LoadAsync(media);
Console.WriteLine($"Media loaded: {mediaStatus.PlayerState}");
Comprehensive Examples
Complete Media Player Example
public class ChromecastMediaPlayer
{
private ChromecastClient _client;
private ChromecastReceiver _device;
public async Task<bool> ConnectAsync(string deviceName = null)
{
try
{
var locator = new MdnsChromecastLocator();
var devices = await locator.FindReceiversAsync(CancellationToken.None);
_device = deviceName != null
? devices.FirstOrDefault(d => d.Name.Contains(deviceName))
: devices.FirstOrDefault();
if (_device == null) return false;
_client = new ChromecastClient();
await _client.ConnectChromecast(_device);
// Subscribe to events
_client.MediaChannel.StatusChanged += OnMediaStatusChanged;
_client.Disconnected += OnDisconnected;
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
return false;
}
}
public async Task PlayVideoAsync(string url, string title = null)
{
await _client.LaunchApplicationAsync("CC1AD845"); // Default Media Receiver
var media = new Media
{
ContentUrl = url,
ContentType = GetContentType(url),
Metadata = new MediaMetadata
{
Title = title ?? Path.GetFileNameWithoutExtension(url),
MetadataType = MetadataType.Movie
}
};
await _client.MediaChannel.LoadAsync(media);
}
public async Task PlayAudioAsync(string url, string title = null, string artist = null)
{
await _client.LaunchApplicationAsync("CC1AD845");
var media = new Media
{
ContentUrl = url,
ContentType = GetContentType(url),
Metadata = new MusicTrackMetadata
{
Title = title ?? Path.GetFileNameWithoutExtension(url),
Artist = artist,
MetadataType = MetadataType.MusicTrack
}
};
await _client.MediaChannel.LoadAsync(media);
}
private void OnMediaStatusChanged(object sender, MediaStatus status)
{
Console.WriteLine($"Media Status: {status.PlayerState} - {status.CurrentTime:F1}s");
}
private void OnDisconnected(object sender, EventArgs e)
{
Console.WriteLine("Disconnected from Chromecast");
}
private static string GetContentType(string url)
{
var extension = Path.GetExtension(url).ToLower();
return extension switch
{
".mp4" => "video/mp4",
".mp3" => "audio/mpeg",
".wav" => "audio/wav",
".webm" => "video/webm",
_ => "video/mp4"
};
}
}
Media Queue Management
SharpCaster supports advanced queue operations for playlist-style media playback:
// Create a media queue
var queueItems = new[]
{
new QueueItem
{
Media = new Media
{
ContentUrl = "https://example.com/song1.mp3",
ContentType = "audio/mpeg",
Metadata = new MusicTrackMetadata { Title = "Song 1", Artist = "Artist 1" }
}
},
new QueueItem
{
Media = new Media
{
ContentUrl = "https://example.com/song2.mp3",
ContentType = "audio/mpeg",
Metadata = new MusicTrackMetadata { Title = "Song 2", Artist = "Artist 2" }
}
}
};
// Load queue with repeat mode
await client.MediaChannel.QueueLoadAsync(queueItems, 0, RepeatModeType.ALL);
// Navigate through queue
await client.MediaChannel.QueueNextAsync(); // Next track
await client.MediaChannel.QueuePrevAsync(); // Previous track
// Get queue information
var itemIds = await client.MediaChannel.QueueGetItemIdsAsync();
var items = await client.MediaChannel.QueueGetItemsAsync(itemIds);
Volume Control
// Get current volume
var status = await client.ReceiverChannel.GetChromecastStatusAsync();
Console.WriteLine($"Current volume: {status.Volume.Level:P0}");
// Set volume (0.0 to 1.0)
await client.ReceiverChannel.SetVolumeAsync(0.5f);
// Mute/unmute
await client.ReceiverChannel.SetMutedAsync(true);
await client.ReceiverChannel.SetMutedAsync(false);
Event Handling
SharpCaster provides rich event support for real-time updates:
// Media events
client.MediaChannel.StatusChanged += (sender, status) =>
{
Console.WriteLine($"Player State: {status.PlayerState}");
Console.WriteLine($"Current Time: {status.CurrentTime}s");
Console.WriteLine($"Duration: {status.Media?.Duration}s");
};
// Connection events
client.Disconnected += (sender, args) =>
{
Console.WriteLine("Connection lost to Chromecast");
};
// Application events
client.ReceiverChannel.StatusChanged += (sender, status) =>
{
foreach (var app in status.Applications ?? [])
{
Console.WriteLine($"Running app: {app.DisplayName} ({app.AppId})");
}
};
Custom Chromecast Channels
Create custom channels for specialized applications:
public class CustomGameChannel : ChromecastChannel
{
public CustomGameChannel(ILogger<CustomGameChannel> logger)
: base("custom.game", logger) { }
public async Task SendGameCommandAsync(string command, object data)
{
var message = new { type = command, data = data };
await SendAsync(JsonSerializer.Serialize(message));
}
protected override async Task OnMessageReceivedAsync(string message, string messageType)
{
// Handle custom game messages
var gameMessage = JsonSerializer.Deserialize<GameMessage>(message);
// Process game-specific logic
}
}
// Register and use custom channel
var gameChannel = new CustomGameChannel(logger);
client.RegisterChannel(gameChannel);
You can also reverse engineer existing channels:
- In Chrome, go to
chrome://net-export/
- Select 'Include raw bytes (will include cookies and credentials)'
- Click 'Start Logging to Disk'
- Cast from your favorite web app
- Stop logging and open the log in netlog-viewer
- Search for
type:SOCKET
and find familiar JSON data - Collect the exchanged JSON
- Create a new class inheriting from
ChromecastChannel
and implement your logic
Troubleshooting
Common Issues and Solutions
Device Discovery Issues:
// Increase discovery timeout for slow networks
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token;
var devices = await locator.FindReceiversAsync(cancellationToken);
// Manually specify device if discovery fails
var manualDevice = new ChromecastReceiver
{
Name = "My Chromecast",
DeviceUri = new Uri("http://192.168.1.100"),
Port = 8009
};
Connection Timeouts:
// Enable logging for debugging
var loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Debug));
var client = new ChromecastClient(loggerFactory);
Media Loading Failures:
- Ensure media URLs are publicly accessible
- Verify correct
ContentType
is specified - Check that the Chromecast supports the media format
- Use HTTPS URLs when possible
Network Issues:
- Ensure device is on the same network as Chromecast
- Check firewall settings (port 8009 must be accessible)
- Verify mDNS/Bonjour is enabled on the network
Error Handling Best Practices
try
{
await client.MediaChannel.LoadAsync(media);
}
catch (TimeoutException)
{
Console.WriteLine("Request timed out - check network connection");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"Invalid operation: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error: {ex.Message}");
}
Demo
Supported Platforms
- .NET Standard 2.0 - Maximum compatibility across .NET implementations
- .NET 9 - Latest features including Native AOT support
- Compatible with: .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+, Xamarin, Unity
Contributing
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Development Setup
git clone https://github.com/Tapanila/SharpCaster.git
cd SharpCaster
dotnet restore
dotnet build
dotnet test
Testing
Tests require a physical Chromecast device on the network:
dotnet test
Some of the tests may require few tries to pass due to network conditions.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Google.Protobuf (>= 3.31.1)
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.7)
- System.Text.Json (>= 9.0.7)
- Tmds.MDns (>= 0.8.0)
-
net9.0
- Google.Protobuf (>= 3.31.1)
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.7)
- System.Text.Json (>= 9.0.7)
- Tmds.MDns (>= 0.8.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Sharpcaster:
Package | Downloads |
---|---|
SharpCaster.Console
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated | |
---|---|---|---|
2.0.3 | 207 | 7/19/2025 | |
2.0.2 | 186 | 7/19/2025 | |
2.0.1 | 116 | 7/17/2025 | |
2.0.0 | 144 | 7/9/2025 | |
2.0.0-beta1 | 1,304 | 12/27/2024 | |
1.2.4 | 142 | 7/9/2025 | |
1.2.3 | 469 | 12/3/2024 | |
1.2.2 | 295 | 8/30/2024 | |
1.2.1 | 192 | 8/12/2024 | |
1.2.1-alpha | 130 | 8/12/2024 | |
1.2.0 | 183 | 7/21/2024 | |
1.1.18 | 158 | 7/20/2024 | |
1.1.17 | 136 | 7/18/2024 | |
1.1.16 | 129 | 7/18/2024 | |
1.1.15 | 129 | 7/18/2024 | |
1.1.14 | 135 | 7/16/2024 | |
1.1.3 | 163 | 7/15/2024 | |
1.1.2 | 144 | 7/8/2024 | |
1.1.1 | 144 | 7/3/2024 | |
1.1.0 | 123 | 7/3/2024 | |
1.0.8 | 1,858 | 2/27/2023 | |
1.0.7 | 840 | 2/27/2023 | |
1.0.6 | 887 | 2/8/2023 | |
1.0.5 | 1,542 | 5/2/2022 | |
1.0.4 | 1,269 | 3/29/2022 | |
1.0.3 | 1,298 | 2/18/2022 | |
1.0.0 | 1,209 | 2/12/2022 | |
0.4.0 | 7,636 | 5/21/2017 | |
0.4.0-pre | 1,596 | 5/21/2017 | |
0.3.5 | 1,931 | 4/1/2017 | |
0.3.5-pre | 1,566 | 1/23/2017 | |
0.3.4 | 1,923 | 1/11/2017 | |
0.3.4-pre | 1,627 | 1/11/2017 | |
0.3.3-pre | 1,609 | 1/1/2017 | |
0.3.2 | 1,958 | 11/25/2016 | |
0.3.1 | 1,922 | 9/30/2016 | |
0.3.1-pre | 1,574 | 9/30/2016 | |
0.3.0 | 1,844 | 9/8/2016 | |
0.3.0-pre | 1,562 | 9/8/2016 | |
0.2.0-pre | 1,637 | 8/31/2016 | |
0.1.7-pre2 | 1,595 | 8/18/2016 | |
0.1.7-pre | 1,612 | 8/14/2016 | |
0.1.6 | 1,863 | 8/2/2016 | |
0.1.5 | 1,892 | 6/2/2016 | |
0.1.4 | 1,879 | 3/22/2016 | |
0.1.3 | 1,851 | 3/9/2016 | |
0.1.2 | 1,805 | 3/4/2016 | |
0.1.1 | 2,139 | 2/13/2016 | |
0.0.0 | 160 | 8/12/2024 |
See https://github.com/Tapanila/SharpCaster/releases for release notes