- self-taught programer
- 7+ years of experience
- currently at French IT school of Epita (2026)
m1dugh / native-sound-mixer Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Writes proper documentation:
README.md
to github pages siteCONTRIBUTING.md
fileC++
API for contributors.C++
docs to github pages at /contributors
add basic CI/CD for push:
add basic CI/CD for push on master:
Hi @m1dugh,
are you interested in me making a PR to add @Julusian's excellent pkg-prebuilds
tooling?
This would add a GitHub Action which would build the prebuild binaries on Windows and Linux for amd64 (maybe also amd64).
Then, you could ship those directly in the pakage published on npm. This has the benefit of not requiring users to have a working node-gyp build environment as well as easy cross-compilation (as in fact no compilation should be needed when installing the lib).
Let me know what you think.
@m1dugh Hello sir!
Currently, I'm working on electron project where we need to control app audio session for some features, but when i tried to install your package via npm I receive an error like this:
From the message I can see that error point out to CMake, is it necessary to have the software to be installed on developer machine to proceed using the package, or I can fix it in other way?
Thank you ๐
Hi, first of all thank you for this very useful project :)
I think I have found a bug in the source code which causes a null pointer dereference:
device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,
(LPVOID *)&endpointVolume);
if (device_cb == NULL)
device_cb = new SoundMixerAudioEndpointVolumeCallback(this);
endpointVolume->RegisterControlChangeNotify(device_cb);
return true;
From: https://github.com/m1dugh/native-sound-mixer/blob/master/cppsrc/win/win-sound-mixer.cpp#L308-L315
According to https://learn.microsoft.com/en-us/windows/win32/api/mmdeviceapi/nf-mmdeviceapi-immdevice-activate the endpointVolume
could be NULL when the Activate
call fails. However, the return value is not checked and later endpointVolume->RegisterControlChangeNotify(device_cb);
is done. When endpointVolume
is NULL, this causes a null pointer dereference.
I have no test case to reproduce this behavior because I am only seeing this from production users by collecting crashes. In case it might be useful for you, here is a snippet of the native crash dump:
EXCEPTION_ACCESS_VIOLATION_READ: Attempted to dereference null pointer.
0 win-sound-mixer.node +0xeaab 0xeaab
r10 = 0x5555555555555555 rbp = 0x1b5a0af79f0
r11 = 0xaaaa88a8c00aa2aa rbx = 0x1b5a0a54d70
r12 = 0x1b5a0ade5e0 rcx = 0x0
r13 = 0x497fffc3b8 rdi = 0x1b5a0a54d00
r14 = 0x1b55d6b4250 rdx = 0x1b55d681b70
r15 = 0x0 rip = 0x7ffb654aeaab
r8 = 0x0 rsi = 0x1b5a0a54d18
r9 = 0x555577573ff55d55 rsp = 0x497fffc110
rax = 0x7ffb654cdbe0
1 win-sound-mixer.node +0xc95b 0xc95c
2 ntdll.dll +0x3dca4 0x3dca5
3 win-sound-mixer.node +0x10beb 0x10bec
4 win-sound-mixer.node +0xe056 0xe057
5 win-sound-mixer.node +0x728b 0x728c
6 win-sound-mixer.node +0x31fd 0x31fe
7 win-sound-mixer.node +0x2767 0x2768
This is the instruction on where it fails: mov rax, [rcx]
. You can clearly see that rcx
is set to 0x0 which being dereferenced.
I don't know the code well enough to know how to handle this case. Do you maybe now why Activate
could fail?
When I try to change the volume for an application (ex. Chrome), the volume in volume mixer only changes if Chrome is actively playing audio. If the audio (in Chrome) is paused or stopped, the slider in volume mixer won't change when I try to adjust volume with this node package.
Is it possible to allow volume changes even if there is no audio playing? (but there previously was, so the session still exists)
Hello, thank you for this great project.
I'm facing a big problem with memory usage,
when I use simple code like that
setInterval(function(){
const d = SoundMixer.devices.filter( dz => dz.type == DeviceType.RENDER);
}, 1);
it get devices based on my filter and store it in variable d
every 1ms
but every time the loop get devices it increase app memory usage.
I tried a lot to insure that's not my code issue.
you can test above code and in less than 5 min the memory usage will be above 1GB !!!!
Hi there - bit off topic here but would love to build this for nwjs.
I'm trying to build using prebuild. Bit baffled really!
Any help would be well appreciated.
Thanks
Is it possible to add in the control of per app audio panning (to the left or right channel) by scripts? This is highly appreciated!
First of all, thank you for the work you have done.
I'm not sure if I'm doing something wrong or not but I don't get this package to work.
I'm using this package inside electron (with React) so I should be able to use native node.js packages in the main process. When I add the package with yarn, the folder /node_modules/native-sound-mixer/dist does only contain SoundMixer.node, no javascript files.
I'm unable to import anything because this dist folder is empty. What am i missing here?
Hello, first of all thank you for making this project, it's a pretty interesting idea for a native node project.
I ran into this issue while I was trying to list the devices with this simple code:
import SoundMixer, { Device } from 'native-sound-mixer';
const getAudioDevices = async () => {
const devices: Device[] | undefined = SoundMixer.devices;
return devices;
};
export { getAudioDevices };
I'm currently using electron and using this function on the main thread.
This is the error stack trace:
App threw an error during load
Error: Cannot find module '...\node_modules\native-sound-mixer\dist/addons/win-sound-mixer.node'
Require stack:
- ...\node_modules\native-sound-mixer\dist\sound-mixer.js
- ...\electron-main.js
-...\electron\dist\resources\default_app.asar\main.js
-
at Module._resolveFilename (node:internal/modules/cjs/loader:1082:15)
at n._resolveFilename (node:electron/js2c/browser_init:2:117457)
at Module._load (node:internal/modules/cjs/loader:927:27)
at f._load (node:electron/js2c/asar_bundle:2:13330)
at Module.require (node:internal/modules/cjs/loader:1148:19)
at require (node:internal/modules/cjs/helpers:110:18)
at getModule (...r\node_modules\native-sound-mixer\dist\sound-mixer.js:34:19)
at ...\node_modules\native-sound-mixer\dist\sound-mixer.js:42:20
at Object.<anonymous> (...r\node_modules\native-sound-mixer\dist\sound-mixer.js:50:3)
at Module._compile (node:internal/modules/cjs/loader:1269:14)
I'm currently using Node v18.16.1
The path does not seem to be wrong at all as I can access it on my window explorer, is there something I'm missing?
Just wanted to know what your thoughts are on supporting macOS. I've done a lot of research about per-application volume control on macOS but it seems a really difficult task. It might require some sort of virtual device or special driver...
I noticed you just finished Linux support. What are your thoughts on macOS support? Do you already have a plan how you would do this? I'm happy to help in any way but I'm not a C++ or macOS developer.. (I do mostly javascript) I only did a lot of reading about this topic :)
macOS support would be awesome since there are no good solutions as far as I know.
Hi @m1dugh,
first of all, thanks for this library. It's working great.
Do you think it is possible to add a feature to be able to subscribe to changes of Volume / Mute?
The Device class could become an EventEmitter
and emit mute
or volumeChanged
Events.
Hi,
I couldn't find any info on whether this is compatible with the Memory Cage of Electron 21+. Is it?
I just don't want to risk that it works on my machine and users of my application are doing something differently and it crashes for them.
Hi, I wasn't able to get this module (from npm and from the master
branch) working on my machine (Node v16.2.0 x86 on Windows).
I noted that
const { arch } = require('os');
console.log(arch());
is printing 'ia32' on my machine (instead of the 'x32' expected by this module).
An easy fix would be to replace this line
native-sound-mixer/src/sound-mixer.ts
Line 8 in fede9f9
with
if (arch() === "x32" || arch() === "x64" || arch() === "ia32") {
With this patch the module works fine.
In Windows, when zoom was launched for a meeting, there will be two audio sessions which can be viewed from the volume mixer, namely Zoom/Zoom Cloud Meetings, and Zoom Meetings/Zoom Meetings- 40minutes (for free user when it is close to session time limit), however, the session that can be captured is only zoom.exe from C:\Users\xxx\AppData\Roaming\Zoom\bin, but both audio sessions. The result is if anyone is lucky and stars are aligned, then Zoom Meetings thread can be control from this plug-in, but otherwise it would have no control. The audio comes from the later - Zoom Meetings session only. Any idea on how to resolve this? @m1dugh Thanks!
Hi, when trying to use this lib on a Windows 10 machine, my application crashed with the following error:
FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place
1: 00007FF6A265B34F v8::internal::CodeObjectRegistry::~CodeObjectRegistry+123599
2: 00007FF6A25E8CB6 v8::internal::MicrotaskQueue::GetMicrotasksScopeDepth+65206
3: 00007FF6A25E9D8D node::OnFatalError+301
4: 00007FF6A2F10A0B v8::HandleScope::Initialize+107
5: 00007FF6A2EFAFF1 v8::EscapableHandleScope::EscapableHandleScope+81
6: 00007FF6A262CC78 napi_open_escapable_handle_scope+120
7: 00007FF9CA33280D Napi::FunctionReference::New+61 [A:\_Source\native-sound-mixer\node_modules\node-addon-api\napi-inl.h]:L3370
8: 00007FF9CA333663 SoundMixer::DeviceObject::New+83 [A:\_Source\native-sound-mixer\cppsrc\win\sound-mixer.cpp]:L83
9: 00007FF9CA333465 SoundMixer::MixerObject::GetDevices+341 [A:\_Source\native-sound-mixer\cppsrc\win\sound-mixer.cpp]:L4710: 00007FF9CA336A3E Napi::details::WrapCallback<<lambda_2d6a469e53703925d71c48cc7e420a87> >+46 [A:\_Source\native-sound-mixer\node_modules\node-addon-api\napi-inl.h]:L75
11: 00007FF9CA335F58 Napi::details::TemplatedCallback<&SoundMixer::MixerObject::GetDevices>+40 [A:\_Source\native-sound-mixer\node_modules\node-addon-api\napi-inl.h]:L153
12: 00007FF6A262564B node::Stop+32747
13: 00007FF6A2F3E74F v8::internal::SetupIsolateDelegate::SetupHeap+53823
14: 00007FF6A2F6FAE9 v8::internal::SetupIsolateDelegate::SetupHeap+255449
15: 000002D94CCBDBBE
Any idea?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.