飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

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

时间:2021-12-03  作者:rustfisher  

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

html

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

    <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-域名" async></script>
  • video
    • v1 用来预览
    • v2 用来播放录制好的视频
  • button 控制摄像头开启、录制,下载等等
  • select 选择录制用的视频格式
  • input 选择回声消除

js

准备

先把界面上的元素拿到

\'use strict\';

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

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

视频支持的格式

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

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 域名er(mimeType => {
    return 域名peSupported(mimeType);
  });
}

开启摄像头

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

// 启动摄像头
域名ventListener(\'click\', async () => {
  域名bled = true;
  const isEchoCancellation = 域名ySelector(\'#echoCancellation\').checked;
  const constraints = {
    audio: {
      echoCancellation: { exact: isEchoCancellation }
    },
    video: {
      width: 1280, height: 720
    }
  };
  await init(constraints);
});

async function init(constraints) {
  try {
    const stream = await 域名serMedia(constraints);
    gotStream(stream);
  } catch (e) {
    showMsg(`域名serMedia error:${域名ring()}`);
  }
}

function gotStream(stream) {
  域名bled = false;
  showMsg(\'拿到了 stream:\', stream);
  域名am = stream;
  域名bject = stream;

  // 重置
  var codecOption = 域名Child;
  while (codecOption != null) {
    域名veChild(codecOption);
    codecOption = 域名Child;
  }

  getSupportedMimeTypes().forEach(mimeType => {
    const option = 域名teElement(\'option\');
    域名e = mimeType;
    域名rText = 域名e;
    域名ndChild(option);
  });
  域名bled = false; // 可以进行选择了
}

下面是停止摄像头的方法

域名ventListener(\'click\', () => {
  var stream = 域名bject;
  if (stream == null) {
    return;
  }
  const tracks = 域名racks();
  域名ach(function (track) {
    域名();
  });
  域名bject = null;
  域名am = null;
  域名bled = true;
  域名bled = false;
});

开始录制

开始录制视频

function startRecording() {
  recordedBlobs = [];
  const mimeType = 域名ons[域名ctedIndex].value;
  const options = { mimeType };

  try {
    mediaRecorder = new MediaRecorder(域名am, options);
  } catch (e) {
    showMsg(`创建MediaRecorder出错: ${域名ngify(e)}`);
    return;
  }

  showMsg(\'创建MediaRecorder\', mediaRecorder, \' -> options\', options);
  域名Content = \'停止录制\';
  isRecording = true;
  域名bled = true;
  域名bled = true;
  域名bled = true;
  域名op = (event) => {
    showMsg(\'录制停止了: \' + event);
    showMsg(\'录制的数据Blobs: \' + recordedBlobs);
  };
  域名taavailable = handleDataAvailable;
  域名t();
  showMsg(\'录制开始 mediaRecorder: \' + mediaRecorder);
}

function handleDataAvailable(event) {
  if (域名 && 域名 > 0) {
    域名(域名);
  }
}

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

停止录制

function stopRecording() {
  域名();
}

播放录制好的视频

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

域名ventListener(\'click\', () => {
  const mimeType = 域名ons[域名ctedIndex].域名t(\';\', 1)[0];
  const superBuffer = new Blob(recordedBlobs, { type: mimeType });
  域名 = null;
  域名bject = null;
  域名 = 域名teObjectURL(superBuffer);
  域名rols = true;
  域名();
});

下载视频

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

域名ventListener(\'click\', () => {
  const blob = new Blob(recordedBlobs, { type: \'video/webm\' });
  const url = 域名teObjectURL(blob);
  const a = 域名teElement(\'a\');
  域名lay = \'none\';
  域名 = url;
  域名load = \'视频_\' + new Date().getTime() + \'.webm\';
  域名ndChild(a);
  域名k();
  setTimeout(() => {
    域名veChild(a);
    域名keObjectURL(url);
  }, 100);
});

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

延迟把这个a移除掉。

小结

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

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

原文链接

标签:Web编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。