react-media-manager 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/index.d.mts +171 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +1102 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1091 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 arunkumarbrahmaniyaa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# react-media-manager
|
|
2
|
+
|
|
3
|
+
Production-ready React hooks for cameras, microphones, speakers, permissions, device changes, and recording. The package is SSR-safe, tree-shakeable, TypeScript-first, and built for React 18+ applications across Next.js, Vite, CRA, Remix, and plain React setups.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Camera, microphone, and speaker device enumeration
|
|
8
|
+
- Stream lifecycle management with start, stop, pause, resume, mute, and unmute flows
|
|
9
|
+
- Permission querying and permission request helpers
|
|
10
|
+
- Automatic device-change detection
|
|
11
|
+
- Audio output switching through `setSinkId` when supported
|
|
12
|
+
- Optional media recording hook
|
|
13
|
+
- Human-readable normalized media errors
|
|
14
|
+
- TypeScript declarations for all public hooks and device models
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install react-media-manager
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Peer dependencies:
|
|
23
|
+
|
|
24
|
+
- `react >= 18`
|
|
25
|
+
- `react-dom >= 18`
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { useCamera } from 'react-media-manager';
|
|
31
|
+
|
|
32
|
+
export function CameraPreview() {
|
|
33
|
+
const { cameras, currentCamera, stream, isActive, error, start, stop, switchCamera } = useCamera();
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div>
|
|
37
|
+
<button onClick={() => void start()} disabled={isActive}>
|
|
38
|
+
Start camera
|
|
39
|
+
</button>
|
|
40
|
+
<button onClick={stop} disabled={!isActive}>
|
|
41
|
+
Stop camera
|
|
42
|
+
</button>
|
|
43
|
+
<select
|
|
44
|
+
value={currentCamera?.deviceId ?? ''}
|
|
45
|
+
onChange={(event) => void switchCamera(event.target.value)}
|
|
46
|
+
>
|
|
47
|
+
{cameras.map((camera) => (
|
|
48
|
+
<option key={camera.deviceId} value={camera.deviceId}>
|
|
49
|
+
{camera.label || camera.deviceId}
|
|
50
|
+
</option>
|
|
51
|
+
))}
|
|
52
|
+
</select>
|
|
53
|
+
{stream && <video autoPlay muted playsInline ref={(node) => node && (node.srcObject = stream)} />}
|
|
54
|
+
{error && <p>{error.message}</p>}
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API Overview
|
|
61
|
+
|
|
62
|
+
### `useCamera(options?)`
|
|
63
|
+
|
|
64
|
+
Returns camera devices, the active stream, camera status, permission state, and camera controls.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
const {
|
|
68
|
+
cameras,
|
|
69
|
+
currentCamera,
|
|
70
|
+
stream,
|
|
71
|
+
isActive,
|
|
72
|
+
isLoading,
|
|
73
|
+
isPaused,
|
|
74
|
+
permission,
|
|
75
|
+
status,
|
|
76
|
+
error,
|
|
77
|
+
start,
|
|
78
|
+
stop,
|
|
79
|
+
pause,
|
|
80
|
+
resume,
|
|
81
|
+
switchCamera,
|
|
82
|
+
refreshDevices,
|
|
83
|
+
refresh,
|
|
84
|
+
destroy,
|
|
85
|
+
} = useCamera();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `useMicrophone(options?)`
|
|
89
|
+
|
|
90
|
+
Returns microphone devices, audio stream state, mute state, and live volume level monitoring when supported.
|
|
91
|
+
|
|
92
|
+
### `useSpeaker(target)`
|
|
93
|
+
|
|
94
|
+
Returns output devices and a `switchSpeaker` helper for `HTMLMediaElement.setSinkId` capable browsers.
|
|
95
|
+
|
|
96
|
+
### `usePermissions()`
|
|
97
|
+
|
|
98
|
+
Returns live camera and microphone permission state plus `requestCamera`, `requestMicrophone`, and `requestAll` helpers.
|
|
99
|
+
|
|
100
|
+
### `useMediaDevices(options?)`
|
|
101
|
+
|
|
102
|
+
Returns grouped device lists and a refresh method.
|
|
103
|
+
|
|
104
|
+
### `useDeviceChange()`
|
|
105
|
+
|
|
106
|
+
Returns refreshed devices plus `changeCount` and `lastChangeAt` each time `navigator.mediaDevices.devicechange` fires.
|
|
107
|
+
|
|
108
|
+
### `useMediaRecorder()`
|
|
109
|
+
|
|
110
|
+
Returns recorder lifecycle helpers, chunk data, final `Blob`, object URL, and download support.
|
|
111
|
+
|
|
112
|
+
### `MediaProvider`
|
|
113
|
+
|
|
114
|
+
Provides shared defaults:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<MediaProvider
|
|
118
|
+
value={{
|
|
119
|
+
autoRefreshOnDeviceChange: true,
|
|
120
|
+
cameraConstraints: { width: 1280, height: 720 },
|
|
121
|
+
microphoneConstraints: { echoCancellation: true },
|
|
122
|
+
monitorMicrophoneVolume: true,
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
<App />
|
|
126
|
+
</MediaProvider>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## TypeScript
|
|
130
|
+
|
|
131
|
+
Public types include:
|
|
132
|
+
|
|
133
|
+
- `CameraDevice`
|
|
134
|
+
- `MicrophoneDevice`
|
|
135
|
+
- `SpeakerDevice`
|
|
136
|
+
- `MediaPermissionState`
|
|
137
|
+
- `MediaError`
|
|
138
|
+
- `MediaConstraints`
|
|
139
|
+
|
|
140
|
+
## Browser Support
|
|
141
|
+
|
|
142
|
+
- Chrome: supported
|
|
143
|
+
- Edge: supported
|
|
144
|
+
- Firefox: supported, with browser-specific output-device limitations
|
|
145
|
+
- Safari: supported for core camera and microphone hooks, with limited output-device support
|
|
146
|
+
- Brave: supported
|
|
147
|
+
|
|
148
|
+
The library degrades gracefully when `MediaDevices`, `Permissions`, `MediaRecorder`, or `setSinkId` are not available.
|
|
149
|
+
|
|
150
|
+
## Errors
|
|
151
|
+
|
|
152
|
+
Errors are normalized into a consistent shape:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
type MediaError = {
|
|
156
|
+
code:
|
|
157
|
+
| 'abort'
|
|
158
|
+
| 'browser-not-supported'
|
|
159
|
+
| 'device-in-use'
|
|
160
|
+
| 'device-not-found'
|
|
161
|
+
| 'invalid-state'
|
|
162
|
+
| 'not-allowed'
|
|
163
|
+
| 'not-readable'
|
|
164
|
+
| 'overconstrained'
|
|
165
|
+
| 'permission-denied'
|
|
166
|
+
| 'permission-query-failed'
|
|
167
|
+
| 'recorder-not-supported'
|
|
168
|
+
| 'speaker-not-supported'
|
|
169
|
+
| 'unknown';
|
|
170
|
+
message: string;
|
|
171
|
+
cause?: unknown;
|
|
172
|
+
name?: string;
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Development
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npm install
|
|
180
|
+
npm run build
|
|
181
|
+
npm test
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Current local validation:
|
|
185
|
+
|
|
186
|
+
- Build: passes with `tsup`
|
|
187
|
+
- Tests: 16 passing
|
|
188
|
+
- Coverage: 90.87% statements, 90.87% lines, 91.2% functions
|
|
189
|
+
|
|
190
|
+
## Examples and Docs
|
|
191
|
+
|
|
192
|
+
- JavaScript example: `examples/js-example/App.jsx`
|
|
193
|
+
- TypeScript example: `examples/ts-example/App.tsx`
|
|
194
|
+
- Next.js example notes: `docs/nextjs.md`
|
|
195
|
+
- Troubleshooting and FAQ: `docs/troubleshooting.md`
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
interface MediaProviderConfig {
|
|
4
|
+
autoRefreshOnDeviceChange?: boolean;
|
|
5
|
+
cameraConstraints?: MediaTrackConstraints;
|
|
6
|
+
microphoneConstraints?: MediaTrackConstraints;
|
|
7
|
+
monitorMicrophoneVolume?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface MediaProviderProps {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
value?: MediaProviderConfig;
|
|
12
|
+
}
|
|
13
|
+
declare function MediaProvider({ children, value }: MediaProviderProps): React.JSX.Element;
|
|
14
|
+
declare function useMediaProviderConfig(): Required<MediaProviderConfig>;
|
|
15
|
+
|
|
16
|
+
type HookPermissionState = PermissionState | 'unsupported' | 'unknown';
|
|
17
|
+
type MediaPermissionState = HookPermissionState;
|
|
18
|
+
type MediaDeviceCategory = 'camera' | 'microphone' | 'speaker';
|
|
19
|
+
type MediaStatus = 'idle' | 'loading' | 'active' | 'paused' | 'stopped' | 'error';
|
|
20
|
+
type MediaErrorCode = 'abort' | 'browser-not-supported' | 'device-in-use' | 'device-not-found' | 'invalid-state' | 'not-allowed' | 'not-readable' | 'overconstrained' | 'permission-denied' | 'permission-query-failed' | 'recorder-not-supported' | 'speaker-not-supported' | 'unknown';
|
|
21
|
+
interface MediaError {
|
|
22
|
+
code: MediaErrorCode;
|
|
23
|
+
message: string;
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
name?: string;
|
|
26
|
+
}
|
|
27
|
+
interface BaseMediaDevice<TKind extends MediaDeviceCategory = MediaDeviceCategory> {
|
|
28
|
+
deviceId: string;
|
|
29
|
+
groupId: string;
|
|
30
|
+
kind: TKind;
|
|
31
|
+
label: string;
|
|
32
|
+
raw: MediaDeviceInfo;
|
|
33
|
+
}
|
|
34
|
+
interface DeviceCollection {
|
|
35
|
+
cameras: BaseMediaDevice<'camera'>[];
|
|
36
|
+
microphones: BaseMediaDevice<'microphone'>[];
|
|
37
|
+
speakers: BaseMediaDevice<'speaker'>[];
|
|
38
|
+
}
|
|
39
|
+
interface BaseHookResult {
|
|
40
|
+
loading: boolean;
|
|
41
|
+
error: MediaError | null;
|
|
42
|
+
supported: boolean;
|
|
43
|
+
refresh: () => Promise<void>;
|
|
44
|
+
destroy: () => void;
|
|
45
|
+
}
|
|
46
|
+
interface MediaConstraints {
|
|
47
|
+
audio?: boolean | MediaTrackConstraints;
|
|
48
|
+
video?: boolean | MediaTrackConstraints;
|
|
49
|
+
}
|
|
50
|
+
interface MediaDevicesHookResult extends BaseHookResult, DeviceCollection {
|
|
51
|
+
devices: BaseMediaDevice[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface CameraDevice extends BaseMediaDevice<'camera'> {
|
|
55
|
+
facingMode?: 'user' | 'environment';
|
|
56
|
+
}
|
|
57
|
+
interface UseCameraOptions {
|
|
58
|
+
autoStart?: boolean;
|
|
59
|
+
deviceId?: string;
|
|
60
|
+
constraints?: MediaTrackConstraints;
|
|
61
|
+
facingMode?: 'user' | 'environment';
|
|
62
|
+
}
|
|
63
|
+
interface UseCameraResult extends BaseHookResult {
|
|
64
|
+
cameras: CameraDevice[];
|
|
65
|
+
constraints: MediaTrackConstraints;
|
|
66
|
+
currentCamera: CameraDevice | null;
|
|
67
|
+
isActive: boolean;
|
|
68
|
+
isLoading: boolean;
|
|
69
|
+
isPaused: boolean;
|
|
70
|
+
permission: HookPermissionState;
|
|
71
|
+
status: MediaStatus;
|
|
72
|
+
stream: MediaStream | null;
|
|
73
|
+
pause: () => void;
|
|
74
|
+
refreshDevices: () => Promise<void>;
|
|
75
|
+
resume: () => void;
|
|
76
|
+
start: (override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
77
|
+
stop: () => void;
|
|
78
|
+
switchCamera: (deviceId: string, override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare function useCamera(options?: UseCameraOptions): UseCameraResult;
|
|
82
|
+
|
|
83
|
+
interface UseMediaDevicesOptions {
|
|
84
|
+
listen?: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function useMediaDevices(options?: UseMediaDevicesOptions): MediaDevicesHookResult;
|
|
87
|
+
|
|
88
|
+
interface DeviceChangeHookResult {
|
|
89
|
+
cameras: ReturnType<typeof useMediaDevices>['cameras'];
|
|
90
|
+
changeCount: number;
|
|
91
|
+
destroy: ReturnType<typeof useMediaDevices>['destroy'];
|
|
92
|
+
devices: ReturnType<typeof useMediaDevices>['devices'];
|
|
93
|
+
error: ReturnType<typeof useMediaDevices>['error'];
|
|
94
|
+
lastChangeAt: number | null;
|
|
95
|
+
loading: boolean;
|
|
96
|
+
microphones: ReturnType<typeof useMediaDevices>['microphones'];
|
|
97
|
+
refresh: ReturnType<typeof useMediaDevices>['refresh'];
|
|
98
|
+
speakers: ReturnType<typeof useMediaDevices>['speakers'];
|
|
99
|
+
supported: boolean;
|
|
100
|
+
}
|
|
101
|
+
declare function useDeviceChange(): DeviceChangeHookResult;
|
|
102
|
+
|
|
103
|
+
interface UseMediaRecorderResult extends BaseHookResult {
|
|
104
|
+
blob: Blob | null;
|
|
105
|
+
chunks: Blob[];
|
|
106
|
+
isPaused: boolean;
|
|
107
|
+
isRecording: boolean;
|
|
108
|
+
start: (stream: MediaStream, options?: MediaRecorderOptions) => void;
|
|
109
|
+
status: MediaStatus;
|
|
110
|
+
stop: () => void;
|
|
111
|
+
pause: () => void;
|
|
112
|
+
resume: () => void;
|
|
113
|
+
reset: () => void;
|
|
114
|
+
download: (fileName?: string) => string | null;
|
|
115
|
+
url: string | null;
|
|
116
|
+
}
|
|
117
|
+
declare function useMediaRecorder(): UseMediaRecorderResult;
|
|
118
|
+
|
|
119
|
+
interface MicrophoneDevice extends BaseMediaDevice<'microphone'> {
|
|
120
|
+
}
|
|
121
|
+
interface UseMicrophoneOptions {
|
|
122
|
+
autoStart?: boolean;
|
|
123
|
+
deviceId?: string;
|
|
124
|
+
constraints?: MediaTrackConstraints;
|
|
125
|
+
monitorVolume?: boolean;
|
|
126
|
+
}
|
|
127
|
+
interface UseMicrophoneResult extends BaseHookResult {
|
|
128
|
+
currentMicrophone: MicrophoneDevice | null;
|
|
129
|
+
isActive: boolean;
|
|
130
|
+
isLoading: boolean;
|
|
131
|
+
microphones: MicrophoneDevice[];
|
|
132
|
+
muted: boolean;
|
|
133
|
+
permission: HookPermissionState;
|
|
134
|
+
status: MediaStatus;
|
|
135
|
+
stream: MediaStream | null;
|
|
136
|
+
volume: number;
|
|
137
|
+
mute: () => void;
|
|
138
|
+
refreshDevices: () => Promise<void>;
|
|
139
|
+
start: (override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
140
|
+
stop: () => void;
|
|
141
|
+
switchMicrophone: (deviceId: string, override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
142
|
+
unmute: () => void;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
declare function useMicrophone(options?: UseMicrophoneOptions): UseMicrophoneResult;
|
|
146
|
+
|
|
147
|
+
interface UsePermissionsResult extends BaseHookResult {
|
|
148
|
+
camera: HookPermissionState;
|
|
149
|
+
microphone: HookPermissionState;
|
|
150
|
+
requestAll: () => Promise<void>;
|
|
151
|
+
requestCamera: () => Promise<void>;
|
|
152
|
+
requestMicrophone: () => Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
declare function usePermissions(): UsePermissionsResult;
|
|
155
|
+
|
|
156
|
+
interface SpeakerDevice extends BaseMediaDevice<'speaker'> {
|
|
157
|
+
}
|
|
158
|
+
interface UseSpeakerResult extends BaseHookResult {
|
|
159
|
+
currentSpeaker: SpeakerDevice | null;
|
|
160
|
+
isSupported: boolean;
|
|
161
|
+
permission: HookPermissionState;
|
|
162
|
+
speakers: SpeakerDevice[];
|
|
163
|
+
switchSpeaker: (deviceId: string) => Promise<boolean>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type SpeakerTarget = RefObject<HTMLMediaElement | null> | HTMLMediaElement | null;
|
|
167
|
+
declare function useSpeaker(target: SpeakerTarget): UseSpeakerResult;
|
|
168
|
+
|
|
169
|
+
declare const version = "0.1.0";
|
|
170
|
+
|
|
171
|
+
export { type BaseHookResult, type BaseMediaDevice, type CameraDevice, type DeviceCollection, type HookPermissionState, type MediaConstraints, type MediaDeviceCategory, type MediaDevicesHookResult, type MediaError, type MediaErrorCode, type MediaPermissionState, MediaProvider, type MediaStatus, type MicrophoneDevice, type SpeakerDevice, type UseCameraOptions, type UseCameraResult, type UseMicrophoneOptions, type UseMicrophoneResult, type UseSpeakerResult, useCamera, useDeviceChange, useMediaDevices, useMediaProviderConfig, useMediaRecorder, useMicrophone, usePermissions, useSpeaker, version };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
interface MediaProviderConfig {
|
|
4
|
+
autoRefreshOnDeviceChange?: boolean;
|
|
5
|
+
cameraConstraints?: MediaTrackConstraints;
|
|
6
|
+
microphoneConstraints?: MediaTrackConstraints;
|
|
7
|
+
monitorMicrophoneVolume?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface MediaProviderProps {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
value?: MediaProviderConfig;
|
|
12
|
+
}
|
|
13
|
+
declare function MediaProvider({ children, value }: MediaProviderProps): React.JSX.Element;
|
|
14
|
+
declare function useMediaProviderConfig(): Required<MediaProviderConfig>;
|
|
15
|
+
|
|
16
|
+
type HookPermissionState = PermissionState | 'unsupported' | 'unknown';
|
|
17
|
+
type MediaPermissionState = HookPermissionState;
|
|
18
|
+
type MediaDeviceCategory = 'camera' | 'microphone' | 'speaker';
|
|
19
|
+
type MediaStatus = 'idle' | 'loading' | 'active' | 'paused' | 'stopped' | 'error';
|
|
20
|
+
type MediaErrorCode = 'abort' | 'browser-not-supported' | 'device-in-use' | 'device-not-found' | 'invalid-state' | 'not-allowed' | 'not-readable' | 'overconstrained' | 'permission-denied' | 'permission-query-failed' | 'recorder-not-supported' | 'speaker-not-supported' | 'unknown';
|
|
21
|
+
interface MediaError {
|
|
22
|
+
code: MediaErrorCode;
|
|
23
|
+
message: string;
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
name?: string;
|
|
26
|
+
}
|
|
27
|
+
interface BaseMediaDevice<TKind extends MediaDeviceCategory = MediaDeviceCategory> {
|
|
28
|
+
deviceId: string;
|
|
29
|
+
groupId: string;
|
|
30
|
+
kind: TKind;
|
|
31
|
+
label: string;
|
|
32
|
+
raw: MediaDeviceInfo;
|
|
33
|
+
}
|
|
34
|
+
interface DeviceCollection {
|
|
35
|
+
cameras: BaseMediaDevice<'camera'>[];
|
|
36
|
+
microphones: BaseMediaDevice<'microphone'>[];
|
|
37
|
+
speakers: BaseMediaDevice<'speaker'>[];
|
|
38
|
+
}
|
|
39
|
+
interface BaseHookResult {
|
|
40
|
+
loading: boolean;
|
|
41
|
+
error: MediaError | null;
|
|
42
|
+
supported: boolean;
|
|
43
|
+
refresh: () => Promise<void>;
|
|
44
|
+
destroy: () => void;
|
|
45
|
+
}
|
|
46
|
+
interface MediaConstraints {
|
|
47
|
+
audio?: boolean | MediaTrackConstraints;
|
|
48
|
+
video?: boolean | MediaTrackConstraints;
|
|
49
|
+
}
|
|
50
|
+
interface MediaDevicesHookResult extends BaseHookResult, DeviceCollection {
|
|
51
|
+
devices: BaseMediaDevice[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface CameraDevice extends BaseMediaDevice<'camera'> {
|
|
55
|
+
facingMode?: 'user' | 'environment';
|
|
56
|
+
}
|
|
57
|
+
interface UseCameraOptions {
|
|
58
|
+
autoStart?: boolean;
|
|
59
|
+
deviceId?: string;
|
|
60
|
+
constraints?: MediaTrackConstraints;
|
|
61
|
+
facingMode?: 'user' | 'environment';
|
|
62
|
+
}
|
|
63
|
+
interface UseCameraResult extends BaseHookResult {
|
|
64
|
+
cameras: CameraDevice[];
|
|
65
|
+
constraints: MediaTrackConstraints;
|
|
66
|
+
currentCamera: CameraDevice | null;
|
|
67
|
+
isActive: boolean;
|
|
68
|
+
isLoading: boolean;
|
|
69
|
+
isPaused: boolean;
|
|
70
|
+
permission: HookPermissionState;
|
|
71
|
+
status: MediaStatus;
|
|
72
|
+
stream: MediaStream | null;
|
|
73
|
+
pause: () => void;
|
|
74
|
+
refreshDevices: () => Promise<void>;
|
|
75
|
+
resume: () => void;
|
|
76
|
+
start: (override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
77
|
+
stop: () => void;
|
|
78
|
+
switchCamera: (deviceId: string, override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare function useCamera(options?: UseCameraOptions): UseCameraResult;
|
|
82
|
+
|
|
83
|
+
interface UseMediaDevicesOptions {
|
|
84
|
+
listen?: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function useMediaDevices(options?: UseMediaDevicesOptions): MediaDevicesHookResult;
|
|
87
|
+
|
|
88
|
+
interface DeviceChangeHookResult {
|
|
89
|
+
cameras: ReturnType<typeof useMediaDevices>['cameras'];
|
|
90
|
+
changeCount: number;
|
|
91
|
+
destroy: ReturnType<typeof useMediaDevices>['destroy'];
|
|
92
|
+
devices: ReturnType<typeof useMediaDevices>['devices'];
|
|
93
|
+
error: ReturnType<typeof useMediaDevices>['error'];
|
|
94
|
+
lastChangeAt: number | null;
|
|
95
|
+
loading: boolean;
|
|
96
|
+
microphones: ReturnType<typeof useMediaDevices>['microphones'];
|
|
97
|
+
refresh: ReturnType<typeof useMediaDevices>['refresh'];
|
|
98
|
+
speakers: ReturnType<typeof useMediaDevices>['speakers'];
|
|
99
|
+
supported: boolean;
|
|
100
|
+
}
|
|
101
|
+
declare function useDeviceChange(): DeviceChangeHookResult;
|
|
102
|
+
|
|
103
|
+
interface UseMediaRecorderResult extends BaseHookResult {
|
|
104
|
+
blob: Blob | null;
|
|
105
|
+
chunks: Blob[];
|
|
106
|
+
isPaused: boolean;
|
|
107
|
+
isRecording: boolean;
|
|
108
|
+
start: (stream: MediaStream, options?: MediaRecorderOptions) => void;
|
|
109
|
+
status: MediaStatus;
|
|
110
|
+
stop: () => void;
|
|
111
|
+
pause: () => void;
|
|
112
|
+
resume: () => void;
|
|
113
|
+
reset: () => void;
|
|
114
|
+
download: (fileName?: string) => string | null;
|
|
115
|
+
url: string | null;
|
|
116
|
+
}
|
|
117
|
+
declare function useMediaRecorder(): UseMediaRecorderResult;
|
|
118
|
+
|
|
119
|
+
interface MicrophoneDevice extends BaseMediaDevice<'microphone'> {
|
|
120
|
+
}
|
|
121
|
+
interface UseMicrophoneOptions {
|
|
122
|
+
autoStart?: boolean;
|
|
123
|
+
deviceId?: string;
|
|
124
|
+
constraints?: MediaTrackConstraints;
|
|
125
|
+
monitorVolume?: boolean;
|
|
126
|
+
}
|
|
127
|
+
interface UseMicrophoneResult extends BaseHookResult {
|
|
128
|
+
currentMicrophone: MicrophoneDevice | null;
|
|
129
|
+
isActive: boolean;
|
|
130
|
+
isLoading: boolean;
|
|
131
|
+
microphones: MicrophoneDevice[];
|
|
132
|
+
muted: boolean;
|
|
133
|
+
permission: HookPermissionState;
|
|
134
|
+
status: MediaStatus;
|
|
135
|
+
stream: MediaStream | null;
|
|
136
|
+
volume: number;
|
|
137
|
+
mute: () => void;
|
|
138
|
+
refreshDevices: () => Promise<void>;
|
|
139
|
+
start: (override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
140
|
+
stop: () => void;
|
|
141
|
+
switchMicrophone: (deviceId: string, override?: MediaTrackConstraints) => Promise<MediaStream | null>;
|
|
142
|
+
unmute: () => void;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
declare function useMicrophone(options?: UseMicrophoneOptions): UseMicrophoneResult;
|
|
146
|
+
|
|
147
|
+
interface UsePermissionsResult extends BaseHookResult {
|
|
148
|
+
camera: HookPermissionState;
|
|
149
|
+
microphone: HookPermissionState;
|
|
150
|
+
requestAll: () => Promise<void>;
|
|
151
|
+
requestCamera: () => Promise<void>;
|
|
152
|
+
requestMicrophone: () => Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
declare function usePermissions(): UsePermissionsResult;
|
|
155
|
+
|
|
156
|
+
interface SpeakerDevice extends BaseMediaDevice<'speaker'> {
|
|
157
|
+
}
|
|
158
|
+
interface UseSpeakerResult extends BaseHookResult {
|
|
159
|
+
currentSpeaker: SpeakerDevice | null;
|
|
160
|
+
isSupported: boolean;
|
|
161
|
+
permission: HookPermissionState;
|
|
162
|
+
speakers: SpeakerDevice[];
|
|
163
|
+
switchSpeaker: (deviceId: string) => Promise<boolean>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type SpeakerTarget = RefObject<HTMLMediaElement | null> | HTMLMediaElement | null;
|
|
167
|
+
declare function useSpeaker(target: SpeakerTarget): UseSpeakerResult;
|
|
168
|
+
|
|
169
|
+
declare const version = "0.1.0";
|
|
170
|
+
|
|
171
|
+
export { type BaseHookResult, type BaseMediaDevice, type CameraDevice, type DeviceCollection, type HookPermissionState, type MediaConstraints, type MediaDeviceCategory, type MediaDevicesHookResult, type MediaError, type MediaErrorCode, type MediaPermissionState, MediaProvider, type MediaStatus, type MicrophoneDevice, type SpeakerDevice, type UseCameraOptions, type UseCameraResult, type UseMicrophoneOptions, type UseMicrophoneResult, type UseSpeakerResult, useCamera, useDeviceChange, useMediaDevices, useMediaProviderConfig, useMediaRecorder, useMicrophone, usePermissions, useSpeaker, version };
|