Skip to content

Releases: sbokatuk/OpenTok.Net.Win

Release list

v2.34.1.4

Choose a tag to compare

@github-actions github-actions released this 29 Jul 06:08
9fe2f60

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

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