Skip to content

Commit e050c0a

Browse files
VinSpeeplauche
andauthored
Adding optional deviceId prop (bringing #24 up to date) (#92)
* Adding optional deviceId prop * Including lib * Adding more broad customMediaStream prop * Added stopStreamsOnStop prop to prevent stopping underlying streams when recording stops * Added onStart hook * Removing deviceId prop in favor of customMediaStream Co-authored-by: Ryan Plauche <ryan.plauche@conduit.vc>
1 parent 91ec08a commit e050c0a

File tree

5 files changed

+109
-4
lines changed

5 files changed

+109
-4
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ typings/
5858
.env
5959

6060
# build directories
61-
lib
61+
# lib

lib/index.d.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/// <reference types="dom-mediacapture-record" />
2+
import { ReactElement } from "react";
3+
declare type ReactMediaRecorderRenderProps = {
4+
error: string;
5+
muteAudio: () => void;
6+
unMuteAudio: () => void;
7+
startRecording: () => void;
8+
pauseRecording: () => void;
9+
resumeRecording: () => void;
10+
stopRecording: () => void;
11+
mediaBlobUrl: null | string;
12+
status: StatusMessages;
13+
isAudioMuted: boolean;
14+
previewStream: MediaStream | null;
15+
clearBlobUrl: () => void;
16+
};
17+
declare type ReactMediaRecorderProps = {
18+
render: (props: ReactMediaRecorderRenderProps) => ReactElement;
19+
audio?: boolean | MediaTrackConstraints;
20+
video?: boolean | MediaTrackConstraints;
21+
screen?: boolean;
22+
onStop?: (blobUrl: string, blob: Blob) => void;
23+
onStart?: () => void;
24+
blobPropertyBag?: BlobPropertyBag;
25+
mediaRecorderOptions?: MediaRecorderOptions | null;
26+
customMediaStream?: MediaStream | null;
27+
stopStreamsOnStop?: boolean;
28+
};
29+
declare type StatusMessages = "media_aborted" | "permission_denied" | "no_specified_media_found" | "media_in_use" | "invalid_media_constraints" | "no_constraints" | "recorder_error" | "idle" | "acquiring_media" | "delayed_start" | "recording" | "stopping" | "stopped";
30+
export declare const ReactMediaRecorder: ({ render, audio, video, onStop, onStart, blobPropertyBag, screen, mediaRecorderOptions, customMediaStream, stopStreamsOnStop, }: ReactMediaRecorderProps) => ReactElement<any, string | ((props: any) => ReactElement<any, string | any | (new (props: any) => import("react").Component<any, any, any>)> | null) | (new (props: any) => import("react").Component<any, any, any>)>;
31+
export {};

lib/index.js

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ export type ReactMediaRecorderHookProps = {
2121
video?: boolean | MediaTrackConstraints;
2222
screen?: boolean;
2323
onStop?: (blobUrl: string, blob: Blob) => void;
24+
onStart?: () => void;
2425
blobPropertyBag?: BlobPropertyBag;
2526
mediaRecorderOptions?: MediaRecorderOptions | null;
27+
customMediaStream?: MediaStream | null;
28+
stopStreamsOnStop?: boolean;
2629
askPermissionOnMount?: boolean;
2730
};
2831
export type ReactMediaRecorderProps = ReactMediaRecorderHookProps & {
@@ -60,9 +63,12 @@ export function useReactMediaRecorder({
6063
audio = true,
6164
video = false,
6265
onStop = () => null,
66+
onStart = () => null,
6367
blobPropertyBag,
6468
screen = false,
6569
mediaRecorderOptions = null,
70+
customMediaStream = null,
71+
stopStreamsOnStop = true,
6672
askPermissionOnMount = false,
6773
}: ReactMediaRecorderHookProps): ReactMediaRecorderRenderProps {
6874
const mediaRecorder = useRef<MediaRecorder | null>(null);
@@ -80,7 +86,9 @@ export function useReactMediaRecorder({
8086
video: typeof video === "boolean" ? !!video : video,
8187
};
8288
try {
83-
if (screen) {
89+
if (customMediaStream) {
90+
mediaStream.current = customMediaStream;
91+
} else if (screen) {
8492
//@ts-ignore
8593
const stream = (await window.navigator.mediaDevices.getDisplayMedia({
8694
video: video || true,
@@ -196,6 +204,7 @@ export function useReactMediaRecorder({
196204
mediaRecorder.current = new MediaRecorder(mediaStream.current);
197205
mediaRecorder.current.ondataavailable = onRecordingActive;
198206
mediaRecorder.current.onstop = onRecordingStop;
207+
mediaRecorder.current.onstart = onRecordingStart;
199208
mediaRecorder.current.onerror = () => {
200209
setError("NO_RECORDER");
201210
setStatus("idle");
@@ -209,6 +218,10 @@ export function useReactMediaRecorder({
209218
mediaChunks.current.push(data);
210219
};
211220

221+
const onRecordingStart = () => {
222+
onStart();
223+
};
224+
212225
const onRecordingStop = () => {
213226
const [chunk] = mediaChunks.current;
214227
const blobProperty: BlobPropertyBag = Object.assign(
@@ -249,8 +262,10 @@ export function useReactMediaRecorder({
249262
if (mediaRecorder.current.state !== "inactive") {
250263
setStatus("stopping");
251264
mediaRecorder.current.stop();
252-
mediaStream.current &&
253-
mediaStream.current.getTracks().forEach((track) => track.stop());
265+
if (stopStreamsOnStop) {
266+
mediaStream.current &&
267+
mediaStream.current.getTracks().forEach((track) => track.stop());
268+
}
254269
mediaChunks.current = [];
255270
}
256271
}

yarn.lock

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
"@types/dom-mediacapture-record@^1.0.2":
6+
version "1.0.7"
7+
resolved "https://registry.yarnpkg.com/@types/dom-mediacapture-record/-/dom-mediacapture-record-1.0.7.tgz#08bacca4296ef521d59049f43e65cf971bbf6be1"
8+
integrity sha512-ddDIRTO1ajtbxaNo2o7fPJggpN54PZf1ZUJKOjto2ENMJE/9GKUvaw3ZRuQzlS/p0E+PnIcssxfoqYJ4yiXSBw==
9+
10+
"@types/node@^12.12.11":
11+
version "12.12.54"
12+
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1"
13+
integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==
14+
15+
"@types/prop-types@*":
16+
version "15.7.3"
17+
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
18+
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
19+
20+
"@types/react@^16.9.11":
21+
version "16.9.49"
22+
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872"
23+
integrity sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==
24+
dependencies:
25+
"@types/prop-types" "*"
26+
csstype "^3.0.2"
27+
28+
csstype@^3.0.2:
29+
version "3.0.3"
30+
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8"
31+
integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==
32+
33+
jsmin@^1.0.1:
34+
version "1.0.1"
35+
resolved "https://registry.yarnpkg.com/jsmin/-/jsmin-1.0.1.tgz#e7bd0dcd6496c3bf4863235bf461a3d98aa3b98c"
36+
integrity sha1-570NzWSWw79IYyNb9GGj2YqjuYw=
37+
38+
typescript@^3.7.2:
39+
version "3.9.7"
40+
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
41+
integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==

0 commit comments

Comments
 (0)