Skip to content

Commit

Permalink
New hook: useReactMediaRecorder
Browse files Browse the repository at this point in the history
  • Loading branch information
danigb committed Oct 22, 2020
1 parent e06d53e commit 6cdd6ab
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# react-media-recorder :o2: :video_camera: :microphone: :computer:

`react-media-recorder` is a fully typed react component with render prop that can be used to:
`react-media-recorder` is a fully typed react component with render prop, or a react hook, that can be used to:

- Record audio/video
- Record screen
Expand Down Expand Up @@ -43,6 +43,32 @@ const RecordView = () => (

Since `react-media-recording` uses render prop, you can define what to render in the view. Just don't forget to wire the `startRecording`, `stopRecording` and `mediaBlobUrl` to your component.

## Usage with react hooks

```javascript
import { useReactMediaRecorder } from "react-media-recorder";

const RecordView = () => {
const {
status,
startRecording,
stopRecording,
mediaBlobUrl,
} = useReactMediaRecorder({ video: true });

return (
<div>
<p>{status}</p>
<button onClick={startRecording}>Start Recording</button>
<button onClick={stopRecording}>Stop Recording</button>
<video src={mediaBlobUrl} controls autoplay loop />
</div>
);
};
```

The hook receives an object as argument with the same ReactMediaRecorder options / props (except the `render` function).

### Options / Props

#### audio
Expand Down Expand Up @@ -167,9 +193,9 @@ A `function` which unmutes the audio tracks when invoked.

#### mediaBlobUrl

A `blob` url that can be wired to an `<audio />`, `<video />` or an `<a />` element.
A `blob` url that can be wired to an `<audio />`, `<video />` or an `<a />` element.

#### clearBlobUrl
#### clearBlobUrl

A `function` which clears the existing generated blob url (if any)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-media-recorder",
"version": "1.3.0",
"version": "1.4.0",
"description": "A React component based on MediaRecorder() API to record audio/video streams",
"main": "index.js",
"scripts": {
Expand Down
26 changes: 15 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactElement, useCallback, useEffect, useRef, useState } from "react";

type ReactMediaRecorderRenderProps = {
export type ReactMediaRecorderRenderProps = {
error: string;
muteAudio: () => void;
unMuteAudio: () => void;
Expand All @@ -15,17 +15,19 @@ type ReactMediaRecorderRenderProps = {
clearBlobUrl: () => void;
};

type ReactMediaRecorderProps = {
render: (props: ReactMediaRecorderRenderProps) => ReactElement;
export type ReactMediaRecorderHookProps = {
audio?: boolean | MediaTrackConstraints;
video?: boolean | MediaTrackConstraints;
screen?: boolean;
onStop?: (blobUrl: string, blob: Blob) => void;
blobPropertyBag?: BlobPropertyBag;
mediaRecorderOptions?: MediaRecorderOptions | null;
};
export type ReactMediaRecorderProps = ReactMediaRecorderHookProps & {
render: (props: ReactMediaRecorderRenderProps) => ReactElement;
};

type StatusMessages =
export type StatusMessages =
| "media_aborted"
| "permission_denied"
| "no_specified_media_found"
Expand All @@ -40,7 +42,7 @@ type StatusMessages =
| "stopping"
| "stopped";

enum RecorderErrors {
export enum RecorderErrors {
AbortError = "media_aborted",
NotAllowedError = "permission_denied",
NotFoundError = "no_specified_media_found",
Expand All @@ -51,15 +53,14 @@ enum RecorderErrors {
NO_RECORDER = "recorder_error",
}

export const ReactMediaRecorder = ({
render,
export function useReactMediaRecorder({
audio = true,
video = false,
onStop = () => null,
blobPropertyBag,
screen = false,
mediaRecorderOptions = null,
}: ReactMediaRecorderProps) => {
}: ReactMediaRecorderHookProps): ReactMediaRecorderRenderProps {
const mediaRecorder = useRef<MediaRecorder | null>(null);
const mediaChunks = useRef<Blob[]>([]);
const mediaStream = useRef<MediaStream | null>(null);
Expand Down Expand Up @@ -226,7 +227,7 @@ export const ReactMediaRecorder = ({
}
};

return render({
return {
error: RecorderErrors[error],
muteAudio: () => muteAudio(true),
unMuteAudio: () => muteAudio(false),
Expand All @@ -241,5 +242,8 @@ export const ReactMediaRecorder = ({
? new MediaStream(mediaStream.current.getVideoTracks())
: null,
clearBlobUrl: () => setMediaBlobUrl(null),
});
};
};
}

export const ReactMediaRecorder = (props: ReactMediaRecorderProps) =>
props.render(useReactMediaRecorder(props));

0 comments on commit 6cdd6ab

Please sign in to comment.