opentok / opentok-windows-sdk-samples

Sample applications illustrating best practices using OpenTok Windows SDK
MIT License
9 stars 29 forks source link

.NET Core 6 #48

Closed wesoos closed 1 year ago

wesoos commented 1 year ago

Describe the bug I'm having an issue with the OpenTok Windows Client SDK. I just upgraded to the latest version, 2.24.2. Calling AudioDevice.EnumerateInputAudioDevices() now gives me an empty list, where version 2.23.2 gives me 2 devices. I am using .NET Core 6.

To Reproduce Create a .Net Core 6 WPF application. Add nuget for latest OpenTok.Client package (2.24.2). Add same code from BasicVideoChat sample app. Run app.

Expected behavior AudioDevice.EnumerateInputAudioDevices() should give me 2 devices. Version 2.23.2 works fine and gives me 2 devices.

Device (please compete the following information):

wesoos commented 1 year ago

I have also enabled the logging and it gives nothing...

sergioturgil-vonage commented 1 year ago

Hi. I believe I know what the problem is.

In version 2.23.2 audio device enumeration is done directly using a windows specific library that we recently included in the package (OpenTokMMDevice). This was so both for regular Windows desktop projects and for .NetCore projects which depended on OpenTokNetStandard library.

As of 2.24.0, we generalized OpenTokNetStandard library to make it platform agnostic so it can be used in our upcoming SDKs (UWP and Unity). As a result we had to stop using OpenTokMMDevice with OpenTOkNetStandard which is the library used when building for .NET6. Instead, we resort to using the old internal audio module provided by webrtc.

The problem with this internal audio module is it needs to be initialized to work and for the windows SDK, that means creating the session before actually using AudioDevice methods. A quick (maybe not ideal) fix for this is using AudioDevice.EnumerateInputAudioDevices after creating the session (but before connecting).

Note this is only required when building with OpenTOkNetStandard library (that is, with .Net Core framework). With the regular .Net framework this should work ok.

Also, since we're aware that this is not a good solution, we've recently been working on a more solid solution for audio management in windows (both regular .net framework and .net core). It involves using a custom audio device. This solution has already been tested and it's way underway to make it to the official release. Once this happens, we'll provide a sample to show how to use the system which is far more reliable.

Hope I could help. Pls let us know if anything is not clear. Thx!

wesoos commented 1 year ago

Thank you for the clear explanation. I will try the workaround for now…

Thanks

Wessel Oosthuizen ● CTO o: (678) 951-0626 EXT. 103 ● c: (404) 993-2736 e: @.**@.> ● TEKWAVESolutions.com

From: Sergio Tur Gil @.> Sent: Tuesday, February 21, 2023 12:06 PM To: opentok/opentok-windows-sdk-samples @.> Cc: Wessel Oosthuizen @.>; Author @.> Subject: Re: [opentok/opentok-windows-sdk-samples] .NET Core 6 (Issue #48)

Hi. I believe I know what the problem is.

In version 2.23.2 audio device enumeration is done directly using a windows specific library that we recently included in the package (OpenTokMMDevice). This was so both for regular Windows desktop projects and for .NetCore projects which depended on OpenTokNetStandard library.

As of 2.24.0, we generalized OpenTokNetStandard library to make it platform agnostic so it can be used in our upcoming SDKs (UWP and Unity). As a result we had to stop using OpenTokMMDevice with OpenTOkNetStandard which is the library used when building for .NET6. Instead, we resort to using the old internal audio module provided by webrtc.

The problem with this internal audio module is it needs to be initialized to work and for the windows SDK, that means creating the session before actually using AudioDevice methods. A quick (maybe not ideal) fix for this is using AudioDevice.EnumerateInputAudioDevices after creating the session (but before connecting).

Note this is only required when building with OpenTOkNetStandard library (that is, with .Net Core framework). With the regular .Net framework this should work ok.

Also, since we're aware that this is not a good solution, we've recently been working on a more solid solution for audio management in windows (both regular .net framework and .net core). It involves using a custom audio device. This solution has already been tested and it's way underway to make it to the official release. Once this happens, we'll provide a sample to show how to use the system which is far more reliable.

Hope I could help. Pls let us know if anything is not clear. Thx!

— Reply to this email directly, view it on GitHubhttps://github.com/opentok/opentok-windows-sdk-samples/issues/48#issuecomment-1438820157, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABXERZXWFYA63IMLWIEW34LWYTYXLANCNFSM6AAAAAAVCE2KTI. You are receiving this because you authored the thread.Message ID: @.**@.>>

wesoos commented 1 year ago

Hello,

This workaround does not seem to work. I’m still getting zero devices. Please see code below:

Session = new Session.Builder(context, API_KEY, SESSION_ID).Build();

            IList<AudioDevice.InputAudioDevice> availableMics = AudioDevice.EnumerateInputAudioDevices();
           if (availableMics == null || availableMics.Count == 0)
                throw new Exception("No audio capture devices detected");
            AudioDevice.SetInputAudioDevice(availableMics[0]);

            IList<VideoCapturer.VideoDevice> capturerDevices = VideoCapturer.EnumerateDevices();
            if (capturerDevices == null || capturerDevices.Count == 0)
                throw new Exception("No video capture devices detected");

            Publisher = new Publisher.Builder(context)
            {
                Capturer = capturerDevices[0].CreateVideoCapturer(VideoCapturer.Resolution.High, VideoCapturer.FrameRate.Fps30),
                Renderer = PublisherVideo
            }.Build();

Wessel Oosthuizen ● CTO o: (678) 951-0626 EXT. 103 ● c: (404) 993-2736 e: @.**@.> ● TEKWAVESolutions.com

From: Sergio Tur Gil @.> Sent: Tuesday, February 21, 2023 12:06 PM To: opentok/opentok-windows-sdk-samples @.> Cc: Wessel Oosthuizen @.>; Author @.> Subject: Re: [opentok/opentok-windows-sdk-samples] .NET Core 6 (Issue #48)

Hi. I believe I know what the problem is.

In version 2.23.2 audio device enumeration is done directly using a windows specific library that we recently included in the package (OpenTokMMDevice). This was so both for regular Windows desktop projects and for .NetCore projects which depended on OpenTokNetStandard library.

As of 2.24.0, we generalized OpenTokNetStandard library to make it platform agnostic so it can be used in our upcoming SDKs (UWP and Unity). As a result we had to stop using OpenTokMMDevice with OpenTOkNetStandard which is the library used when building for .NET6. Instead, we resort to using the old internal audio module provided by webrtc.

The problem with this internal audio module is it needs to be initialized to work and for the windows SDK, that means creating the session before actually using AudioDevice methods. A quick (maybe not ideal) fix for this is using AudioDevice.EnumerateInputAudioDevices after creating the session (but before connecting).

Note this is only required when building with OpenTOkNetStandard library (that is, with .Net Core framework). With the regular .Net framework this should work ok.

Also, since we're aware that this is not a good solution, we've recently been working on a more solid solution for audio management in windows (both regular .net framework and .net core). It involves using a custom audio device. This solution has already been tested and it's way underway to make it to the official release. Once this happens, we'll provide a sample to show how to use the system which is far more reliable.

Hope I could help. Pls let us know if anything is not clear. Thx!

— Reply to this email directly, view it on GitHubhttps://github.com/opentok/opentok-windows-sdk-samples/issues/48#issuecomment-1438820157, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABXERZXWFYA63IMLWIEW34LWYTYXLANCNFSM6AAAAAAVCE2KTI. You are receiving this because you authored the thread.Message ID: @.**@.>>

ntustzeus commented 1 year ago

Same issue, I have WPF, C#, .NET6 project and AudioDevice.EnumerateInputAudioDevices() return empty.

I also tried to create a new project that using WPF, C#, .NET framework 4.8, it throw exceptoin after AudioDevice.EnumerateInputAudioDevices() excuted.

Can I use 2.23.2 or other old version in .NET6 project as workaround?

sergioturgil-vonage commented 1 year ago

Hi! You're right. The code you provided still causes the issue. I've been moving around some parts of the code and it seems that it's, in fact the publisher, and not the session, what needs to be created for the internal audio module to be able to provide a list of audio devices. So, this code worked for me on a .NetCore project (based on BasicVideoChat.Initialize method):

public MainWindow() { InitializeComponent();

        // Uncomment following line to get debug logging
        // LogUtil.Instance.EnableLogging();            

        context = new Context(new WPFDispatcher());

        IList<VideoCapturer.VideoDevice> capturerDevices = VideoCapturer.EnumerateDevices();
        if (capturerDevices == null || capturerDevices.Count == 0)
            throw new Exception("No video capture devices detected");

        Publisher = new Publisher.Builder(context)
        {
            Capturer = capturerDevices[0].CreateVideoCapturer(VideoCapturer.Resolution.High, VideoCapturer.FrameRate.Fps30);,
            Renderer = PublisherVideo
        }.Build();                                   

        IList<AudioDevice.InputAudioDevice> availableMics = AudioDevice.EnumerateInputAudioDevices();
        if (availableMics == null || availableMics.Count == 0)
            throw new Exception("No audio capture devices detected");
        AudioDevice.SetInputAudioDevice(availableMics[0]);

        Session = new Session.Builder(context, API_KEY, SESSION_ID).Build();
        Session.Connected += Session_Connected;
        Session.Disconnected += Session_Disconnected;
        Session.Error += Session_Error;
        Session.StreamReceived += Session_StreamReceived;
        Session.Connect(TOKEN);

}

Please, try this with 2.24.2 and and check it fixes the error. Apologies for the misdirection.

wesoos commented 1 year ago

Hi Sergio,

That seems to have fixed it. Now I have found a different issue with new release. My process to make the video calls happens in a new window in WPF every time.

When the window loads and a call is made, I instantiate a new instance of Context, Publisher, Subscriber, and Session.

When the window closes, I call Dispose() on Subscriber, Publisher, Session, Context. In that order.

The issue is, the first time I open the window and handle a video call, and then close the window, all works fine. The second time, the app crashes when I close the window with the following:

An unhandled exception of type 'System.NullReferenceException' occurred in OpenTokNetStandard.dll

Object reference not set to an instance of an object.

If I don’t call Dispose() on the objects above, the app does not crash, however the windows process hangs. It never ends…

Any ideas?

Thanks

sergioturgil-vonage commented 1 year ago

Yes race conditions when disposing objects is a known issue fixed in upcoming 2.25.0 which will be out in a few days.

I can't promise that's the exact problem you're experiencing but we've definitely handled a several issues like the one you described (it could happen with any of those objects).

Dispose() is definitely the way to go since there are several native resources associated with each of those objects.

If the issue persists after 2.25.0 please let me know asap and we can investigate it further.

Thanks!

wesoos commented 1 year ago

Thanks Sergio, do you have an ETA on 2.25?

sergioturgil-vonage commented 1 year ago

No dates, sorry. We're currently finalizing some details. It should be going out any day now.

v-kpheng commented 1 year ago

@wesoos, 2.25.0 has been released. @sergioturgil-vonage, does 2.25.0 have the fixes @wesoos needed? Or, did it get pushed back to 2.25.x?

sergioturgil-vonage commented 1 year ago

@wesoos, 2.25.0 has been released. @sergioturgil-vonage, does 2.25.0 have the fixes @wesoos needed? Or, did it get pushed back to 2.25.x?

Yes, the fixes are there. Please @wesoos let us know if it solves your problem. Thx!

wesoos commented 1 year ago

Hi, yes it seems it solves the issues. I am still creating the publisher first before pulling list of available MICs. Is that still something needed?

Thanks

sergioturgil-vonage commented 1 year ago

Hi, yes it seems it solves the issues. I am still creating the publisher first before pulling list of available MICs. Is that still something needed? Thanks

Yes. If using the default audio module you will still need to do it that way.

2.25 introduces a new custom audio device that can be used instead of the default audio module. It works better if you want to use audio notifications and integrate with OS audio settings. For this second option I will update a related windows sample in the repo very soon. I'll let you know when I do it.

(To clarify, by audio notifications I mean subscribing to events that inform of new devices connected, devices removed or default device selection changes).