前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebRTC网页打开摄像头并录制视频

WebRTC网页打开摄像头并录制视频

作者头像
落寞的鱼丶
发布2022-02-26 20:07:54
1.6K0
发布2022-02-26 20:07:54
举报
文章被收录于专栏:afjhahfhahajk

前面我们能打开本地摄像头,并且在网页上看到摄像头的预览图像。 本文我们使用MediaRecorder来录制视频。在网页上播放录制好的视频,并能提供下载功能。

html#

首先创建一个html界面,放上一些元素

代码语言:javascript
复制
    <video id="v1" playsinline autoplay muted></video>
    <video id="v2" playsinline loop></video>

    <div>
        <button id="startCamera">开启摄像头</button>
        <button id="stopCamera">停止摄像头</button>
        <button id="record" disabled>录制</button>
        <button id="play" disabled>播放</button>
        <button id="download" disabled>下载视频</button>
    </div>
    <div> 录制使用的视频格式: <select id="codecSelect" disabled></select> </div>
    <div>
        <h4>视频设置</h4>
        <p>回声消除: <input type="checkbox" id="echoCancellation"></p>
    </div>
    <div> <span id="msg" style="font-size:smaller"></span> </div>

    <!-- 使用本地的适配器 -->
    <script src="../js/adapter-latest.js" async></script>
  • video
    • v1 用来预览
    • v2 用来播放录制好的视频
  • button 控制摄像头开启、录制,下载等等
  • select 选择录制用的视频格式
  • input 选择回声消除

js#

准备#

先把界面上的元素拿到

代码语言:javascript
复制
'use strict';

let mediaRecorder;
let recordedBlobs; // 录制下来的内容
let isRecording = false;

// 先把页面元素拿到
const startCameraBtn = document.querySelector('button#startCamera'); // 启动摄像头按钮
const stopCameraBtn = document.querySelector('button#stopCamera');
const recordBtn = document.querySelector('button#record'); // 开始录制按钮
const playBtn = document.querySelector('button#play');     // 播放按钮
const downloadBtn = document.querySelector('button#download'); // 下载视频按钮
const codecSelector = document.querySelector('#codecSelect'); // 选择格式
const msgEle = document.querySelector('span#msg');         // 显示消息
const previewV1 = document.querySelector('video#v1'); // 预览用的
const recordedV2 = document.querySelector('video#v2');  // 用来播放录制好的视频

视频支持的格式#

先预定几个可能的格式,然后一个个来判断是否支持。找到支持的格式。

代码语言:javascript
复制
function getSupportedMimeTypes() {
  const possibleTypes = [
    'video/webm;codecs=vp9,opus',
    'video/webm;codecs=vp8,opus',
    'video/webm;codecs=h264,opus',
    'video/mp4;codecs=h264,aac',
  ];
  return possibleTypes.filter(mimeType => {
    return MediaRecorder.isTypeSupported(mimeType);
  });
}

开启摄像头#

同样要使用getUserMedia方法。这里给视频指定了宽高。回声消除是可选项。

代码语言:javascript
复制
// 启动摄像头
startCameraBtn.addEventListener('click', async () => {
  startCameraBtn.disabled = true;
  const isEchoCancellation = document.querySelector('#echoCancellation').checked;
  const constraints = {
    audio: {
      echoCancellation: { exact: isEchoCancellation }
    },
    video: {
      width: 1280, height: 720
    }
  };
  await init(constraints);
});

async function init(constraints) {
  try {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    gotStream(stream);
  } catch (e) {
    showMsg(`navigator.getUserMedia error:${e.toString()}`);
  }
}

function gotStream(stream) {
  recordBtn.disabled = false;
  showMsg('拿到了 stream:', stream);
  window.stream = stream;
  previewV1.srcObject = stream;

  // 重置
  var codecOption = codecSelector.lastChild;
  while (codecOption != null) {
    codecSelector.removeChild(codecOption);
    codecOption = codecSelector.lastChild;
  }

  getSupportedMimeTypes().forEach(mimeType => {
    const option = document.createElement('option');
    option.value = mimeType;
    option.innerText = option.value;
    codecSelector.appendChild(option);
  });
  codecSelector.disabled = false; // 可以进行选择了
}

下面是停止摄像头的方法

代码语言:javascript
复制
stopCameraBtn.addEventListener('click', () => {
  var stream = previewV1.srcObject;
  if (stream == null) {
    return;
  }
  const tracks = stream.getTracks();
  tracks.forEach(function (track) {
    track.stop();
  });
  previewV1.srcObject = null;
  window.stream = null;
  codecSelector.disabled = true;
  startCameraBtn.disabled = false;
});

开始录制#

开始录制视频

代码语言:javascript
复制
function startRecording() {
  recordedBlobs = [];
  const mimeType = codecSelector.options[codecSelector.selectedIndex].value;
  const options = { mimeType };

  try {
    mediaRecorder = new MediaRecorder(window.stream, options);
  } catch (e) {
    showMsg(`创建MediaRecorder出错: ${JSON.stringify(e)}`);
    return;
  }

  showMsg('创建MediaRecorder', mediaRecorder, ' -> options', options);
  recordBtn.textContent = '停止录制';
  isRecording = true;
  playBtn.disabled = true;
  downloadBtn.disabled = true;
  codecSelector.disabled = true;
  mediaRecorder.onstop = (event) => {
    showMsg('录制停止了: ' + event);
    showMsg('录制的数据Blobs: ' + recordedBlobs);
  };
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start();
  showMsg('录制开始 mediaRecorder: ' + mediaRecorder);
}

function handleDataAvailable(event) {
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}

recordBtn.addEventListener('click', () => {
  if (isRecording == false) {
    startRecording();
  } else {
    stopRecording();
    recordBtn.textContent = '开始录制';
    playBtn.disabled = false;
    downloadBtn.disabled = false;
    codecSelector.disabled = false;
  }
});
  • 重置录制内容recordedBlobs = []
  • 拿到选定的视频格式mimeType
  • 新建MediaRecorder对象,传入前面获取到的流
  • 处理各个按钮(ui)的状态
  • mediaRecorder
    • 设置停止监听器 onstop
    • 监听录制数据 ondataavailable,有数据来的时候存放在recordedBlobs
    • 启动录制 mediaRecorder.start()

停止录制#

代码语言:javascript
复制
function stopRecording() {
  mediaRecorder.stop();
}

播放录制好的视频#

录制好的视频内容存放在recordedBlobs。新建Blob,交给video(recordedV2)来播放

代码语言:javascript
复制
playBtn.addEventListener('click', () => {
  const mimeType = codecSelector.options[codecSelector.selectedIndex].value.split(';', 1)[0];
  const superBuffer = new Blob(recordedBlobs, { type: mimeType });
  recordedV2.src = null;
  recordedV2.srcObject = null;
  recordedV2.src = window.URL.createObjectURL(superBuffer);
  recordedV2.controls = true;
  recordedV2.play();
});

下载视频#

录制好的视频内容存放在recordedBlobs

代码语言:javascript
复制
downloadBtn.addEventListener('click', () => {
  const blob = new Blob(recordedBlobs, { type: 'video/webm' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = '视频_' + new Date().getTime() + '.webm';
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
});

新建Blob和一个a元素。根据blob创建ObjectURL,并传给a元素的href。 修改下载文件的默认名字a.download。 触发a元素的click(),即能让浏览器下载这个文件。

延迟把这个a移除掉。

小结#

getUserMedia()开启视频拿到视频流。MediaRecorder录制视频。用Blob来播放和下载。 实现一个小的录制视频效果。视频数据缓存在对象里。

完整的效果请参考 视频录制

原文链接

作者:AnRFDev

出处:https://www.cnblogs.com/rustfisher/p/15637449.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • html#
  • js#
    • 准备#
      • 视频支持的格式#
        • 开启摄像头#
          • 开始录制#
            • 停止录制#
              • 播放录制好的视频#
                • 下载视频#
                • 小结#
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档