Skip to content

Commit

Permalink
Adding optional deviceId prop (bringing #24 up to date) (#92)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
VinSpee and plauche committed Apr 12, 2022
1 parent 91ec08a commit e050c0a
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ typings/
.env

# build directories
lib
# lib
31 changes: 31 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/// <reference types="dom-mediacapture-record" />
import { ReactElement } from "react";
declare type ReactMediaRecorderRenderProps = {
error: string;
muteAudio: () => void;
unMuteAudio: () => void;
startRecording: () => void;
pauseRecording: () => void;
resumeRecording: () => void;
stopRecording: () => void;
mediaBlobUrl: null | string;
status: StatusMessages;
isAudioMuted: boolean;
previewStream: MediaStream | null;
clearBlobUrl: () => void;
};
declare type ReactMediaRecorderProps = {
render: (props: ReactMediaRecorderRenderProps) => ReactElement;
audio?: boolean | MediaTrackConstraints;
video?: boolean | MediaTrackConstraints;
screen?: boolean;
onStop?: (blobUrl: string, blob: Blob) => void;
onStart?: () => void;
blobPropertyBag?: BlobPropertyBag;
mediaRecorderOptions?: MediaRecorderOptions | null;
customMediaStream?: MediaStream | null;
stopStreamsOnStop?: boolean;
};
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";
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>)>;
export {};
18 changes: 18 additions & 0 deletions lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 18 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ export type ReactMediaRecorderHookProps = {
video?: boolean | MediaTrackConstraints;
screen?: boolean;
onStop?: (blobUrl: string, blob: Blob) => void;
onStart?: () => void;
blobPropertyBag?: BlobPropertyBag;
mediaRecorderOptions?: MediaRecorderOptions | null;
customMediaStream?: MediaStream | null;
stopStreamsOnStop?: boolean;
askPermissionOnMount?: boolean;
};
export type ReactMediaRecorderProps = ReactMediaRecorderHookProps & {
Expand Down Expand Up @@ -60,9 +63,12 @@ export function useReactMediaRecorder({
audio = true,
video = false,
onStop = () => null,
onStart = () => null,
blobPropertyBag,
screen = false,
mediaRecorderOptions = null,
customMediaStream = null,
stopStreamsOnStop = true,
askPermissionOnMount = false,
}: ReactMediaRecorderHookProps): ReactMediaRecorderRenderProps {
const mediaRecorder = useRef<MediaRecorder | null>(null);
Expand All @@ -80,7 +86,9 @@ export function useReactMediaRecorder({
video: typeof video === "boolean" ? !!video : video,
};
try {
if (screen) {
if (customMediaStream) {
mediaStream.current = customMediaStream;
} else if (screen) {
//@ts-ignore
const stream = (await window.navigator.mediaDevices.getDisplayMedia({
video: video || true,
Expand Down Expand Up @@ -196,6 +204,7 @@ export function useReactMediaRecorder({
mediaRecorder.current = new MediaRecorder(mediaStream.current);
mediaRecorder.current.ondataavailable = onRecordingActive;
mediaRecorder.current.onstop = onRecordingStop;
mediaRecorder.current.onstart = onRecordingStart;
mediaRecorder.current.onerror = () => {
setError("NO_RECORDER");
setStatus("idle");
Expand All @@ -209,6 +218,10 @@ export function useReactMediaRecorder({
mediaChunks.current.push(data);
};

const onRecordingStart = () => {
onStart();
};

const onRecordingStop = () => {
const [chunk] = mediaChunks.current;
const blobProperty: BlobPropertyBag = Object.assign(
Expand Down Expand Up @@ -249,8 +262,10 @@ export function useReactMediaRecorder({
if (mediaRecorder.current.state !== "inactive") {
setStatus("stopping");
mediaRecorder.current.stop();
mediaStream.current &&
mediaStream.current.getTracks().forEach((track) => track.stop());
if (stopStreamsOnStop) {
mediaStream.current &&
mediaStream.current.getTracks().forEach((track) => track.stop());
}
mediaChunks.current = [];
}
}
Expand Down
41 changes: 41 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@types/dom-mediacapture-record@^1.0.2":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@types/dom-mediacapture-record/-/dom-mediacapture-record-1.0.7.tgz#08bacca4296ef521d59049f43e65cf971bbf6be1"
integrity sha512-ddDIRTO1ajtbxaNo2o7fPJggpN54PZf1ZUJKOjto2ENMJE/9GKUvaw3ZRuQzlS/p0E+PnIcssxfoqYJ4yiXSBw==

"@types/node@^12.12.11":
version "12.12.54"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1"
integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==

"@types/prop-types@*":
version "15.7.3"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==

"@types/react@^16.9.11":
version "16.9.49"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872"
integrity sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

csstype@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8"
integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==

jsmin@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/jsmin/-/jsmin-1.0.1.tgz#e7bd0dcd6496c3bf4863235bf461a3d98aa3b98c"
integrity sha1-570NzWSWw79IYyNb9GGj2YqjuYw=

typescript@^3.7.2:
version "3.9.7"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==

0 comments on commit e050c0a

Please sign in to comment.