目录

  • 打开摄像头/关闭摄像头
  • 静音/解除静音
  • 打开视频/关闭视频
  • 截图且下载

打开摄像头/关闭摄像头

效果图

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>打开摄像头</title>
<link rel="stylesheet" href="../../../static/layui/css/layui.css">
</head>
<body>
<div id="container">
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<video id="video-local" autoplay playsinline width="400px" height="400px"></video>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
<button type="button" class="layui-btn layui-btn-danger" onclick="stopVideo()">关闭摄像头</button>
</div>
</div>
<blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
<p>显示摄像头预览的内容,网页上由元素video来呈现。</p>
<p>点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
</blockquote>
</div>
</body>
</html>

javaScript

   let videoElem = document.querySelector('video');

    /**
* MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
* 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
* @param e
* @returns {Promise<void>}
*/
function openCamera() {
if (window.stream != null) {
alert('摄像头已打开,请勿重新打开摄像头');
return false;
}
const constraints = {
audio: true,
video: true
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(error => {
console.error(error)
});
} /**
* 成功获取到流
* @param stream
*/
function gotStream(stream) {
window.stream = stream;
videoEle.srcObject = stream;
} /**
* 关闭摄像头
* 获取到video中的流,并将流中的轨道关闭
*/
function stopVideo() {
// 获取video中的流
const stream = videoElem.srcObject;
// 判断stream 是否为空
if (stream == null) {
return;
}
// 获取流中的所有轨道
const tracks = stream.getTracks();
tracks.forEach(function (track) {
track.stop();
});
videoElem.srcObject = null;
window.stream = null;
}

静音/解除静音

效果图





前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>静音-解除静音</title>
<link rel="stylesheet" href="../../../static/layui/css/layui.css">
</head>
<body>
<div id="container">
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<video id="video-local" autoplay playsinline width="400px" height="400px"></video>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
<button id="mute" type="button" class="layui-btn layui-btn-normal" onclick="muted()">静音</button>
<button id="unmute" type="button" class="layui-btn layui-btn-normal" onclick="unmuted()">解除静音</button>
</div>
</div>
<blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
<p>1.显示摄像头预览的内容,网页上由元素video来呈现。</p>
<p>2.点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
<p>3.打开摄像头获取到浏览器摄像头数据后,可以对获取到的流数据进行静音以及解除静音相关操作</p>
</blockquote>
</div>
</body>
</html>

javaScript

    const constraints = {
audio: true,
video: true
}; let localStream = null;
let videoEle = document.querySelector('video');
/**
* MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
* 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
* @param e
* @returns {Promise<void>}
*/
function openCamera() {
if(localStream!=null){
alert('摄像头已打开,请勿重新打开摄像头');
return false;
}
navigator.mediaDevices.getUserMedia(constraints).then(stream=>{
localStream = stream;
videoEle.srcObject = stream;
}).catch(error=>{
alert('打开摄像头失败');
console.error('打开摄像头失败',error)
});
} function muted() {
if(localStream==null){
alert('请打开音视频');
return false;
}
const tracks = localStream.getTracks();
tracks.forEach(track => {
if(track.kind === 'audio'){
track.enabled = false
}
console.log(track)
});
alert('静音开启,u can`t speak ')
} function unmuted() {
if(localStream==null){
alert('请打开音视频');
return false;
}
const tracks = localStream.getTracks();
tracks.forEach(track => {
if(track.kind === 'audio'){
track.enabled = true
}
console.log(track)
});
alert('解除静音,u can speak ')
}
}

打开视频/关闭视频

效果图

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>打开视频/关闭视频</title>
<link rel="stylesheet" href="../../../static/layui/css/layui.css">
</head>
<body>
<div id="container">
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<video id="video-local" autoplay playsinline width="400px" height="400px"></video>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
<button id="openVideo" type="button" class="layui-btn layui-btn-normal" onclick="openVideo()">打开视频</button>
<button id="closeVideo" type="button" class="layui-btn layui-btn-normal" onclick="closeVideo()">关闭视频</button>
</div>
</div>
<blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
<p>1.显示摄像头预览的内容,网页上由元素video来呈现。</p>
<p>2.点击打开摄像头按钮后,浏览器会询问是否允许,请点击“允许”。</p>
<p>3.打开摄像头获取到浏览器摄像头数据后,可以对获取到的流数据进行打开视频/关闭视频相关操作</p>
</blockquote>
</div> </body>
</html>

javaScript

 const constraints = {
audio: true,
video: true
}; let localStream = null;
let videoEle = document.querySelector('video');
/**
* MediaDevices.getUserMedia()方法在用户允许后,按照请求,拿到stream。 stream可以包含视频或音频。前面的设定里,我们只使用视频。
* 如果用户拒绝了使用摄像头申请,或者申请的媒体不可用,即表现为被拒绝。 用户拒绝会报NotAllowedError,找不到符合要求的设备会报NotFoundError DOMException。
* @param e
* @returns {Promise<void>}
*/
function openCamera() {
if(localStream!=null){
alert('摄像头已打开,请勿重新打开摄像头');
return false;
}
navigator.mediaDevices.getUserMedia(constraints).then(stream=>{
localStream = stream;
videoEle.srcObject = stream;
}).catch(error=>{
alert('打开摄像头失败');
console.error('打开摄像头失败',error)
});
} function openVideo() {
if(localStream==null){
alert('请打开音视频');
return false;
}
const tracks = localStream.getTracks();
tracks.forEach(track => {
if(track.kind === 'video'){
track.enabled = true
}
console.log(track)
});
alert('打开视频,u can see u ')
} function closeVideo() {
if(localStream==null){
alert('请打开音视频');
return false;
}
const tracks = localStream.getTracks();
tracks.forEach(track => {
if(track.kind === 'video'){
track.enabled = false
}
console.log(track)
});
alert('关闭视频,u can`t see u ')
}

视频截图

效果图

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>截屏</title>
<link rel="stylesheet" href="../../../static/layui/css/layui.css"> </head>
<body>
<div id="container">
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<video id="video-local" autoplay playsinline width="400px" height="400px"></video>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs6 layui-col-md12" style="text-align: center">
<button type="button" class="layui-btn layui-btn-normal" onclick="openCamera()">打开摄像头</button>
<button type="button" class="layui-btn layui-btn-normal" onclick="getCapure()">截图</button>
</div>
</div>
<canvas id="mainCanvas"></canvas>
<div id="list" style="display: grid; grid-template-columns: repeat(auto-fill, 100px);
column-gap: 20px; row-gap: 20px;"></div>
<blockquote class="layui-elem-quote layui-text" style="margin-top: 15px;">
<p>1.获取摄像头数据,点击截图,展示截图数据</p>
</blockquote>
</div>
</body>
</html>

javaScript

 const video = document.querySelector('video');
const constraints = {
audio: false,
video: true
}; const list = document.querySelector('#list'); // 拿来存放多个元素 function openCamera() {
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(onError);
} /**
* 成功获取流数据
* @param stream
*/
function gotStream(stream) {
window.stream = stream;
video.srcObject = stream;
}
/**
* 获取流发生错误
* @param stream
*/
function onError(error) {
console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
} /**
* 捕获
*/
function getCapure(){
const mCanvas = window.canvas = document.querySelector('#mainCanvas');
mCanvas.width = 480;
mCanvas.height = 360; // 开始截取
mCanvas.width = video.videoWidth;
mCanvas.height = video.videoHeight;
mCanvas.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height);
// 新增1张
var divItem = document.createElement("div");
divItem.style.display = "block";
divItem.width = 100;
divItem.height = divItem.width * video.videoHeight / video.videoWidth; // 计算一下比例
divItem.style.width = divItem.width + "px";
divItem.style.height = divItem.height + "px";
var c1 = document.createElement("canvas");
c1.width = divItem.width;
c1.height = divItem.height;
c1.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height, 0, 0, c1.width, c1.height);
divItem.appendChild(c1);
list.appendChild(divItem);
} /**
* 清除记录
*/
function clear(){
var child = list.lastElementChild;
while (child) {
list.removeChild(child);
child = list.lastElementChild;
}
}

写在最后学习参考视频讲解比较详细:https://space.bilibili.com/394612055/video?tid=0&page=2&keyword=&order=pubdate

Web网页音视频通话之Webrtc相关操作(一)的更多相关文章

  1. iOS下WebRTC音视频通话(一)

    在iOS下做IM功能时,难免都会涉及到音频通话和视频通话.QQ中的QQ电话和视频通话效果就非常好,但是如果你没有非常深厚的技术,也没有那么大的团队,很难做到QQ那么快速和稳定的通话效果. 但是利用We ...

  2. iOS下WebRTC音视频通话(三)-音视频通话

    前两篇文章记录了音视频通话的一些概念和一些流程,以及一个局域网内音视频通话的示例. 今天以一个伪真实网络间的音视频通话示例,来分析WebRTC音视频通话的过程. 上一篇因为是在相同路由内,所以不需要穿 ...

  3. iOS下WebRTC音视频通话(二)-局域网内音视频通话

    这里是iOS 下WebRTC音视频通话开发的第二篇,在这一篇会利用一个局域网内音视频通话的例子介绍WebRTC中常用的API. 如果你下载并编译完成之后,会看到一个iOS 版的WebRTC Demo. ...

  4. 鹅厂优文|打通小程序音视频和webRTC

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯视频云终端技术总监常青, 2008 年毕业加入腾讯,一直从事客户端研发相关工作,先后参与过 PC QQ.手机QQ.QQ物联 等产品 ...

  5. 腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践

    1.概述 本文来自腾讯视频云终端技术总监rexchang(常青)技术分享,内容分别介绍了微信小程序视音视频和WebRTC的技术特征.差异等,并针对两者的技术差异分享和总结了微信小程序视音视频和WebR ...

  6. WebRTC相关的基础知识点

    这里主要用来记录自己整理的和webRTC相关的一些基本的知识点,后续整理的一些基础和零碎的知识点都会更新在这里.内容大部分来自于webRTC官网.w3c以及一些前辈们的博客中的文章和相关书籍等. 20 ...

  7. JS实现Web网页打印功能(IE)

    问题描述:     JS实现Web网页打印功能 问题解决:     这里主要使用WebBrowser控件的ExeWB在IE中打印功能的实现 WebBrowser介绍:         WebBrows ...

  8. Android音视频通话过程中最小化成悬浮框的实现(类似Android8.0画中画效果)

    关于音视频通话过程中最小化成悬浮框这个功能的实现,网络上类似的文章很多,但是好像还没看到解释的较为清晰的,这里因为项目需要实现了这样的一个功能,今天我把它记录下来,一方面为了以后用到便于自己查阅,一方 ...

  9. 二、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-腾讯云后台配置TXIM

    项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...

  10. Web自动化测试怎么做呢?好!接下来我们就开始Web网页测试针对性的流程解析啦!!!

    前言 测试行业现在70%是以手工测试为主,那么只有20%是自动化测试,剩下的10%是性能测试. 有人可能会说,我现在做手工,我为什么要学自动化呢?我去学性能更好性能的人更少? 其实,性能的要求比自动化 ...

随机推荐

  1. 【Vue】Vuex

    Vuex简介 概念: 专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中管理(读.写),也是一种适用于任意组件间的通信方式. 什么时候用Vuex ①多个 ...

  2. 3520. 【NOIP2013模拟11.7B组】原根(math)

    题目: 考试想法: 考试的时候觉得这些数学公式太恶心了,所以就直接跳过了. 正解: 直接暴力模拟就可以了. 代码: #include<bits/stdc++.h> using namesp ...

  3. Object o = new Object();

    对象的创建过程: 1,申请内存,并初始化: 2,构造器初始化: 3,o指向对象. 对象在内存中的存储布局: 使用jol工具打印java对象在内存的存储布局: 其中,对象头的组成: 对象头包括Mark ...

  4. [人脸活体检测] 论文: Learning Deep Models for Face Anti-Spoofing: Binary or Auxiliary Supervision

    Learning Deep Models for Face Anti-Spoofing: Binary or Auxiliary Supervision 论文简介 与人脸生理相关的rppG信号被研究者 ...

  5. 数据分析01-(numpy概述及使用)

    数据分析-01 数据分析 numpy numpy概述 numpy`历史` numpy的核心:多维数组 numpy基础 ndarray数组 内存中的ndarray对象 ndarray数组对象的特点 nd ...

  6. [Opencv-C++] 3. opencv数据类型

    文章目录 Point类 cv::Scalar类 size类 cv::Rect类 cv::RotatedRect类 固定矩阵类 固定向量类 复数类 工具函数 模板结构 Point类 在大多数程序中,Po ...

  7. flutter系列之:做一个修改组件属性的动画

    目录 简介 flutter中的动画widget AnimatedContainers使用举例 总结 简介 什么是动画呢?动画实际上就是不同的图片连续起来形成的.flutter为我们提供了一个Anima ...

  8. 2022-10-24:以下go语言代码输出什么?A:3 3;B:3 4;C:0 0;D:0 1。 package main func main() { m := make(map[int]int

    2022-10-24:以下go语言代码输出什么?A:3 3:B:3 4:C:0 0:D:0 1. package main func main() { m := make(map[int]int, 3 ...

  9. 2021-01-29:redis同步机制是怎样的?

    福哥答案2021-01-30: [答案1:](https://italk.mashibing.com/question/detail/ques_00006009)全量同步master服务器会开启一个后 ...

  10. vue全家桶进阶之路32:Vue3 WatchEffect和watch 监听

    在 Vue 3 中,watchEffect 是一个用于监听响应式数据变化的 API.它可以在函数内部自动跟踪数据的依赖,并在依赖变化时重新运行函数. watchEffect 的作用以及各个参数的功能讲 ...