1

I am using a ReactMediaRecorder but I need to call my own method on the onClick for the controls.

Here is the ReactMediaRecorder code:

/// <reference types="dom-mediacapture-record" /> import { ReactElement } from "react"; export 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; }; export declare type ReactMediaRecorderHookProps = { audio?: boolean | MediaTrackConstraints; video?: boolean | MediaTrackConstraints; screen?: boolean; onStop?: (blobUrl: string, blob: Blob) => void; blobPropertyBag?: BlobPropertyBag; mediaRecorderOptions?: MediaRecorderOptions | null; }; export declare type ReactMediaRecorderProps = ReactMediaRecorderHookProps & { render: (props: ReactMediaRecorderRenderProps) => ReactElement; }; export 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 enum RecorderErrors { AbortError = "media_aborted", NotAllowedError = "permission_denied", NotFoundError = "no_specified_media_found", NotReadableError = "media_in_use", OverconstrainedError = "invalid_media_constraints", TypeError = "no_constraints", NONE = "", NO_RECORDER = "recorder_error" } export declare function useReactMediaRecorder({ audio, video, onStop, blobPropertyBag, screen, mediaRecorderOptions, }: ReactMediaRecorderHookProps): ReactMediaRecorderRenderProps; export declare const ReactMediaRecorder: (props: 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>)>; 

If I run the below code below then everything works. As startRecording stopRecording are not overwritten so its using the voids passed in (see above).

function RecordAudio(props) { isVideo = false; return ( <ReactMediaRecorder audio render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => ( <Row> {status === 'recording' ? ( <AudioPreview stream={previewStream} /> ) : ( <audio src={mediaBlobUrl} controls autoPlay /> )} <Controls status={status} startRecording={startRecordingC} stopRecording={stopRecordingC} mediaBlobUrl={mediaBlobUrl} /> </Row> )} /> ); } 

However, if I overwrite these functions then then the ReactMediaRecorder doesn't work, but my functions get called.

function RecordAudio(props) { isVideo = false; const startRecording = (evt) => { console.log('start streaming'); fetch('/api/stream/start', { method: 'post' }).then((response) => { console.log('stream requested'); }); }; const stopRecording = (evt) => { console.log('stop streaming'); fetch('/api/stream/stop', { method: 'post' }).then((response) => { audioStreamer.stopStreaming(); console.log('streaming ended'); }); }; return ( <ReactMediaRecorder audio render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => ( <Row> {status === 'recording' ? ( <AudioPreview stream={previewStream} /> ) : ( <audio src={mediaBlobUrl} controls autoPlay /> )} <Controls status={status} startRecording={startRecording} stopRecording={stopRecording} mediaBlobUrl={mediaBlobUrl} /> </Row> )} /> ); } 

New to JS and this is very frustrating. Is there a way to run both the provided void function and mine on the onClick? Or can I passthrough?

1 Answer 1

2

Yes, you can do this by passing an anonymous callback to the 3rd-party module. In the anonymous callback you proxy the event object to both callbacks. You my need to give your callbacks a different name so you can disambiguate them within the render prop function.

function RecordAudio(props) { isVideo = false; const myStartRecording = (evt) => { console.log('start streaming'); fetch('/api/stream/start', { method: 'post' }).then((response) => { console.log('stream requested'); }); }; const myStopRecording = (evt) => { console.log('stop streaming'); fetch('/api/stream/stop', { method: 'post' }).then((response) => { audioStreamer.stopStreaming(); console.log('streaming ended'); }); }; return ( <ReactMediaRecorder audio render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => ( <Row> {status === 'recording' ? ( <AudioPreview stream={previewStream} /> ) : ( <audio src={mediaBlobUrl} controls autoPlay /> )} <Controls status={status} startRecording={e => { myStartRecording(e); startRecording(e); }} stopRecording={e => { myStopRecording(e); stopRecording(e); }} mediaBlobUrl={mediaBlobUrl} /> </Row> )} /> ); } 
Sign up to request clarification or add additional context in comments.

2 Comments

I would pay you money if I could on here. I have spent 40 hours on this. Any resources to learn this better you would suggest?
@jdog For me... it's been just lots and lots of time spent reading the React docs, and almost as much reading docs on MDN. The skillset built mostly from lots of reading of other people's code, be it reviewing pull requests at work or questions here on SO.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.