UNPKG

@mastashake08/vue-4k-camera-recorder

Version:

A Vue 3 component using MediaRecorder and MediaCapabilities API to record 4K video from the user's camera.

3 lines (2 loc) 7.06 kB
(function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.Vue4kCameraRecorder={},u.Vue))})(this,function(u,e){"use strict";const V=(k,m)=>{const r=k.__vccOpts||k;for(const[y,t]of m)r[y]=t;return r},S={class:"camera-recorder"},T={key:0,class:"error"},B={key:1},M={class:"status"},D={key:0},I={class:"controls"},O=["disabled"],P=["disabled"],U=["disabled"],$={class:"video-container"},K={key:0,class:"download-section"},F=["href","download"],R=3840,h=2160,b=30,_=50*1e3*1e3,w=V({__name:"CameraRecorder",setup(k){const m=["video/webm;codecs=vp9","video/webm;codecs=av01","video/mp4;codecs=h264","video/webm;codecs=vp8"],r=e.ref(null),y=e.ref(null),t=e.ref(null),s=e.ref(null),E=e.ref([]),v=e.ref(null),n=e.ref(!1),c=e.ref(!1),l=e.ref("Idle. Check support first."),d=e.ref(null),p=e.ref(""),C=e.computed(()=>"mediaDevices"in navigator&&"getUserMedia"in navigator.mediaDevices&&"MediaRecorder"in window&&"mediaCapabilities"in navigator),g=e.computed(()=>{var a;return((a=d.value)==null?void 0:a.supported)??!1}),N=e.computed(()=>{var i;const a=new Date().toISOString().replace(/[:.]/g,"-"),o=((i=p.value)==null?void 0:i.split(";")[0].split("/")[1])||"webm";return`recording-4k-${a}.${o}`});async function j(){if(!C.value){l.value="Browser lacks necessary API support.";return}c.value=!0,l.value="Checking 4K recording capabilities...",d.value=null,p.value="";let a=!1;for(const o of m){const i={contentType:o,width:R,height:h,bitrate:_,framerate:b};try{const f=await navigator.mediaCapabilities.encodingInfo({type:"record",video:i});if(console.log(`Checking ${o}:`,f),f.supported){d.value={supported:!0,config:i,powerEfficient:f.powerEfficient,smooth:f.smooth},p.value=o,l.value=`4K recording check complete. Supported (${o}).`,a=!0;break}}catch(f){console.error(`Error checking capabilities for ${o}:`,f),a||(d.value={supported:!1,reason:`${o}: ${f.message}`})}}a||(l.value="4K recording check complete. No suitable configuration found.",d.value||(d.value={supported:!1,reason:"Failed to check any configuration."})),c.value=!1}async function A(){if(!g.value||!p.value){l.value="Cannot start: 4K recording not supported or not checked.";return}if(!n.value){v.value=null,E.value=[],c.value=!0,l.value="Requesting camera access...";try{t.value=await navigator.mediaDevices.getUserMedia({audio:!0,video:{width:{ideal:R},height:{ideal:h},frameRate:{ideal:b}}}),l.value="Camera access granted. Starting recorder...",r.value&&(r.value.srcObject=t.value,r.value.captureStream=r.value.captureStream||r.value.mozCaptureStream,await r.value.play());const a={mimeType:p.value,videoBitsPerSecond:_};if(!MediaRecorder.isTypeSupported(a.mimeType))throw console.warn(`MediaRecorder does not support ${a.mimeType}, falling back or failing.`),new Error(`MediaRecorder reported unsupported mimeType: ${a.mimeType}`);s.value=new MediaRecorder(t.value,a),s.value.ondataavailable=o=>{o.data&&o.data.size>0&&E.value.push(o.data)},s.value.onstop=()=>{l.value="Recording stopped. Processing video...";const o=new Blob(E.value,{type:p.value});v.value=URL.createObjectURL(o),n.value=!1,c.value=!1,l.value="Processing complete. Download ready.",t.value&&(t.value.getTracks().forEach(i=>i.stop()),t.value=null),r.value&&(r.value.srcObject=null)},s.value.onerror=o=>{console.error("MediaRecorder Error:",o.error),l.value=`Recording Error: ${o.error.name||"Unknown error"}`,n.value=!1,c.value=!1,t.value&&(t.value.getTracks().forEach(i=>i.stop()),t.value=null),r.value&&(r.value.srcObject=null)},s.value.start(),n.value=!0,c.value=!1,l.value="Recording 4K video..."}catch(a){console.error("Error starting recording:",a);let o="Failed to start recording.";a.name==="NotAllowedError"?o="Permission denied. Please allow camera/microphone access.":a.name==="NotFoundError"?o="No camera/microphone found.":a.name==="NotReadableError"?o="Camera/microphone is already in use or hardware error.":a.name==="OverconstrainedError"?o=`Could not satisfy constraints (e.g., 4K resolution not supported by device): ${a.constraint}`:a.message.includes("MediaRecorder reported unsupported mimeType")&&(o=a.message),l.value=o,c.value=!1,n.value=!1,t.value&&(t.value.getTracks().forEach(i=>i.stop()),t.value=null)}}}function L(){!n.value||!s.value||(l.value="Stopping recording...",s.value.stop())}return e.onMounted(()=>{}),e.onUnmounted(()=>{n.value&&s.value&&s.value.stop(),t.value&&t.value.getTracks().forEach(a=>a.stop()),v.value&&URL.revokeObjectURL(v.value)}),(a,o)=>(e.openBlock(),e.createElementBlock("div",S,[o[5]||(o[5]=e.createElementVNode("h2",null,"4K Camera Recorder",-1)),C.value?(e.openBlock(),e.createElementBlock("div",B,[e.createElementVNode("div",M,[e.createElementVNode("p",null,"Status: "+e.toDisplayString(l.value),1),d.value!==null?(e.openBlock(),e.createElementBlock("p",D,[o[0]||(o[0]=e.createTextVNode(" 4K High-Bitrate Recording Supported: ")),e.createElementVNode("span",{class:e.normalizeClass(g.value?"supported":"not-supported")},[e.createTextVNode(e.toDisplayString(g.value?"Yes":"No")+" ",1),g.value&&p.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(" (Using: "+e.toDisplayString(p.value)+")",1)],64)):e.createCommentVNode("",!0),!g.value&&d.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(" (Reason: "+e.toDisplayString(d.value.reason||"Unsupported configuration")+")",1)],64)):e.createCommentVNode("",!0)],2)])):e.createCommentVNode("",!0)]),e.createElementVNode("div",I,[e.createElementVNode("button",{onClick:j,disabled:c.value||n.value}," Check 4K Support ",8,O),n.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,onClick:A,disabled:c.value||n.value||!g.value}," Start 4K Recording ",8,P)),n.value?(e.openBlock(),e.createElementBlock("button",{key:1,onClick:L,disabled:!n.value}," Stop Recording ",8,U)):e.createCommentVNode("",!0)]),e.createElementVNode("div",$,[o[1]||(o[1]=e.createElementVNode("h3",null,"Preview",-1)),e.createElementVNode("video",{ref_key:"videoPreviewRef",ref:r,autoplay:"",muted:"",playsinline:""},null,512)]),v.value?(e.openBlock(),e.createElementBlock("div",K,[o[2]||(o[2]=e.createElementVNode("h3",null,"Recording Complete",-1)),o[3]||(o[3]=e.createElementVNode("p",null,"Download your recording:",-1)),e.createElementVNode("a",{href:v.value,download:N.value,ref_key:"downloadLinkRef",ref:y},e.toDisplayString(N.value),9,F),o[4]||(o[4]=e.createElementVNode("p",null,"(File size might be very large)",-1))])):e.createCommentVNode("",!0)])):(e.openBlock(),e.createElementBlock("div",T," Required APIs (getUserMedia, MediaRecorder, MediaCapabilities) are not fully supported by your browser. "))]))}},[["__scopeId","data-v-40afb732"]]),x={install:(k,m)=>{const r=(m==null?void 0:m.componentName)||"CameraRecorder";k.component(r,w)}};u.CameraRecorder=w,u.default=x,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); //# sourceMappingURL=vue-4k-camera-recorder.umd.js.map