@pineappleaf/react-media-recorder
Version:
A React component based on MediaRecorder() API to record audio/video streams
24 lines • 11.9 kB
JavaScript
;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});exports.useReactMediaRecorder=exports.RecorderErrors=exports.useQueryMediaPermissions=exports.isSupported=exports.MediaPermissions=void 0;var react_1=require("react");var MediaPermissions;(function(MediaPermissions){MediaPermissions["Granted"]="granted";MediaPermissions["Denied"]="denied";MediaPermissions["Prompt"]="prompt";})(MediaPermissions=exports.MediaPermissions||(exports.MediaPermissions={}));function isSupported(){var _a,_b;return(!!((_b=(_a=window===null||window===void 0?void 0:window.navigator)===null||_a===void 0?void 0:_a.mediaDevices)===null||_b===void 0?void 0:_b.getUserMedia)||!!(window===null||window===void 0?void 0:window.MediaRecorder)||!!(window===null||window===void 0?void 0:window.localStorage));}
exports.isSupported=isSupported;var MEDIA_PERMISSIONS_KEY="react-media-recorder.media-permissions";function setLocalMediaPermissions(permissions){window.localStorage.setItem(MEDIA_PERMISSIONS_KEY,permissions);}
function getLocalMediaPermissions(){var permissions=window.localStorage.getItem(MEDIA_PERMISSIONS_KEY);switch(permissions){case MediaPermissions.Granted:return permissions;default:return MediaPermissions.Prompt;}}
function useQueryMediaPermissions(){var _this=this;return react_1.useCallback(function(){return __awaiter(_this,void 0,void 0,function(){var microphone,camera,error_1;return __generator(this,function(_a){switch(_a.label){case 0:_a.trys.push([0,3,,4]);return[4,window.navigator.permissions.query({name:"microphone",})];case 1:microphone=_a.sent();return[4,window.navigator.permissions.query({name:"camera",})];case 2:camera=_a.sent();if(camera.state==="granted"&µphone.state==="granted"){return[2,MediaPermissions.Granted];}
if(camera.state==="prompt"||microphone.state==="prompt"){return[2,MediaPermissions.Prompt];}
return[2,MediaPermissions.Denied];case 3:error_1=_a.sent();return[2,getLocalMediaPermissions()];case 4:return[2];}});});},[]);}
exports.useQueryMediaPermissions=useQueryMediaPermissions;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["UnsupportedBrowserError"]="unsupported_browser";})(RecorderErrors=exports.RecorderErrors||(exports.RecorderErrors={}));function useReactMediaRecorder(_a){var _this=this;var _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,_e=_a.onStart,onStart=_e===void 0?function(){return null;}:_e,blobPropertyBag=_a.blobPropertyBag,_f=_a.screen,screen=_f===void 0?false:_f,_g=_a.mediaRecorderOptions,mediaRecorderOptions=_g===void 0?null:_g,_h=_a.customMediaStream,customMediaStream=_h===void 0?null:_h,_j=_a.stopStreamsOnStop,stopStreamsOnStop=_j===void 0?true:_j,_k=_a.recorderTimeslice,recorderTimeslice=_k===void 0?100:_k;var _l=react_1.useState(MediaPermissions.Prompt),mediaPermissions=_l[0],setMediaPermissions=_l[1];var queryMediaPermissions=useQueryMediaPermissions();react_1.useEffect(function(){(function(){return __awaiter(_this,void 0,void 0,function(){var _a;return __generator(this,function(_b){switch(_b.label){case 0:_a=setMediaPermissions;return[4,queryMediaPermissions()];case 1:_a.apply(void 0,[_b.sent()]);return[2];}});});})();},[]);var mediaRecorder=react_1.useRef(null);var mediaChunks=react_1.useRef([]);var _m=react_1.useState(null),mediaStream=_m[0],setMediaStream=_m[1];var _o=react_1.useState("idle"),status=_o[0],setStatus=_o[1];var _p=react_1.useState(false),isAudioMuted=_p[0],setIsAudioMuted=_p[1];var _q=react_1.useState(null),mediaBlobUrl=_q[0],setMediaBlobUrl=_q[1];var _r=react_1.useState("NONE"),error=_r[0],setError=_r[1];var getMediaStream=react_1.useCallback(function(){return __awaiter(_this,void 0,void 0,function(){var requiredMedia,stream_1,audioStream,stream,err_1;return __generator(this,function(_a){switch(_a.label){case 0:setStatus("acquiring_media");requiredMedia={audio:typeof audio==="boolean"?!!audio:audio,video:typeof video==="boolean"?!!video:video,};_a.label=1;case 1:_a.trys.push([1,9,,10]);if(!customMediaStream)return[3,2];setMediaStream(customMediaStream);return[3,8];case 2:if(!screen)return[3,6];return[4,window.navigator.mediaDevices.getDisplayMedia({video:video||true,})];case 3:stream_1=(_a.sent());if(!audio)return[3,5];return[4,window.navigator.mediaDevices.getUserMedia({audio:audio,})];case 4:audioStream=_a.sent();audioStream.getAudioTracks().forEach(function(audioTrack){stream_1.addTrack(audioTrack);});_a.label=5;case 5:setMediaStream(stream_1);return[3,8];case 6:return[4,window.navigator.mediaDevices.getUserMedia(requiredMedia)];case 7:stream=_a.sent();setMediaStream(stream);_a.label=8;case 8:setLocalMediaPermissions(MediaPermissions.Granted);setMediaPermissions(MediaPermissions.Granted);setStatus("idle");return[3,10];case 9:err_1=_a.sent();setLocalMediaPermissions(MediaPermissions.Prompt);setMediaPermissions(MediaPermissions.Denied);setError(err_1.name);setStatus("idle");return[3,10];case 10:return[2];}});});},[audio,video,screen]);react_1.useEffect(function(){if(!window.MediaRecorder){setError("UnsupportedBrowserError");return;}
if(screen){if(!window.navigator.mediaDevices.getDisplayMedia){setError("UnsupportedBrowserError");return;}}
var checkConstraints=function(mediaType){var supportedMediaConstraints=navigator.mediaDevices.getSupportedConstraints();var unSupportedConstraints=Object.keys(mediaType).filter(function(constraint){return!supportedMediaConstraints[constraint];});if(unSupportedConstraints.length>0){return new Error("The constraints "+unSupportedConstraints.join(",")+" doesn't support on this browser. Please check your ReactMediaRecorder component.");}
return null;};if(typeof audio==="object"){checkConstraints(audio);}
if(typeof video==="object"){checkConstraints(video);}
if(mediaRecorderOptions&&mediaRecorderOptions.mimeType){if(!MediaRecorder.isTypeSupported(mediaRecorderOptions.mimeType)){console.warn("The specified MIME type you supplied for MediaRecorder doesn't support this browser");}}},[audio,screen,video]);var startMediaStream=react_1.useCallback(function(){return __awaiter(_this,void 0,void 0,function(){return __generator(this,function(_a){switch(_a.label){case 0:if(!!mediaStream)return[3,2];return[4,getMediaStream()];case 1:_a.sent();_a.label=2;case 2:return[2];}});});},[mediaStream,getMediaStream]);var onRecordingStart=react_1.useCallback(function(){onStart();},[onStart]);var onRecordingStop=react_1.useCallback(function(){var blob=new Blob(mediaChunks.current,blobPropertyBag);var url=URL.createObjectURL(blob);setStatus("stopped");setMediaBlobUrl(url);onStop(url,blob);},[mediaChunks,setMediaBlobUrl,onStop,setStatus,mediaRecorder,blobPropertyBag,]);var muteAudio=react_1.useCallback(function(mute){setIsAudioMuted(mute);mediaStream===null||mediaStream===void 0?void 0:mediaStream.getAudioTracks().forEach(function(audioTrack){audioTrack.enabled=!mute;});},[setIsAudioMuted,mediaStream]);var pauseRecording=react_1.useCallback(function(){if(mediaRecorder.current&&mediaRecorder.current.state==="recording"){mediaRecorder.current.pause();}},[mediaRecorder.current]);var resumeRecording=react_1.useCallback(function(){if(mediaRecorder.current&&mediaRecorder.current.state==="paused"){mediaRecorder.current.resume();}},[mediaRecorder.current]);var onRecordingActive=react_1.useCallback(function(_a){var data=_a.data;mediaChunks.current.push(data);},[mediaChunks.current]);var stopRecording=react_1.useCallback(function(){if(mediaRecorder.current){if(mediaRecorder.current.state!=="inactive"){setStatus("stopping");mediaRecorder.current.stop();if(stopStreamsOnStop){mediaStream===null||mediaStream===void 0?void 0:mediaStream.getTracks().forEach(function(track){return track.stop();});}}}},[mediaRecorder.current,setStatus,stopStreamsOnStop]);var startRecording=react_1.useCallback(function(){return __awaiter(_this,void 0,void 0,function(){var isStreamEnded;return __generator(this,function(_a){switch(_a.label){case 0:setError("NONE");if(!mediaStream)return[3,3];isStreamEnded=mediaStream.getTracks().some(function(track){return track.readyState==="ended";});if(!isStreamEnded)return[3,2];return[4,getMediaStream()];case 1:_a.sent();_a.label=2;case 2:mediaRecorder.current=new MediaRecorder(mediaStream);mediaRecorder.current.ondataavailable=onRecordingActive;mediaRecorder.current.onstop=onRecordingStop;mediaRecorder.current.onstart=onRecordingStart;mediaRecorder.current.onerror=function(){setError("NO_RECORDER");setStatus("idle");};mediaChunks.current=[];mediaRecorder.current.start(recorderTimeslice);setStatus("recording");return[3,4];case 3:throw new Error("cannot record without active media stream");case 4:return[2];}});});},[mediaStream,mediaChunks,setError,setStatus,onRecordingStart,onRecordingStop,onRecordingActive,]);var stopMediaStream=react_1.useCallback(function(){if(mediaStream){mediaStream.getTracks().forEach(function(track){track.stop();});setMediaStream(null);}},[mediaStream,setMediaStream]);return react_1.useMemo(function(){return{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,previewStream:mediaStream,clearBlobUrl:function(){return setMediaBlobUrl(null);},stopMediaStream:stopMediaStream,startMediaStream:startMediaStream,mediaPermissions:mediaPermissions,};},[error,muteAudio,startRecording,stopRecording,pauseRecording,resumeRecording,mediaBlobUrl,status,isAudioMuted,mediaStream,setMediaBlobUrl,startMediaStream,stopMediaStream,mediaPermissions,]);}
exports.useReactMediaRecorder=useReactMediaRecorder;