@eatsjobs/media-mock
v1.2.0
Published
Media-Mock is a JavaScript library that simulates media devices (like webcams) in web applications, allowing developers to test and debug media constraints, device configurations, and stream functionality without needing physical devices. This is particul
Maintainers
Readme
@eatsjobs/media-mock
Media-Mock is a JavaScript library that simulates media devices (like webcams) in web applications, allowing developers to test and debug media constraints, device configurations, and stream functionality without needing physical devices. This is particularly useful in scenarios where hardware or user permissions aren't available or desired, such as in automated testing environments.
Can also be used as browser extension please have a look at this repo https://github.com/eatsjobs/media-mock-extension
Table of Contents
Key Features
- Device Simulation: Simulate configurations for various devices like iPhone, desktop, or custom configurations.
- Constraint Support: Set custom video constraints such as resolution, frame rate, and more.
- Canvas-based Mock Stream: Use an image as a video input source and capture it as a canvas stream.
- Debug Mode: Visualize the mock stream by displaying the canvas and image in the DOM.
- Easy Integration with Testing: Ideal for testing media applications with tools like Vitest, Jest or Playwright.
Installation
Install with npm:
npm install @eatsjobs/media-mockInstall with jsr:
npx jsr add @eatsjobs/media-mockUsage
Basic Usage
To start using MediaMock, initialize the library, configure a mock media stream, and then request a stream from navigator.mediaDevices.
import { MediaMock, devices } from "@eatsjobs/media-mock";
// Configure and initialize MediaMock with default settings
MediaMock.mock(devices["iPhone 12"]); // or devices["Samsung Galaxy M53"] for Android, "Mac Desktop" for desktop mediaDevice emulation
await MediaMock.setMediaURL("./assets/640x480-sample.png");
// Set up a video element to display the stream
const videoElement = document.createElement("video");
document.body.appendChild(videoElement);
videoElement.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
videoElement.play();
const enumeratedDevices = await navigator.mediaDevices.enumerateDevices();
const supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
console.log(enumeratedDevices, supportedConstraints);Configuring a Custom Device and Constraints
You can set a specific device and define video constraints such as resolution and frame rate.
MediaMock.mock(devices["Mac Desktop"]);
await MediaMock.setMediaURL("./assets/640x480-sample.png");Configuring Media Load Timeout
You can adjust the timeout for media loading based on your network conditions or test requirements. The default timeout is 60 seconds for both images and videos.
import { MediaMock, devices } from "@eatsjobs/media-mock";
MediaMock.mock(devices["iPhone 12"]);
// Set a custom timeout of 30 seconds (useful for faster tests)
MediaMock.setMediaTimeout(30 * 1000);
await MediaMock.setMediaURL("./assets/640x480-sample.png");
// Or set a longer timeout for slow networks
MediaMock.setMediaTimeout(5 * 60 * 1000); // 5 minutes
await MediaMock.setMediaURL("./assets/video.mp4");
// Method chaining is supported
MediaMock
.setMediaTimeout(45 * 1000)
.setCanvasScaleFactor(0.8);API Documentation
MediaMock
The main class of the library, used to configure, initialize, and manage the mock media devices.
async setMediaURL(path: string): Promise<MediaMock>
Sets a custom image URL or video URL to be used as the source and returns the instance for chaining. This method is now asynchronous to properly handle media loading.
- path:
string- Path to the image or video file.
enableDebugMode(): MediaMock
Enables debug mode, appending the mock canvas and image elements to the DOM for visualization. This allows you to see what's being used as a video feed during tests.
disableDebugMode(): MediaMock
Disables debug mode and removes the mock canvas and image elements from the DOM.
setCanvasScaleFactor(factor: number): MediaMock
Sets the scale factor for the image in the canvas. Lower values create more margin, higher values fill more of the canvas.
- factor:
number- Scale factor between 0.1 and 1.0.
setMediaTimeout(timeoutMs: number): MediaMock
Sets the timeout for media loading (both images and videos) in milliseconds. This allows you to adjust the timeout based on network conditions or test requirements.
- timeoutMs:
number- Timeout in milliseconds. Must be a positive number. Default is 60000 (60 seconds).
addMockDevice(device: MockMediaDeviceInfo): MediaMock
Adds a new mock device to the current device configuration and triggers a devicechange event.
- device:
MockMediaDeviceInfo- The mock device to add.
removeMockDevice(deviceId: string): MediaMock
Removes a mock device by its device ID and triggers a devicechange event.
- deviceId:
string- The ID of the device to remove.
setMockedVideoTracksHandler(handler: (tracks: MediaStreamTrack[]) => MediaStreamTrack[]): MediaMock
Sets a custom handler for the video tracks. The handler is called when the video tracks are created and can be used to modify the tracks programmatically.
- handler:
(tracks: MediaStreamTrack[]) => MediaStreamTrack[]- A function that receives the video tracks and returns the modified tracks.
mock(device: DeviceConfig, options?: MockOptions): MediaMock
Initializes the mock with a specific device configuration and enables specified media device methods for testing.
- device:
DeviceConfig- The device configuration preset to use (e.g.,devices["iPhone 12"]). - options:
MockOptions- An optional configuration to enable specificnavigator.mediaDevicesmethods, such asgetUserMediaandenumerateDevices.
unmock(): MediaMock
Restores original navigator.mediaDevices methods by removing the mock properties and stops any ongoing mock stream. Useful for cleanup after testing.
MockOptions
Defines which navigator.mediaDevices methods should be mocked:
interface MockOptions {
mediaDevices: {
getUserMedia: boolean;
getSupportedConstraints: boolean;
enumerateDevices: boolean;
};
}- mediaDevices.getUserMedia:
boolean- Enablesnavigator.mediaDevices.getUserMedia. - mediaDevices.getSupportedConstraints:
boolean- Enablesnavigator.mediaDevices.getSupportedConstraints. - mediaDevices.enumerateDevices:
boolean- Enablesnavigator.mediaDevices.enumerateDevices.
Settings
Interface that contains the mock settings for media URL, device configuration, and video constraints.
- mediaURL:
string- The URL of the image or video used as the media source. - device:
DeviceConfig- Specifies the configuration for the mock device, such as resolution and media information. - constraints:
MediaTrackConstraints- Specifies video constraints, like resolution and frame rate. - canvasScaleFactor:
number- Scale factor for the image in the canvas (0.1-1.0). - mediaTimeout:
number- Timeout for media loading in milliseconds (default: 60000 = 60 seconds). Applied to both images and videos.
DeviceConfig
Represents configuration settings for mock devices, including available video resolutions and media device information like device ID and group ID. Used in MediaMock.mock() to apply device-specific settings.
interface DeviceConfig {
videoResolutions: { width: number; height: number }[];
mediaDeviceInfo: MockMediaDeviceInfo[];
supportedConstraints: Record<
keyof MediaTrackSupportedConstraints & "torch",
boolean
>;
}
interface MockMediaDeviceInfo extends MediaDeviceInfo {
getCapabilities: () => MediaTrackCapabilities;
}
Debugging
enableDebugMode() appends the canvas and the loaded image used by the canvas to the document.body.
import { MediaMock, devices } from "@eatsjobs/media-mock";
// Configure and initialize MediaMock with default settings
MediaMock
.enableDebugMode()
.mock(devices["iPhone 12"]); // or devices["Samsung Galaxy M53"] for Android, "Mac Desktop" for desktop mediaDevice emulation
await MediaMock.setMediaURL("./assets/640x480-sample.png");
// Set up a video element to display the stream
const videoElement = document.createElement("video");
document.body.appendChild(videoElement);
videoElement.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
videoElement.play();
