PC端调用摄像头录制视频——vue标准写法

在PC端调用摄像头录制视频,传给后端生成链接。

说说最近做的这个功能的需求,就是简单的在PC端调起摄像头功能(非笔记本使用usb接口的摄像头),录制一个实时的视频,将录制的这个视频传递给后端生成一个链接展示。网上搜索了很多也没搜到满意的答案。最终只能自己来总结一下这个踩过了的坑。。。

实现步骤:

1.客户端的浏览器需要设置允许摄像头和麦克风的权限

2.使用原生js里面navigato中的mediaDevices属性去获取到视频流。

3.将获取的视频流转为file,再将file使用formData的方式传递给后端。

上代码(代码及属性介绍):

1、这是使用navigato、mediaDevices、getUserMedia的这几个属性判断浏览器是否开启摄像头、麦克风等,这一段代码网上有很多,就是对以上三个属性兼容性的方法封装。
  属性介绍(MDN官方介绍):
  
navigato: navigato接口表示用户代理的状态和标识。 它允许脚本查询它和注册自己进行一些活动。

mediaDevices: mediaDevices是navigator 只读属性,返回一个mediaDevices对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。

getUserMedia: mediaDevices.getUserMedia()会提示用户给予使用媒体输入的许可,媒体输入会产生一个mediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
getCompetence() {
      // 确保在页面渲染完毕后获取DOM
      this.$nextTick(() => {
        this.open = false; //切换成关闭摄像头
        //我这是使用原生获取元素,可以使用vue的this.$refs.xxx
        this.thisCancas = document.getElementById("canvasCamera");
        this.thisContext = this.thisCancas.getContext("2d");
        this.thisVideo = document.getElementById("videoCamera");
        this.thisVideoData = document.getElementById("videoCameraData");//录像时的video

        // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
        if (navigator.mediaDevices === undefined) {
          navigator.mediaDevices = {};
        }

        // 部分浏览器实现了mediaDevices,使用getUserMedia进行覆盖现有属性,如果缺少getUserMedia属性,就进行添加
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = (constraints) => {
            // 获取不同浏览器getUserMedia属性(兼容写法)
            let getUserMedia =
            navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia;

            // 浏览器不支持,返回错误信息
            if (!getUserMedia) {
              //不支持getUserMedia时,同意返回错误信息
              return Promise.reject(
                new Error("此浏览器中未实现getUserMedia,不能调用摄像头")
              );
            }

            // 支持getUserMedia时,使用Promise将调用包装到旧的navigator.getUserMedia
            return new Promise((resolve, reject) => {
            getUserMedia.call(navigator, constraints, resolve, reject);
            });
          };
        }

        
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = (constraints) => {
            // 首先获取现存的getUserMedia(如果存在)
            let getUserMedia =
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.getUserMedia;
            // 有些浏览器不支持,会返回错误信息
            // 保持接口一致
            if (!getUserMedia) {
              return Promise.reject(
                new Error("getUserMedia is not implemented in this browser")
              );
            }
            // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
            return new Promise((resolve, reject) => {
                getUserMedia.call(navigator, constraints, resolve, reject);
            });
          };
        }

        const constraints = {
          //定义constraints:video和audio需要开启
          audio: true,
          video: {
            width: this.videoWidth,
            height: this.videoHeight,
            transform: "scaleX(-1)",
          },
        };
        navigator.mediaDevices
        .getUserMedia(constraints)
        .then((stream) => {
          // 旧的浏览器可能没有srcObject
          if ("srcObject" in this.thisVideo) {
            this.thisVideo.srcObject = stream;
          } else {
            // 避免在新的浏览器中使用它,新浏览器正在被弃用。没有开启摄像头权限或浏览器版本不兼容
            this.thisVideo.src = window.URL.createObjectURL(stream);
          }

          this.thisVideo.onloadedmetadata = (e) => {
            this.thisVideo.play();
          };

          
          // 录制视频窗口(这个窗口是录制视频时显示的窗口)
          this.$refs.videoCameraData.srcObject = stream;
          this.$refs.videoCameraData.play();
          this.startRecording(stream);//调用录制控件方法,触发开始录制
          
        })
        .catch((err) => {
          // 没有摄像头弹窗
          this.isHave = false;
          this.$alert(
            "请在有摄像头的电脑上允许浏览器中的隐私设置使用摄像头,建议使用IE10以上及最新版谷歌、QQ、火狐等游浏览器观看网络课程。",
          );
        });
      });
    },

以上这段代码可以百度搜索到,这是获取到摄像头权限的原生方法。

2、就是控制录制视频开始和结束方法的操作,在正常获取到了摄像头和麦克风权限时触发。
属性介绍:

**mediaRecorde**r:MediaRecorder()构造函数会创建一个mediaStream进行录制的MediaRecorder对象。mediaRecorder可以很好的捕获到媒体流。

**mediaRecorder**的参数:
	stream:mediaStream将要录制的媒体流,它可以来自于使用navigato.mediaDevices.getUserMedia()创建的流(如:视频流获取音频流等媒体流)。

**mediaRecorder**的方法:

	start:开始将媒体流记录到一个或多个Buffer,得到的这个Buffer就是所捕获到的媒体流.

	dataavailable:出发了开始录制,当数据有效时会触发这个方法,将数据存储在缓冲区,可以传event和data,此刻的data为真实的数据,也就是最终所捕获到的媒体流数据。

	stop:停止录制,会触发最终Blob数据的dataavailable方法。
startRecording(stream) {
      // console.log(stream,"stream");
      // this.logger();
      this.mediaRecorderData = new MediaRecorder(stream);

      this.mediaRecorderData.start();

      this.mediaRecorderData.addEventListener("dataavailable", (e)=> {
        if (e.data.size > 0) {
          this.videoCecorded.push(e.data);//视频录制视频流数据
        };
      });

      this.mediaRecorderData.addEventListener("stop", ()=>{
        // console.log("暂停 自动下载");
        if(this.videoStatus != 1){
            this.updataVideo();//上传实时录制的视频
        }
      });

      this.mediaRecorderData.addEventListener("start", (e) => {
        // console.log("开始 录制");
      });
3.获取到数据与后台进行交互。
    字段介绍:
		videoCecorded:这是一个数组,将dataavailable方法中获取到的真实数据流获取到。然后将这个数据转为file,再将这个file使用formData的形式传给后端(我这最终后端会返回一个线上的视频链接)。

// 结束录制视频,触发基数录制视频事件
stopLive() {
   // console.log(this.mediaRecorderData,"this.mediaRecorderData");
   if (this.mediaRecorderData) { 
   	this.mediaRecorderData.stop();
   } 
},

// 上传录制视频方法,获取视频地址
updata(){
     var file = new File(this.videoCecorded, 'video-' + (new Date).toISOString().replace(/:|\./g, '-') + '.mp4', {
         type: 'video/mp4'
     });

     let data = new FormData();
     data.append('file', file);    
     return uploadVideoFile(data).then(res=>{
       return this.recordVideoUrl = res.url;//获取上传的视频地址
     })
   }

写在最后,这是本人自己踩过的坑,已经成功解决,期间也花费了一些事件,不过最终还是跨过去了,在此与大家共勉,如果对你有帮助,请使用,如有疑问可以留眼,会及时回复提供力所能及的帮助。

  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 37
    评论
抱歉,我是一个语言模型AI,我没有能力调用摄像头录制视频。不过,您可以尝试使用WebRTC技术来实现在浏览器端调用摄像头录制视频。在Vue中,可以使用vue-webrtc库来实现。这个库提供了一些Vue组件,可以方便地实现WebRTC功能。以下是实现WebRTC录制视频的基本步骤: 1. 安装vue-webrtc库 运行以下命令: ``` npm install vue-webrtc --save ``` 2. 在Vue组件中导入vue-webrtc 在组件中引入vue-webrtc: ```javascript import { Webrtc } from 'vue-webrtc' ``` 3. 在组件中使用Webrtc元素 在组件的template中添加Webrtc元素,用于显示摄像头捕获的视频: ```html <template> <div> <webrtc :autoPlay="true"></webrtc> </div> </template> ``` 4. 实现录制视频功能 使用MediaRecorder API来录制视频: ```javascript let mediaRecorder = null let chunks = [] function startRecording() { const stream = this.$refs.webrtc.getStream() mediaRecorder = new MediaRecorder(stream) mediaRecorder.ondataavailable = function(e) { chunks.push(e.data) } mediaRecorder.onstop = function() { const blob = new Blob(chunks, { type: 'video/mp4' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = 'recording.mp4' a.click() chunks = [] } mediaRecorder.start() } function stopRecording() { mediaRecorder.stop() } ``` 这个例子中,我们使用MediaRecorder API来捕获摄像头视频,并将录制的数据保存到Blob对象中。最后,我们将Blob对象转换为URL,并创建一个链接,使用户可以下载录制视频
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值