Releases: sbokatuk/OpenTok.Net.Win
Release list
v2.34.1.4
OpenTok.Net.Win 2.34.1.4
First release. WinUI 3 video rendering for Vonage's OpenTok Windows SDK, built against
OpenTok.Client 2.34.1.
dotnet add package OpenTok.Net.WinWhat it is for
Unlike the sibling repositories this is not a binding. OpenTok.Client is already managed .NET,
so there is no Objective-C or Java surface to project into C# and nothing here is generated.
What OpenTok.Client does not have is a renderer that works in WinUI:
Asset in OpenTok.Client |
Renderer it ships |
|---|---|
net462 |
WPFVideoRenderer, WinFormsVideoRenderer |
netcoreapp3.1 |
WPFVideoRendererNetCore, WinFormsVideoRendererNetCore |
netstandard2.0 — what a modern .NET app resolves |
none |
WPF and Windows Forms renderers cannot be used from WinUI 3, and .NET MAUI on Windows is WinUI 3.
So without this package an app can connect, publish and subscribe perfectly well and still have
nowhere to put the picture.
What it adds
| Type | For |
|---|---|
OpenTokVideoView |
A WinUI control that displays one stream. Hand view.Renderer to a publisher or subscriber. |
OpenTokVideoRenderer |
The IVideoRenderer itself, if you want to own the Image. |
OpenTokDispatcher |
An IDispatcher that delivers every SDK event on the UI thread. |
I420Converter |
The I420 → BGRA8 conversion, public because a custom renderer needs it too. |
// Every OpenTok event arrives on the UI thread because of this one argument.
var context = new Context(new OpenTokDispatcher(DispatcherQueue.GetForCurrentThread()));
var view = new OpenTokVideoView();
var publisher = new Publisher.Builder(context) { Renderer = view.Renderer }.Build();OpenTokDispatcher is the part most easily missed. The default Context raises events on the SDK's
own threads, and touching any XAML object from there throws RPC_E_WRONG_THREAD — in exactly the
handlers that need to change the UI. It is preferred over the SDK's own ThreadPoolDispatcher
because DispatcherQueue is FIFO: a StreamDropped cannot overtake its StreamReceived and leave
an orphaned tile on screen for the rest of the call.
Notes on the conversion
VideoFrame.ConvertInPlace looks like it should do this and does not — its documentation says it
supports YUV420p as a destination, so it converts to I420, not from it. It is used here for
frames that arrive in some other format, and the I420 → BGRA8 step is written by hand.
BT.601 limited range (Y in 16–235), which is what WebRTC delivers. Full-range coefficients are
the classic mistake here and do not look obviously broken — they produce slightly washed-out video
that survives review.
x64 only
OpenTok.Client's native payload — opentok.dll and its three capturers — is built for x64
only. There is no arm64 build in the package and no separate arm64 package.
This package ships build/OpenTok.Net.Win.targets, which fails the build with OTW0001 if you
target arm64 rather than letting it surface as a BadImageFormatException after the app has
started. Windows on ARM runs the x64 build under emulation; set OpenTokSkipArchitectureCheck=true
if you are supplying the native payload yourself.
Testing
The converter is deliberately written with no WinUI, Windows or OpenTok types in it, and
tests/OpenTok.Net.Win.UnitTests compiles that same source file into a plain net9.0 assembly —
so it runs on any operating system, and CI runs it on Ubuntu.
Everything else here needs Windows to build at all, which is a poor place to leave the one piece of
code that is pure arithmetic over raw bytes and can be wrong without looking wrong: an off-by-one in
a chroma stride or the wrong coefficient set produces a picture that is merely slightly off. 16
tests, pinned to independently computed values.
Versioning
<native SDK version>.<binding revision>, matching the sibling repositories, so
OpenTok.Net.Win 2.34.1.x means "sits on Vonage's Video SDK 2.34.1". OpenTok.Net's façade
requires all three platform heads to agree on the first three components.