Socket
Socket
Sign inDemoInstall

react-media-recorder

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-media-recorder - npm Package Compare versions

Comparing version 0.7.1 to 1.0.0

lib/index.d.ts

18

lib/index.js

@@ -1,1 +0,17 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var _regenerator=require("babel-runtime/regenerator"),_regenerator2=_interopRequireDefault(_regenerator),_asyncToGenerator2=require("babel-runtime/helpers/asyncToGenerator"),_asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2),_classCallCheck2=require("babel-runtime/helpers/classCallCheck"),_classCallCheck3=_interopRequireDefault(_classCallCheck2),_possibleConstructorReturn2=require("babel-runtime/helpers/possibleConstructorReturn"),_possibleConstructorReturn3=_interopRequireDefault(_possibleConstructorReturn2),_inherits2=require("babel-runtime/helpers/inherits"),_inherits3=_interopRequireDefault(_inherits2),_typeof2=require("babel-runtime/helpers/typeof"),_typeof3=_interopRequireDefault(_typeof2),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes);function _interopRequireDefault(a){return a&&a.__esModule?a:{default:a}}function checkMediaConstraint(a){var b=Object.keys(a)[0],c=a[b];if(c&&"boolean"!=typeof c&&"object"!==("undefined"==typeof c?"undefined":(0,_typeof3.default)(c)))return new Error("The "+b+" prop must be either a boolean or MediaTrackConstraints object. Please check your React Media Recorder component");if("object"===("undefined"==typeof c?"undefined":(0,_typeof3.default)(c))){var d=navigator.mediaDevices.getSupportedConstraints(),e=Object.keys(c).filter(function(a){return!d[a]});if(0<e.length)return new Error("The constraint(s) ["+e.join(",")+"] which you've supplied to the "+b+" prop are unsupported in this browser")}}var errors={AbortError:"media_aborted",NotAllowedError:"permission_denied",NotFoundError:"no_specified_media_found",NotReadableError:"media_in_use",OverconstrainedError:"invalid_media_constraints",TypeError:"no_constraints"},ReactMediaRecorder=function(a){function b(a){(0,_classCallCheck3.default)(this,b);var c=(0,_possibleConstructorReturn3.default)(this,(b.__proto__||Object.getPrototypeOf(b)).call(this,a));if(_initialiseProps.call(c),!window.MediaRecorder)throw new Error("React Media Recorder: Unsupported browser");var d=a.audio,e=a.video,f=a.blobPropertyBag,g=void 0===f?e?{type:"video/mp4"}:{type:"audio/wav"}:f;return Object.prototype.hasOwnProperty.call(a,"muted")&&console.warn("React Media Recorder: Please use mute() and unmute() functions available in the render method for muting/unmuting audio. mute prop will be deprecated soon."),a.muted&&(c.state.status+="_muted"),c.requiredMedia={audio:"boolean"==typeof d?!!d:d,video:"boolean"==typeof e?!!e:e},c.blobPropertyBag=g,c}return(0,_inherits3.default)(b,a),b}(_react2.default.Component);ReactMediaRecorder.propTypes={audio:function c(a){var b=a.audio;return checkMediaConstraint({audio:b})},video:function c(a){var b=a.video;return checkMediaConstraint({video:b},!0)},delay:_propTypes2.default.number,muted:function e(a){var b=a.muted,c=a.audio,d=a.video;return"boolean"==typeof b?b&&c&&!d?new Error("It looks like you tried to mute as well as record audio. Please check your react-media-recorder component declaration"):void 0:new Error("Invalid prop: muted should be a boolan value. Please check your react-media-recorder component declaration")},render:_propTypes2.default.func.isRequired,blobPropertyBag:_propTypes2.default.object,whenStopped:_propTypes2.default.func},ReactMediaRecorder.defaultProps={audio:!0,muted:!1,delay:0,render:function a(){return null},whenStopped:function a(){return null}};var _initialiseProps=function(){var a=this;this.state={status:"idle"},this.chunks=[],this.componentDidMount=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function b(){var c;return _regenerator2.default.wrap(function(b){for(;;)switch(b.prev=b.next){case 0:return b.next=2,a.getMediaStream();case 2:c=b.sent,c&&(c.getAudioTracks().forEach(function(b){return b.enabled=!a.props.muted}),a.stream=c);case 4:case"end":return b.stop();}},b,a)})),this.componentDidUpdate=function(b){if(b.muted!==a.props.muted&&a.stream.getAudioTracks().forEach(function(b){return b.enabled=!a.props.muted}),a.stream){var c=!a.stream.getAudioTracks().every(function(a){return a.enabled});c&&!a.state.status.includes("muted")&&a.setState(function(){return{status:a.state.status+"_muted"}}),!c&&a.state.status.includes("muted")&&a.setState(function(){return{status:a.state.status.replace("_muted","")}})}},this.componentWillUnmount=function(){a.flush()},this.flush=function(){a.stream&&a.stream.getTracks().forEach(function(a){return a.stop()}),a.mediaRecorder=null,a.stream=null,a.chunks=[]},this.muteAudio=function(b){a.stream&&a.stream.getAudioTracks().every(function(a){return a.enabled===b})&&(a.stream.getAudioTracks().forEach(function(a){return a.enabled=!b}),a.setState(a.state))},this.getMediaStream=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function b(){var c;return _regenerator2.default.wrap(function(b){for(;;)switch(b.prev=b.next){case 0:return b.prev=0,b.next=3,window.navigator.mediaDevices.getUserMedia(a.requiredMedia);case 3:return c=b.sent,b.abrupt("return",c);case 7:b.prev=7,b.t0=b["catch"](0),a.setState({status:errors[b.t0.name]});case 10:case"end":return b.stop();}},b,a,[[0,7]])})),this.onRecordingStop=function(){var b=new Blob(a.chunks,a.blobPropertyBag),c=URL.createObjectURL(b);a.props.whenStopped&&a.props.whenStopped(c),a.setState({mediaBlob:c,status:"stopped"})},this.onRecordingActive=function(b){var c=b.data;a.chunks.push(c)},this.initMediaRecorder=function(b){var c=new MediaRecorder(b);return c.ondataavailable=a.onRecordingActive,c.onstop=a.onRecordingStop,c.onerror=function(){return a.setState({status:"recorder_error"})},c},this.startRecording=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function b(){var c;return _regenerator2.default.wrap(function(b){for(;;)switch(b.prev=b.next){case 0:if(a.stream&&(!a.stream||a.stream.active)){b.next=9;break}return b.next=3,a.getMediaStream();case 3:if(c=b.sent,!c){b.next=8;break}a.stream=c,b.next=9;break;case 8:return b.abrupt("return");case 9:a.mediaRecorder=a.initMediaRecorder(a.stream),a.chunks=[],a.setState({mediaBlob:null}),setTimeout(function(){a.mediaRecorder.start(),a.setState({status:"recording"})},a.props.delay),0<a.props.delay&&a.setState({status:"delayed_start"});case 14:case"end":return b.stop();}},b,a)})),this.pauseRecording=function(){a.mediaRecorder&&"recording"===a.mediaRecorder.state&&(a.setState({status:"paused"}),a.mediaRecorder.pause())},this.resumeRecording=function(){a.mediaRecorder&&"paused"===a.mediaRecorder.state&&(a.setState({status:"recording"}),a.mediaRecorder.resume())},this.stopRecording=function(){a.mediaRecorder&&"inactive"!==a.mediaRecorder.state&&(a.mediaRecorder.stop(),a.mediaRecorder=null)},this.render=function(){return a.props.render({status:a.state.status,startRecording:a.startRecording,stopRecording:a.stopRecording,pauseRecording:a.pauseRecording,resumeRecording:a.resumeRecording,muteAudio:function b(){return a.muteAudio(!0)},unmuteAudio:function b(){return a.muteAudio(!1)},mediaBlob:a.state.mediaBlob})}};exports.default=ReactMediaRecorder;
"use strict";var __awaiter=(this&&this.__awaiter)||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value);});}
return new(P||(P=Promise))(function(resolve,reject){function fulfilled(value){try{step(generator.next(value));}catch(e){reject(e);}}
function rejected(value){try{step(generator["throw"](value));}catch(e){reject(e);}}
function step(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected);}
step((generator=generator.apply(thisArg,_arguments||[])).next());});};var __generator=(this&&this.__generator)||function(thisArg,body){var _={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1];},trys:[],ops:[]},f,y,t,g;return g={next:verb(0),"throw":verb(1),"return":verb(2)},typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this;}),g;function verb(n){return function(v){return step([n,v]);};}
function step(op){if(f)throw new TypeError("Generator is already executing.");while(_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue;}
if(op[0]===3&&(!t||(op[1]>t[0]&&op[1]<t[3]))){_.label=op[1];break;}
if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break;}
if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break;}
if(t[2])_.ops.pop();_.trys.pop();continue;}
op=body.call(thisArg,_);}catch(e){op=[6,e];y=0;}finally{f=t=0;}
if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true};}};Object.defineProperty(exports,"__esModule",{value:true});var react_1=require("react");var RecorderErrors;(function(RecorderErrors){RecorderErrors["AbortError"]="media_aborted";RecorderErrors["NotAllowedError"]="permission_denied";RecorderErrors["NotFoundError"]="no_specified_media_found";RecorderErrors["NotReadableError"]="media_in_use";RecorderErrors["OverconstrainedError"]="invalid_media_constraints";RecorderErrors["TypeError"]="no_constraints";RecorderErrors["NONE"]="";RecorderErrors["NO_RECORDER"]="recorder_error";})(RecorderErrors||(RecorderErrors={}));exports.ReactMediaRecorder=function(_a){var render=_a.render,_b=_a.audio,audio=_b===void 0?true:_b,_c=_a.video,video=_c===void 0?false:_c,_d=_a.onStop,onStop=_d===void 0?function(){return null;}:_d,blobPropertyBag=_a.blobPropertyBag,_e=_a.screen,screen=_e===void 0?false:_e;var mediaRecorder=react_1.useRef(null);var mediaChunks=react_1.useRef([]);var mediaStream=react_1.useRef(null);var _f=react_1.useState("idle"),status=_f[0],setStatus=_f[1];var _g=react_1.useState(false),isAudioMuted=_g[0],setIsAudioMuted=_g[1];var _h=react_1.useState(null),mediaBlobUrl=_h[0],setMediaBlobUrl=_h[1];var _j=react_1.useState("NONE"),error=_j[0],setError=_j[1];var getMediaStream=react_1.useCallback(function(){return __awaiter(void 0,void 0,void 0,function(){var requiredMedia,stream_1,audioStream,stream;return __generator(this,function(_a){switch(_a.label){case 0:requiredMedia={audio:typeof audio==="boolean"?!!audio:audio,video:typeof video==="boolean"?!!video:video};if(!screen)return[3,4];return[4,window.navigator.mediaDevices.getDisplayMedia({video:video})];case 1:stream_1=(_a.sent());if(!audio)return[3,3];return[4,window.navigator.mediaDevices.getUserMedia({audio:audio})];case 2:audioStream=_a.sent();audioStream.getAudioTracks().forEach(function(audioTrack){return stream_1.addTrack(audioTrack);});_a.label=3;case 3:return[2,stream_1];case 4:return[4,window.navigator.mediaDevices.getUserMedia(requiredMedia)];case 5:stream=_a.sent();return[2,stream];}});});},[audio,video,screen]);react_1.useEffect(function(){if(!window.MediaRecorder){throw new Error("Unsupported Browser");}
if(screen){if(!window.navigator.mediaDevices.getDisplayMedia){throw new Error("This browser doesn't support screen capturing");}}
var checkConstraints=function(mediaType){var supportedMediaConstraints=navigator.mediaDevices.getSupportedConstraints();var unSupportedConstraints=Object.keys(mediaType).filter(function(constraint){return!supportedMediaConstraints[constraint];});if(unSupportedConstraints.length>0){console.error("The constraints "+unSupportedConstraints.join(",")+" doesn't support on this browser. Please check your ReactMediaRecorder component.");}};if(typeof audio==="object"){checkConstraints(audio);}
if(typeof video==="object"){checkConstraints(video);}
function loadStream(){return __awaiter(this,void 0,void 0,function(){var stream;return __generator(this,function(_a){switch(_a.label){case 0:return[4,getMediaStream()];case 1:stream=_a.sent();mediaStream.current=stream;return[2];}});});}
if(!mediaStream.current){loadStream();}},[audio,screen,video,getMediaStream]);var startRecording=function(){return __awaiter(void 0,void 0,void 0,function(){var stream,error_1;return __generator(this,function(_a){switch(_a.label){case 0:if(!!mediaStream.current)return[3,4];_a.label=1;case 1:_a.trys.push([1,3,,4]);setStatus("acquiring_media");return[4,getMediaStream()];case 2:stream=_a.sent();setStatus("idle");mediaStream.current=stream;return[3,4];case 3:error_1=_a.sent();setError(error_1.name);setStatus("idle");return[2];case 4:mediaRecorder.current=new MediaRecorder(mediaStream.current);mediaRecorder.current.ondataavailable=onRecordingActive;mediaRecorder.current.onstop=onRecordingStop;mediaRecorder.current.onerror=function(){setError("NO_RECORDER");setStatus("idle");};mediaRecorder.current.start();setStatus("recording");return[2];}});});};var onRecordingActive=function(_a){var data=_a.data;mediaChunks.current.push(data);};var onRecordingStop=function(){var blobProperty=blobPropertyBag||video?{type:"video/mp4"}:{type:"audio/wav"};var blob=new Blob(mediaChunks.current,blobProperty);var url=URL.createObjectURL(blob);setStatus("stopped");setMediaBlobUrl(url);onStop(url);};var muteAudio=function(mute){setIsAudioMuted(mute);if(mediaStream.current){mediaStream.current.getAudioTracks().forEach(function(audioTrack){return(audioTrack.enabled=!mute);});}};var pauseRecording=function(){if(mediaRecorder.current&&mediaRecorder.current.state==="recording"){mediaRecorder.current.pause();}};var resumeRecording=function(){if(mediaRecorder.current&&mediaRecorder.current.state==="paused"){mediaRecorder.current.resume();}};var stopRecording=function(){if(mediaRecorder.current){setStatus("stopping");mediaRecorder.current.stop();}};return render({error:RecorderErrors[error],muteAudio:function(){return muteAudio(true);},unMuteAudio:function(){return muteAudio(false);},startRecording:startRecording,pauseRecording:pauseRecording,resumeRecording:resumeRecording,stopRecording:stopRecording,mediaBlobUrl:mediaBlobUrl,status:status,isAudioMuted:isAudioMuted});};

26

package.json
{
"name": "react-media-recorder",
"version": "0.7.1",
"description":
"A React component based on MediaRecorder() API to record audio/video streams",
"version": "1.0.0",
"description": "A React component based on MediaRecorder() API to record audio/video streams",
"main": "index.js",
"scripts": {
"build": "babel src -d ./lib",
"build": "tsc && jsmin -o ./lib/index.js ./lib/index.js",
"prepublishOnly": "npm run build"
},
"files": ["lib"],
"files": [
"lib"
],
"repository": {

@@ -30,13 +31,8 @@ "type": "git",

"devDependencies": {
"babel": "^6.23.0",
"babel-cli": "^6.26.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-minify": "^0.4.3",
"babel-preset-react": "^6.24.1",
"prop-types": "^15.6.1",
"react": "^16.3.2"
"@types/dom-mediacapture-record": "^1.0.2",
"@types/node": "^12.12.11",
"@types/react": "^16.9.11",
"jsmin": "^1.0.1",
"typescript": "^3.7.2"
}
}

@@ -1,4 +0,4 @@

# react-media-recorder :o2: :video_camera: :microphone:
# react-media-recorder :o2: :video_camera: :microphone: :computer:
`react-media-recorder` is a react component with render prop that can be used to record audio/video streams using [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder) API.
`react-media-recorder` is a fully typed react component with render prop that can be used to record audio/video streams or the screens using [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder) API.

@@ -8,3 +8,3 @@ ## Installation

```
npm i -S react-media-recorder
npm i -S react-media-recorder
```

@@ -15,3 +15,3 @@

```
yarn add react-media-recorder
yarn add react-media-recorder
```

@@ -28,3 +28,3 @@

video
render={({ status, startRecording, stopRecording, mediaBlob }) => (
render={({ status, startRecording, stopRecording, mediaBlobUrl }) => (
<div>

@@ -34,3 +34,3 @@ <p>{status}</p>

<button onClick={stopRecording}>Stop Recording</button>
<video src={mediaBlob} controls />
<video src={mediaBlobUrl} controls autoplay loop />
</div>

@@ -43,52 +43,4 @@ )}

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 `mediaBlob` to your component.
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.
### Props available in the `render` function
#### status
A string `enum`. Possible values:
* `idle`
* `recording`
* `paused`
* `stopped`
* `no_constraints`
* `invalid_media_constraints`
* `no_specified_media_found`
* `media_in_use`
* `media_aborted`
* `permission_denied`
* `delayed_start` (_only if a `delay` has been set_) [_deprecating soon_]
If the audio is muted, you'll see the status suffixed with `_muted`.
#### startRecording
A `function`, which starts recording when invoked.
#### pauseRecording
A `function`, which pauses the recording when invoked.
#### resumeRecording
A `function`, which resumes the recording when invoked.
#### stopRecording
A `function`, which stops recording when invoked.
#### muteAudio
A `function`, which mutes the audio tracks when invoked.
#### unmuteAudio
A `function` which unmutes the audio tracks when invoked.
#### mediaBlob
A `blob` url that can be wired to an `<audio />`, `<video />` or an `<a />` element.
### Options / Props

@@ -108,4 +60,4 @@

* `type`, that represents the MIME type of the content of the array that will be put in the blob.
* `endings`, with a default value of "transparent", that specifies how strings containing the line ending character \n are to be written out. It is one of the two values: "native", meaning that line ending characters are changed to match host OS filesystem convention, or "transparent", meaning that endings are stored in the blob without change
- `type`, that represents the MIME type of the content of the array that will be put in the blob.
- `endings`, with a default value of "transparent", that specifies how strings containing the line ending character \n are to be written out. It is one of the two values: "native", meaning that line ending characters are changed to match host OS filesystem convention, or "transparent", meaning that endings are stored in the blob without change

@@ -130,16 +82,9 @@ type: `object`

#### delay [_deprecating soon_]
#### onStop
If you want to start recording after a delay. In milliseconds.
A `function` that would get invoked when the MediaRecorder stops. It'll provide the blob url as its param.
type: `number`
default: `0`
type: `function(blobUrl: string)`
default: `() => null`
#### muted [_deprcating soon_]
Whether you want to mute the audio (while recording video)
type: `boolean`
default: `false`
#### render

@@ -152,2 +97,6 @@

#### screen
A `boolean` value. Lets you to record your current screen. Not all browsers would support this. Please [check here](https://caniuse.com/#search=getDisplayMedia) for the availability. Please note that at the moment, the MediaRecorder won't record two alike streams at a time, if you provide both `screen` and `video` prop, the **screen capturing will take precedence** than the video capturing. But, you can provide the `video` prop (_as the MediaTrackConstraints_) which will then utilized by screen capture (for example, `height`, `width` etc..)
#### video

@@ -160,9 +109,65 @@

#### whenStopped(blobUrl)
### Props available in the `render` function
Will be invoked when the recording stops. This callback will be invoked with the blobUrl as its params.
#### error
type: `function`
default: `() => null`
A string enum. Possible values:
- `media_aborted`
- `permission_denied`
- `no_specified_media_found`
- `media_in_use`
- `invalid_media_constraints`
- `no_constraints`
- `recorder_error`
#### status
A string `enum`. Possible values:
- `media_aborted`
- `permission_denied`
- `no_specified_media_found`
- `media_in_use`
- `invalid_media_constraints`
- `no_constraints`
- `recorder_error`
- `idle`
- `acquiring_media`
- `recording`
- `stopping`
- `stopped`
#### startRecording
A `function`, which starts recording when invoked.
#### pauseRecording
A `function`, which pauses the recording when invoked.
#### resumeRecording
A `function`, which resumes the recording when invoked.
#### stopRecording
A `function`, which stops recording when invoked.
#### muteAudio
A `function`, which mutes the audio tracks when invoked.
#### unmuteAudio
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.
#### isMuted
A boolean prop that tells whether the audio is muted or not.
## Contributing

@@ -169,0 +174,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc