<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>WebRTC</h1>
<video style="position: absolute ;background-color: red"
autoplay playsinline
id="video1" width="680" height="480"></video>
<div style="margin:550px auto">
<button id="snapshot">拍照</button>
<button id="record">录制视频</button>
<button id="recplay" disabled>播放视频</button>
<button onclick="dol()">下载视频
<a id="download" disabled></a>
</button>
<div id="images">
</div>
</div>
<div>
<canvas id="picture"></canvas>
</div>
<video style="background-color: aqua;position: absolute;top:90px; left: 50%"
controls
id="video2" width="680" height="480">>
</video>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"
integrity="sha512-v8ng/uGxkge3d1IJuEo6dJP8JViyvms0cly9pnbfRxT6/31c3dRWxIiwGnMSWwZjHKOuY3EVmijs7k1jz/9bLA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="./js/photo-client.js"></script>
</body>
</html>
var video1 = document.querySelector("#video1");
var video2 = document.querySelector("#video2");
var snapshot = document.querySelector("#snapshot");
var record = document.querySelector("#record");
record.setAttribute("data_status", '0');
var recplay = document.querySelector("#recplay");
var download = document.querySelector("#download");
var picture = document.querySelector("#picture");
let peerConnection = new RTCPeerConnection();
// 创建一个 MediaRecorder 对象,传入视频流
const mediaRecorder = {}
// 录制视频
// 用于存储录制的视频数据
let recordedChunks = [];
let blob; //播放数据
// 检查设备
myDevices()
function myDevices() {
// 获取设备信息
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
// 处理设备信息数组
devices.forEach(function (device) {
console.log('设备类型:', device.kind, '设备标识:', device.deviceId, '设备名称:', device.label);
});
// 有可以播放的设备,则调用 getMedia()
getMedia();
})
.catch(function (error) {
// 处理错误
console.error('获取设备信息失败: ', error);
});
}
var constraints = {
video: {
width: 640,
height: 480,
frameRate: 30,
facingMode: 'enviroment'
},
audio: false
}
// WBERTC 操作
function getMedia() {
navigator.mediaDevices.getUserMedia({video: true, audio: true})
.then(function (stream) {
// 在这里处理获取到的媒体流
// 例如,将其赋给 video 元素的 srcObject 属性
video1.srcObject = stream;
// WebRTC 需要一个流来传输媒体数据,所以必须将其添加到 RTCPeerConnection 对象中
stream.getTracks().forEach(track => {
peerConnection.addTrack(track, stream)
})
createOffer();
const mediaRecorder = new MediaRecorder(stream);
// 监听数据可用事件,将数据添加到 recordedChunks 数组中
mediaRecorder.ondataavailable = function (event) {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
// 监听停止事件,创建 Blob
mediaRecorder.onstop = function () {
blob = new Blob(recordedChunks, {type: 'video/webm'});
};
// 点击开始录制按钮时开始录制
record.addEventListener('click', function () {
if (record.getAttribute('data_status') === '0') {
recordedChunks = [];
record.innerText = '停止';
record.color = 'red';
record.setAttribute("data_status", '1');
recplay.disabled = true
mediaRecorder.start();
} else {
record.setAttribute("data_status", '0');
record.innerText = '录制视频';
record.color = 'green';
recplay.disabled = false
mediaRecorder.stop();
}
});
mediaRecorder.onstop = function () {
console.log("停止录制")
blob = new Blob(recordedChunks, {type: 'video/webm'});
}
})
.catch(function (error) {
// 处理错误
console.error('获取媒体设备失败: ', error);
});
}
//处理屏幕共享的媒体流
function display() {
navigator.mediaDevices.getDisplayMedia({video: true})
.then(function (stream) {
// 处理屏幕共享的媒体流
// 例如,将其赋给 video 元素的 srcObject 属性
video1.srcObject = stream;
})
.catch(function (error) {
// 处理错误
console.error('获取屏幕共享失败: ', error);
});
}
// 创建一个offer(提议)
function createOffer() {
peerConnection.createOffer()
.then(offer => {
console.log("创建 offer 成功:", offer)
// 设置本地描述
peerConnection.setLocalDescription(offer).then(r => {
console.log("设置本地描述:", r)
}).then(() => {
// 将 offer 发送给远程方
}).catch(error => console.error('创建 offer 失败: ', error));
})
}
// 处理远程方的回应
function RemoteDes(offer) {
peerConnection.setRemoteDescription(offer)
.then(() => peerConnection.createAnswer())
.then(answer => peerConnection.setLocalDescription(answer))
.then(() => {
// 将 answer 发送给对方
})
.catch(error => console.error('创建 answer 失败: ', error));
}
// 本地方收到远程方的 answer 后,设置远程描述即可。
function setRemoteDes(answer) {
peerConnection.setRemoteDescription(answer)
.then(() => {
// 远程描述设置成功
console.log("远程描述设置成功")
})
.catch(error => console.error('设置远程描述失败: ', error));
}
// 按钮功能实现
picture.width = 640;
picture.height = 480;
let canvasContext = picture.getContext("2d")
let recordImage = []
snapshot.addEventListener('click', function () {
canvasContext.drawImage(video1, 0, 0, picture.width, picture.height)
// 获取图像数据(Base64 编码)
const imageData = picture.toDataURL('image/png');
recordImage.push(imageData)
let images = document.querySelector("#images")
images.innerHTML = ""
recordImage.reverse();
recordImage.forEach(index => {
// 创建 <img> 元素
let imgElement = document.createElement('img');
imgElement.src = index;
images.appendChild(imgElement)
})
})
recplay.addEventListener('click', function () {
if (blob) {
console.log(blob)
download.disabled = false
video2.width = 648;
video2.height = 480
video2.src = URL.createObjectURL(blob);
}
})
function dol(){
download.disabled = false
download.href = video2.src
download.download = "video.webm"
download.click();
}