WebRTC for Blazor and Xamarin Forms with a single common API
As stated in the WebRTC site: “With WebRTC (Real-Time Communication for the Web), you can add real-time communication capabilities to your application that works on top of an open standard. It supports video, voice, and generic data to be sent between peers, allowing developers to build powerful voice- and video-communication solutions. The technology is available on all modern browsers as well as on native clients for all major platforms. The technologies behind WebRTC are implemented as an open web standard and available as regular JavaScript APIs in all major browsers. For native clients, like Android and iOS applications, a library is available that provides the same functionality.”
Let us setup a peer to peer audio/video (media) connection between Blazor and Xamarin by using my new WebRTCme framework. This connection scenario can equally be applied to all possible combinations of Blazor and Xamarin Forms, i.e. Blazor/Blazor, Blazor/Xamarin.Android, Blazor/Xamarin.iOS, Xamarin.Android/Xamarin.iOS, etc.
- Add two Media tags in your view; one for local and one for the remote media stream (markup is simplified for brevity):
Blazor
<Media Stream="@LocalStream" />
<Media Stream="@RemoteStream" />Xamarin
<webRtc:Media Stream="{Binding LocalStream}" />
<webRtc:Media Stream="{Binding RemoteStream}" />
2. Provide a form to get connection request parameters:
3. On code behind, call media stream service to obtain LocalStream:
LocalStream = await _mediaStreamService.GetCameraMediaStreamAsync();
4. Again on code behind, call signaling server service with the connection request parameters to obtain RemoteStream:
_signallingServerService.ConnectionRequest(connectionRequestParameters).Subscribe(
onNext: (peerResponseParameters) =>
{
RemoteStream = peerResponseParameters.MediaStream;
}
);
5. And the result…
A data channel to exchange messages (chat) or data can be added to the existing connection by specifying a data channel name in code behind.
WebRTCme
WebRTCme framework consists of multiple libraries and their corresponding NuGet packages to provide WebRTC functionality to Blazor and Xamarin Forms applications. Here “me” stands for my initials and used to create a unique name space. Let us analyze these libraries from bottom to top.
- WebRTCme.Api
All three native platforms - Web Browsers, Android and iOS have their own separate APIs. One of the aims of this project is to abstract and wrap these different APIs into a single common API to simplify application programmer’s task not need to learn and use all these APIs, but one.
IETF WebRTC Working Group have developed an API specification (version 1.0) for WebRTC and this API has already been embedded into the browsers as described here.
I decided to use this API as the single common API for Blazor and Xamarin platforms and created a .NET standard library (WebRTCme.Api) for that purpose. API is exposed as interfaces, models and enums; no API implementation, just declarations that can be implemented for any platform. - WebRTCme.Bindings
As can be seen in the following figure, different native platforms are mapped into .NET world by employing Xamarin bindings and Blazor JSInterop. WebRTC iOS and Android SDKs are not released by Google anymore and have to be built from the source code. How to built these SDKs are documented in the following links:
https://webrtc.github.io/webrtc-org/native-code/ios/
https://medium.com/xamarin-webrtc/xamarin-webrtc-compiling-the-native-ios-library-558a8f60aef6
https://dgatto.com/posts/2020/10/xam-webrtc-binding-ios/
https://webrtc.github.io/webrtc-org/native-code/android/
https://medium.com/xamarin-webrtc/compiling-the-android-webrtc-library-7f6e6bcda9c9
https://medium.com/@abdularis/how-to-compile-native-webrtc-from-source-for-android-d0bac8e4c933
- WebRTCme
This is the core unit that implements the WebRTCme.Api for Blazor, Xamarin.iOS and Xamarin.Android platforms. It is a Xamarin plugin unit that uses bait and switch PCL trick to provide platform specific implementations for the shared common WebRTCme.Api interfaces. .NET standard is used for Blazor.
- WebRTCme.Middleware
This is the services layer between application and the core. The Middleware API is exposed as Interfaces, Models and Enums, therefore it can easily be replaced with a custom implementation. This layer provides four functionalities:
1.) Xamarin custom renderer and Blazor component to support Media tag. This requires platform specific implementations, hence WebRTCme.Middleware.Blazor and WebRTCme.Xamarin libraries provided on top of shared WebRTCme.Middleware library.
2.) Media stream service.
3.) Blazor and Xamarin shared connection handling with signalling server through a proxy.
4.) Blazor and Xamarin shared view models to handle call and chat functionalities.
- WebRTCme.SignallingServerProxy
This tiny library is a bridge between middleware and the signalling server. It exposes two APIs as C# interfaces; one for the middleware and the other for the signalling server. The current implementation uses SignalR with message pack protocol. - WebRTCme.SignallingServer
The DotNet Core server implements the API exposed by the proxy and also uses SignalR. It provides gateways to various Turn servers that can be selected from the application. Currently, local StunOnly and Xirsys Turn servers are supported. AppRtc, Coturn and Twilio supports will be added later. The server also supports multi-peer connection by using rooms concept. A peer can join to a room and communicate with the other peers in that room. There is no restriction on number of multi-peer connections. Limit would be the network capacity as it carries separate media streams for each peer to peer connection.
Here is the screenshots of multi peers connections:
The source code of all libraries and the demo application can be found in my GitHub repo. The NuGet package list is given below with their library relationships.
Credits
Credit goes all these people listed below who provided excellent articles and libraries that helped and inspired me to develop this framework:
Paula Aliu: https://medium.com/xamarin-webrtc
Daniel Gatto: https://github.com/dmariogatto/xamarin-webrtc
Valentin Griorean: https://github.com/valentingrigorean/webrtc-xamarin
Remi Bourgarel: https://github.com/RemiBou/BrowserInterop
Aris R: https://medium.com/@abdularis/how-to-compile-native-webrtc-from-source-for-android-d0bac8e4c933
Lachlan Gordon: https://lachlanwgordon.com/blazor-xamarin-code-sharing/