NAudio
NAudio copied to clipboard
Capture specific process with WasapiLoopbackCapture
Hello,
I would like to use NAudio WasapiLoopbackCapture with the new possibility of capture loopback audio from (or excluding) a specific process. This requires Win 10 20348 or later.
There is a new initialization structure of the ActivateAudioInterfaceAsync Win32 API that allows you to pass a process to be included or excluded (and it's children).
I have been playing with the sample code on the docs and it's working OK but I would like to use it from my .Net apps that use NAudio. It would be a very good opportunity for audio apps. https://docs.microsoft.com/en-us/samples/microsoft/windows-classic-samples/applicationloopbackaudio-sample/
AUDIOCLIENT_ACTIVATION_PARAMS audioclientActivationParams = {};
audioclientActivationParams.ActivationType = AUDIOCLIENT_ACTIVATION_TYPE_PROCESS_LOOPBACK;
audioclientActivationParams.ProcessLoopbackParams.ProcessLoopbackMode = includeProcessTree ?
PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE : PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE;
audioclientActivationParams.ProcessLoopbackParams.TargetProcessId = processId;
PROPVARIANT activateParams = {};
activateParams.vt = VT_BLOB;
activateParams.blob.cbSize = sizeof(audioclientActivationParams);
activateParams.blob.pBlobData = (BYTE*)&audioclientActivationParams;
wil::com_ptr_nothrow<IActivateAudioInterfaceAsyncOperation> asyncOp;
RETURN_IF_FAILED(ActivateAudioInterfaceAsync(VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK, __uuidof(IAudioClient),
&activateParams, this, &asyncOp));
// Wait for activation completion
m_hActivateCompleted.wait();
Thanks.
This is really cool. I don't have much time for working on NAudio these days but I'd love to get this in. Will have to find some time for experimenting with it
I gave this a good try, but something isn't quite working. I think I'm close, but the IAudioClient I end up creating fails with weird COM errors. Here's what I tried: https://github.com/naudio/NAudio/commit/446096a0495950342a3594bb57bea00bfdbad44e
someone did a c# version of that Microsoft sample about AUDIOCLIENT_ACTIVATION_PARAMS or ApplicationLoopback. and it's kind of working.. but yeah it's friendly to have it built inside naudio best library ever.
https://github.com/ShortDevelopment/VB-Audio-Router/blob/main/VBAudioRouter.Capture/ProcessAudioCapture.cs
I'd discover that IActivateAudioInterfaceAsyncOperation::GetActivateResult only returns IAudioClient but not IAudioClient2 or IAudioClient3. Calls on the latter always return E_NOINTERFACE or E_NOT_IMPLEMENTED when calling methods like IsFormatSupported or GetDevicePeriod etc. On samples that are using IMMDevice, those interfaces and methods are working as expected. Why is that?
It seems that IAudioClient.GetMixFormat() and IsFormatSupported() are not supported on this scenario and we should use hardcoded format as in the Microsoft example. This is an answer from Microsoft. https://learn.microsoft.com/en-us/answers/questions/1125409/loopbackcapture-(-activateaudiointerfaceasync-with
This is an issue of win-capture-audio plugin C++ implementation https://github.com/bozbez/win-capture-audio/issues/14
I have been trying to port the Microsoft C++ Sample to C# but I had no luck because I don´t know how to Pinvoke/port the WIL library that they are using. I think everything should work if the calls to native methods from C# are done in the same way. I hope that someone can help on this task to finally make it available in NAudio.
At the moment, I have made a tiny wrapper dll to call StartCapture
and StopCapture
of their class, to test it from C#.
The code is here:
https://github.com/joseluisct/AppLoopback