Socket
Socket
Sign inDemoInstall

media-devices-util

Package Overview
Dependencies
2
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    media-devices-util

This package exposes and API to work with mac/win media devices (cameras, microphones, screens)


Version published
Weekly downloads
0
Maintainers
1
Created
Weekly downloads
 

Readme

Source

media-devices-util


What is this package for? To get info about available media devices and work with them. You can:

  • list available devices
  • get default devices
  • get audio/video/screen permissions (mac)
  • request for audio/video/screen permissions (mac)

How to use it

Install

npm i -S media-devices-util

Use

Get devices list
const mediaDevicesUtil = require("media-devices-util");

const videoDevices = mediaDevicesUtil.getVideoDevices();
const audioDevices = mediaDevicesUtil.getAudioDevices();

console.log({ audioDevices, videoDevices });

// output on mac:
// {
//     audioDevices: [
//         {
//             id: 'AppleHDAEngineInput:1F,3,0,1,0:1',
//             label: 'Built-in Microphone'
//         }
//     ],
//     videoDevices: [
//         {
//             id: '0x1420000005ac8600',
//             label: 'FaceTime HD Camera (Built-in)'
//         },
//         {
//             id: '69733382',
//             label: 'Capture screen 0'
//         }
//     ]
// }
//
// output on windows:
// {
//     audioDevices: [
//         {
//             id: '0',
//             label: 'Microphone (High Definition Audio Device)',
//             alternativeName: '@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\\wave_{B073E9D3-C0A7-4CB0-84E0-F829B281F95F}'
//         }
//     ],
//     videoDevices: [
//         {
//             id: '\\\\?\\usb#vid_203a&pid_fff9&mi_00#6&fafa70b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global',
//             label: 'FaceTime HD Camera (Built-in)'',
//             alternativeName: '@device_pnp_\\\\?\\usb#vid_203a&pid_fff9&mi_00#6&fafa70b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global'
//         }
//     ]
// }
Request for Camera permissions
const mediaDevicesUtil = require("media-devices-util");

mediaDevicesUtil.requestMediaAuthorization("camera").then((status) => {
  if ("AUTHORIZED" === status) {
    // permissions granted!
  }
});

API

media-devices-util object has the following API:

type TDevice = {
  // For mac:
  // audio/video devices are using the 'uniqueID' property - https://developer.apple.com/documentation/avfoundation/avcapturedevice/1390477-uniqueid
  // screen devices are using the 'CGDirectDisplayID' property - https://developer.apple.com/documentation/coregraphics/cgdirectdisplayid
  // For win:
  // audio devices are using the 'WaveInID' property - https://docs.microsoft.com/en-us/windows/win32/directshow/selecting-a-capture-device
  // video devices are using the 'DevicePath' property - https://docs.microsoft.com/en-us/windows/win32/directshow/selecting-a-capture-device
  id: string;

  // For mac:
  // audio/video devices are using the 'localizedName' property - https://developer.apple.com/documentation/avfoundation/avcapturedevice/1388222-localizedname
  // screen devices are using the 'Capture screen ' prefix plus device id in 'CGGetActiveDisplayList' - https://developer.apple.com/documentation/coregraphics/1454603-cggetactivedisplaylist
  // For win:
  // using the 'FriendlyName' property - https://docs.microsoft.com/en-us/windows/win32/directshow/selecting-a-capture-device
  label: string;

  // For win:
  // using the 'GetDisplayName' method's return value - https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-imoniker-getdisplayname
  alternativeName?: string;
}

// AUTHORIZED - permissions granted
// DENIED - permissions denied
// NOT_DETERMINED - permissions not set
declare type TAuthorization = "AUTHORIZED" | "DENIED" | "NOT_DETERMINED";

declare type TMediaType = "camera" | "microphone";

type TMediaDevicesUtil = {
    getDefaultVideoDevice(): TDevice;
    getDefaultAudioDevice(): TDevice;
    getVideoDevices(): TDevice[];
    getAudioDevices(): TDevice[];
    getScreenAuthorizationStatus(): TAuthorization;
    getMediaAuthorizationStatus(mediaType: TMediaType): TAuthorization;
    getMediaAuthorizationStatus(): {
        camera: TAuthorization;
        microphone: TAuthorization;
    };
    requestScreenAuthorization(): TAuthorization;
    requestMediaAuthorization(mediaType: TMediaType): Promise<TAuthorization>;
}
getDefaultVideoDevice

Return type: TDevice

Retrieve the default video input device (camera).

For win, taking the first entry of the IEnumMoniker with the CLSID_VideoInputDeviceCategory parameter.

For mac, using the defaultDeviceWithMediaType:AVMediaTypeVideo method for audio/video devices.

getDefaultAudioDevice

Return type: TDevice

Retrieve the default audio input device (microphone).

For win, using the GetDefaultAudioEndpoint method.

For mac, using the defaultDeviceWithMediaType:AVMediaTypeAudio method.

getVideoDevices

Return type: TDevice[]

Retrieve the default video input devices list (cameras, screens, etc.).

For mac, using the devicesWithMediaType:AVMediaTypeVideo method, and the CGGetActiveDisplayList method for screens.

For win, using the IEnumMoniker with the CLSID_VideoInputDeviceCategory parameter.

getAudioDevices

Return type: TDevice[]

Retrieve the default audio input devices list (microphones, virtual devices, etc.).

For mac, using the devicesWithMediaType:AVMediaTypeAudio method.

For win, using the IEnumMoniker with the CLSID_AudioInputDeviceCategory parameter.

getScreenAuthorizationStatus

Return type: TAuthorization

Retrieve current permissions for screen recording.

For mac, using the CGPreflightScreenCaptureAccess method (>=11.0), or will try to match window processes ids (>=10.15), or will return AUTHORIZED.

For win, will always return AUTHORIZED.

getMediaAuthorizationStatus

Return type: TAuthorization | { camera: TAuthorization; microphone: TAuthorization; }

Arguments: (mediaType?: TMediaType)

Retrieve current permissions for audio and/or video usage. If no args passed - will return authorization status for both audio/video.

For mac, using the authorizationStatusForMediaType method.

For win, will always return AUTHORIZED for any type of media.

requestScreenAuthorization

Return type: TAuthorization

Request for screen recording permissions. Will prompt user to modify screen recording permissions config, if possible, otherwise - will open the System Preferences window with Screen Recording tab opened.

For mac, using the CGRequestScreenCaptureAccess method (>=11.0), or will try to use CGDisplayStreamCreate method (>=10.15), or will return AUTHORIZED.

For win, will always return AUTHORIZED.

requestMediaAuthorization

Return type: Promise<TAuthorization>

Arguments: (mediaType: TMediaType)

Request for microphone or camera recording permissions. Will prompt user to modify screen recording permissions config, if possible, otherwise - will open the System Preferences window with Camera or Microphone tab opened.

For mac, using the requestAccessForMediaType method (>=10.14), or will return AUTHORIZED.

For win, will always return AUTHORIZED for any type of media.

FFMPEG

When using an ffmpeg or other libs to capture audio/video devices, you first need to obtain a list of available devices and their labels (IDs).

And when running ffmpeg to just get the devices list - it takes too long, because a lot of overhead ffmpeg lib actions are taken.

Using media-devices-util is much, much faster.

Usage example

Let's imagine, that we want to capture the default audio and default video device with ffmpeg:

const spawn = require("child_process").spawn;
const mediaDevicesUtil = require("media-devices-util");

const defaultVideoDevice = mediaDevicesUtil.getDefaultVideoDevice();
const defaultAudioDevice = mediaDevicesUtil.getDefaultAudioDevice();

// for MacOS, you can use the 'label' prop, and the item's index (if used with getVideoDevices/getAudioDevices):
const ffmpegWinProcess = spawn("ffmpeg", ["-f", "avfoundation", "-i", `${defaultVideoDevice.label}:${defaultAudioDevice.label}`, "video.mkv"]);

// for Windows, you should use the 'label' or the 'alternativeName' prop:
const ffmpegMacProcess = spawn("ffmpeg", ["-f", "dshow", "-i", `video="${defaultVideoDevice.label}":audio="${defaultAudioDevice.alternativeName}"`, "video.mkv"]);

Alternatives

You can use the ffmpeg's list_devices option (for mac or win), and parse it's output to get the list itself.

Also, you can use other ffmpeg command abstractions (like ffmpeg and fluent-ffmpeg).

In any case, the list_devices in ffmpeg lib is something like a crunch, and the lib itself doesn't provide a programmatic way to enumerate devices.

Or use other ffmpeg nodejs bindings lib.

Next Steps

  • Improve Windows API (especially permissions), if possible
  • Add listeners for devices and/or permissions

License

MIT License

Keywords

FAQs

Last updated on 30 Nov 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc