html 悬停播放截图,html5多摄像头播放和截图

Document

打开摄像头

播放摄像头

截取并上传

navigator.getUserMedia =

navigator.getUserMedia ||

navigator.webkitGetUserMedia ||

(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ||

navigator.mozGetUserMedia ||

navigator.msGetUserMedia; // 获取媒体对象(这里指摄像头)

let currentStream = null,

cameraList = [],

videoElement = document.getElementById("video"),

videoElement2 = document.getElementById("video2");

// 1. 获取摄像头列表

function getCameraList() {

navigator.mediaDevices.enumerateDevices().then((mediaDevices) => {

cameraList = mediaDevices;

console.log(JSON.stringify(mediaDevices));

});

}

/*** 格式如下

[

{

"deviceId": "4d9f6ffec7e62d5d7cf94d8943ff2b7b77de8b531822e7f514416f004079a5c6",

"kind": "videoinput",

"label": "LHT-820BW (0c45:6300)",

"groupId": "cc83dc58f13c88df5a4b96bce0af43a7779179ee54508f71457ea9f900cf93d4"

},

{

"deviceId": "539cbf57edd3ee728c912c222920ee9cc0971373938da4bd43545a92cb9b5c9f",

"kind": "videoinput",

"label": "LHT-820VM31B (0c45:6367)",

"groupId": "49f8c5f91a4880636bbf919ee8c567e416252593a6754d84fac8614f4581e7e4"

},

{

"deviceId": "",

"kind": "audiooutput",

"label": "",

"groupId": "f1f9c2fc668cfe64155c501cbcdee5ef12d76a1b14134db19929a94ef1d93fcf"

}

]

*/

// 2. 切换摄像头

function toggleCamera(deviceId) {

if (currentStream !== null) {

stopMediaTracks(currentStream); // 先停止当前摄像头视频流的播放

}

// 组装数据(固定格式)

const constraints = {

video: {

deviceId: {

exact: deviceId, // 要切换到的设备ID

},

},

audio: false,

};

navigator.mediaDevices

.getUserMedia(constraints) // 传入要切换到的设备

.then((stream) => {

currentStream = stream; // 获取当前视频流

video.srcObject = stream; // 将当前视频流放到video标签里

return navigator.mediaDevices.enumerateDevices(); // 获取设备列表

})

.then((mediaDevices) => {}) // 这里可以再次获取到摄像头设备列表

.catch((error) => {

console.error(error);

});

}

// 2-2. 多摄像头同时播放

function playCamera(deviceId, videoEle, env = null) {

// 组装数据(固定格式)

let constraints = {};

if (!env) {

constraints = {

video: {

deviceId: {

exact: deviceId, // 要切换到的设备ID

},

},

audio: false,

};

} else {

constraints = {

video: {

facingMode: "environment",

},

audio: false,

};

}

navigator.mediaDevices

.getUserMedia(constraints) // 传入要切换到的设备

.then((stream) => {

if (videoEle) videoEle.srcObject = stream; // 将当前视频流放到video标签里

return navigator.mediaDevices.enumerateDevices(); // 获取设备列表

})

.then((mediaDevices) => {}) // 这里可以再次获取到摄像头设备列表

.catch((error) => {

console.error(error);

});

}

// 3. 停止当前视频流的播放

function stopMediaTracks(stream) {

stream.getTracks().forEach((track) => {

track.stop();

});

}

// 运行demo 每隔10秒切换摄像头播放数据 (两个摄像头)

/* getCameraList();

setInterval(() => {

let playCount = 0;

cameraList

.filter((v) => v.deviceId !== "") // 清除空设备

.map((v) => {

if (v.isPlay !== true && playCount === 0) {

toggleCamera(v.deviceId);

v.isPlay = true;

playCount++;

console.log("toggle", v.deviceId);

} else {

v.isPlay = false;

}

});

}, 10000); */

// 获取摄像头权限

document.getElementById("open").onclick = () => {

playCamera(null, null, true);

};

// 运行demo 两个摄像头同时播放

document.getElementById("play").onclick = () => {

getCameraList();

setTimeout(() => {

const devs = cameraList.filter((v) => v.deviceId !== ""); // 清除空设备

playCamera(devs[0].deviceId, document.getElementById("video"));

playCamera(devs[1].deviceId, document.getElementById("video2"));

});

};

// 截图并上传

document.getElementById("snap").addEventListener(

"click",

function () {

const can1 = document.getElementById("canvas1");

const can2 = document.getElementById("canvas2");

const ctx1 = can1.getContext("2d");

const ctx2 = can2.getContext("2d");

// 视频放到canvas里

ctx1.drawImage(videoElement, 0, 0, 200, 150);

ctx2.drawImage(videoElement2, 0, 0, 200, 150);

// 转成图像blob对象 保存在formData里

const fd = new FormData();

can1.toBlob(function (blob) {

fd.append("img1", blob);

});

can2.toBlob(function (blob) {

fd.append("img2", blob);

});

// 上传到接口 有延迟需要等待blob对象转换完成 或者写成Promise方式

setTimeout(() => {

fetch("/api/upload/xxx", {

method: "POST",

body: fd,

});

}, 2000);

},

false

);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值