Net.Agora.Video
4.6.2.2
See the version list below for details.
dotnet add package Net.Agora.Video --version 4.6.2.2
NuGet\Install-Package Net.Agora.Video -Version 4.6.2.2
<PackageReference Include="Net.Agora.Video" Version="4.6.2.2" />
<PackageVersion Include="Net.Agora.Video" Version="4.6.2.2" />
<PackageReference Include="Net.Agora.Video" />
paket add Net.Agora.Video --version 4.6.2.2
#r "nuget: Net.Agora.Video, 4.6.2.2"
#:package Net.Agora.Video@4.6.2.2
#addin nuget:?package=Net.Agora.Video&version=4.6.2.2
#tool nuget:?package=Net.Agora.Video&version=4.6.2.2
Net.Agora
.NET bindings for Agora's native SDKs, with one API across Android and iOS. Join RTC channels, publish and subscribe audio and video, from C# — in .NET MAUI or plain .NET for Android / .NET for iOS.
Built on Net.Agora.iOS and Net.Agora.Android, which bind the native SDKs. This repository binds nothing itself — see How this repository works.
dotnet add package Net.Agora.Video.Maui # MAUI video apps: adds the video view
dotnet add package Net.Agora.Video # video, everything else
dotnet add package Net.Agora.Voice.Maui # MAUI voice-only apps
dotnet add package Net.Agora.Voice # voice-only, everything else
var client = new AgoraVideoOptions { AppId = "your-app-id" }.CreateClient();
client.SetLocalView(LocalView); // a <agora:AgoraVideoView /> from your XAML
client.UserJoined += (_, e) => client.SetRemoteView(e.Uid, RemoteView);
await client.JoinAsync("my-channel"); // completes when the server confirms
Both clients carry the call essentials — speakerphone routing, who-is-speaking reports, remote mute state, connection lifecycle events, token renewal — and the video client adds the camera half (preview, flip, remote video mute). Voice-only apps get all of it over native artifacts that carry no video codecs at all:
var client = new AgoraVoiceOptions { AppId = "your-app-id", DefaultToSpeakerphone = true }.CreateClient();
client.VolumeIndication += (_, e) => ShowSpeakers(e.Speakers); // uid 0 is you
client.EnableVolumeIndication(TimeSpan.FromMilliseconds(200));
await client.JoinAsync("my-room");
client.SetSpeakerphone(false); // switch the live route mid-call
Pick one product per app: Video already carries the full audio surface, and the two products'
native artifacts collide (same Java classes on Android, same AgoraRtcKit framework on iOS).
Status
This repository covers Agora's Video and Voice SDKs, wired end to end: the raw Android/iOS bindings (in the two sibling repositories above), the cross-platform clients, the MAUI packages, package tests, sample apps, CI. See docs/BUILD.md for the exact state.
| Product | Android | iOS | Cross-platform client | MAUI |
|---|---|---|---|---|
| Video | ✅ Net.Agora.Android | ✅ Net.Agora.iOS | ✅ | ✅ view + glue |
| Voice | ✅ Net.Agora.Android | ✅ Net.Agora.iOS | ✅ | ✅ glue (no view — voice renders nothing) |
How this repository works
Three repositories, each independently versioned and released:
Net.Agora.Android— the raw Android bindings (Agora.Rtc.*, generated fromio.agora.rtc:full-rtc-basic/voice-rtc-basic).Net.Agora.iOS— the raw iOS bindings (Net.Agora.Video.iOS.*/Net.Agora.Voice.iOS.*, hand-written againstAgoraRtcEngineKit).Net.Agora(this repository) — the façades. Each façade package depends on its two platform packages at an exact pinned version (NetAgora<Product><Platform>VersioninDirectory.Build.props) the same way any consumer would, restored from nuget.org. It contains noApiDefinition.cs, no native artifact, noAndroidLibrary/NativeReference— see docs/BUILD.md.
Without MAUI
Net.Agora.Video.Maui only adds the video view and the platform glue. A plain .NET for Android or
.NET for iOS app needs none of that — reference Net.Agora.Video and use the same
AgoraVideoClient, with the platform's own view type instead of AgoraVideoView:
dotnet add package Net.Agora.Video
Android — the SDK renders into a plain Android.Views.SurfaceView, and the client needs the
Context:
using Net.Agora.Video;
using Android.App;
using Android.OS;
using Android.Views;
[Activity(Label = "Publisher", MainLauncher = true)]
public class MainActivity : Activity
{
private AgoraVideoClient? _client;
private SurfaceView? _preview;
protected override async void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
_preview = new SurfaceView(this);
SetContentView(_preview);
var options = new AgoraVideoOptions { AppId = "your-app-id" };
// The Context is the one thing the Android SDK cannot work out for itself.
// Net.Agora.Video.Maui is what supplies it in a MAUI app.
_client = new AgoraVideoClient(options, this);
_client.SetLocalView(_preview);
_client.EnableVideo();
_client.UserJoined += (_, e) => Log.Info("app", $"remote user joined: {e.Uid}");
_client.Error += (_, e) => Log.Error("app", e.Message);
await _client.JoinAsync("my-channel");
}
protected override void OnDestroy()
{
// Releases the camera and the engine; managed collection alone does not.
_client?.Dispose();
base.OnDestroy();
}
}
iOS — a plain UIView, and the client takes no platform handle at all:
using System;
using Net.Agora.Video;
using UIKit;
public class ChannelViewController : UIViewController
{
private AgoraVideoClient? _client;
public override async void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
var options = new AgoraVideoOptions { AppId = "your-app-id" };
_client = new AgoraVideoClient(options);
// Any UIView will do — the SDK adds its own renderer as a subview.
_client.SetLocalView(View!);
_client.EnableVideo();
_client.UserJoined += (_, e) => Console.WriteLine($"remote user joined: {e.Uid}");
_client.Error += (_, e) => Console.WriteLine($"error: {e.Message}");
await _client.JoinAsync("my-channel");
}
public override void ViewDidDisappear(bool animated)
{
_client?.Dispose();
_client = null;
base.ViewDidDisappear(animated);
}
}
Both snippets create the client once the view exists rather than in a constructor — on Android the
Context route (Platform.CurrentActivity) is not reliably usable before OnCreate, and on Apple
the view has no window before ViewDidAppear.
Capture permissions are the app's own responsibility either way: CAMERA and RECORD_AUDIO in
AndroidManifest.xml, NSCameraUsageDescription and NSMicrophoneUsageDescription in
Info.plist.
Packages
| Package | What it is | Target frameworks | Published from |
|---|---|---|---|
Net.Agora.Video.Maui |
MAUI video view and handlers | net8.0, net9.0, net10.0 (android + ios) | this repo |
Net.Agora.Video |
The cross-platform client: IAgoraVideoClient, options, events, async |
net8.0, net9.0, net10.0 (android + ios) | this repo |
Net.Agora.Video.Android |
The raw binding to Agora's Video Android SDK | net8.0-android34.0, net9.0-android35.0, net10.0-android36.0 |
Net.Agora.Android |
Net.Agora.Video.iOS |
The raw binding to Agora's Video iOS SDK | net8.0-ios18.0, net9.0-ios18.0, net10.0-ios26.0 |
Net.Agora.iOS |
Each package pulls in the one below it, so a single reference is enough. Drop to a platform
binding directly for anything the cross-platform API does not expose — the full bound surface is
under Agora.Rtc.* (Android) and Net.Agora.Video.iOS.* (a hand-written subset — see each
repository's own README).
No Mac Catalyst: Agora's iOS SDK ships no maccatalyst slice (ios-arm64 and simulator only).
Why there is a cross-platform layer
Android's RtcEngine is a Java abstract class overridden with a 100+ method event-handler class;
iOS's AgoraRtcEngineKit takes an Objective-C delegate. Written against the bindings directly, an
app targeting both needs a real per-platform adapter before it can join a channel.
Net.Agora.Video is that adapter, so you do not write it.
The sample is the evidence: samples/Net.Agora.Sample joins a channel and renders
local/remote video with no per-platform code at all.
Building
See docs/BUILD.md. In short, the platform packages are built in their own repositories:
# In sbokatuk/Net.Agora.Android:
./build/BuildNugets.sh
# In sbokatuk/Net.Agora.iOS:
./build/fetch-video.sh
./build/BuildNugets.sh
Then, in this repository, pointing NuGet.config's local-artifacts source at wherever those two
were packed (or once both are published, straight from nuget.org):
./build/BuildNugets.sh video
Licence
MIT — see LICENSE. The bundled Agora SDKs are Agora's own, distributed under their own terms via Maven Central and CocoaPods respectively.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-android34.0 is compatible. net8.0-ios18.0 is compatible. net9.0-android was computed. net9.0-android35.0 is compatible. net9.0-ios was computed. net9.0-ios18.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-ios was computed. net10.0-ios26.0 is compatible. |
-
net10.0-android36.0
- Net.Agora.Video.Android (= 4.6.3.2)
-
net10.0-ios26.0
- Net.Agora.Video.iOS (= 4.6.2.2)
-
net8.0-android34.0
- Net.Agora.Video.Android (= 4.6.3.2)
-
net8.0-ios18.0
- Net.Agora.Video.iOS (= 4.6.2.2)
-
net9.0-android35.0
- Net.Agora.Video.Android (= 4.6.3.2)
-
net9.0-ios18.0
- Net.Agora.Video.iOS (= 4.6.2.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Net.Agora.Video:
| Package | Downloads |
|---|---|
|
Net.Agora.Video.Maui
Adds an AgoraVideoView control and the platform glue a .NET MAUI app needs to use Net.Agora.Video: rendering into a native surface on Android and iOS, and supplying the Android Activity RtcEngineConfig requires. Add Net.Agora.Video on its own if you are not using MAUI. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.6.2.5 | 101 | 7/27/2026 |
| 4.6.2.5-beta.13.26 | 47 | 7/31/2026 |
| 4.6.2.5-beta.12.24 | 47 | 7/30/2026 |
| 4.6.2.5-beta.10.23 | 50 | 7/30/2026 |
| 4.6.2.5-beta.9.21 | 45 | 7/29/2026 |
| 4.6.2.5-beta.8.20 | 46 | 7/28/2026 |
| 4.6.2.5-beta.7.19 | 52 | 7/27/2026 |
| 4.6.2.4 | 95 | 7/24/2026 |
| 4.6.2.4-beta.6.17 | 50 | 7/26/2026 |
| 4.6.2.4-beta.5.16 | 47 | 7/25/2026 |
| 4.6.2.4-beta.4.11 | 53 | 7/24/2026 |
| 4.6.2.3 | 102 | 7/24/2026 |
| 4.6.2.3-beta.3.10 | 50 | 7/24/2026 |
| 4.6.2.2 | 95 | 7/24/2026 |
| 4.6.2.2-beta.2.6 | 49 | 7/24/2026 |
| 4.6.2.1 | 98 | 7/23/2026 |
| 4.6.2.1-beta.1.2 | 43 | 7/23/2026 |
| 4.2.6.1-beta1 | 181 | 2/9/2024 |