js 本地视频录制、拍照

<style>
.showvideo {
position: relative;
height: 500px;
}

video {
width: 800px;
height: 500px;
border: 1px solid #000;
object-fit: fill;
}

canvas {
position: absolute;
width: 800px;
height: 500px;
left: 1px;
top: 1px;
}

.showimg img {
width: 500px;
height: 300px;
}
</style>
 
<div>
<span onclick="startRecording()">开始录像</span>
<span onclick="stopRecording()">结束录像</span>
<span onclick="photograph()">拍照</span>
</div>

<div style="display:flex">
<div class="showvideo">
<video></video>
<canvas id="canvas" style="display: none"></canvas>
</div>
<div class="showimg"></div>
</div>
 
<script>
function findNthIndex (str, searchChar, n) {
let index = -1;
for (let i = 0; i < n; i++) {
index = str.indexOf(searchChar, index + 1);
if (index === -1) {
return -1;
}
}
return index;
}
let mediaRecorder = null;
let recordedChunks = [];
const startRecording = () => {
const options = { mimeType: 'video/webm;codecs=h264' }; //文件格式
mediaRecorder = new MediaRecorder(window.stream, options);
mediaRecorder.ondataavailable = function (e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
};

mediaRecorder.onstop = function (e) {
const blob = new Blob(recordedChunks, { type: 'video/mp4' });
recordedChunks = [];
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = 'recorded.mp4';
a.click();
window.URL.revokeObjectURL(url);
// const index =findNthIndex(str,"/",3);
// let newurl = str.slice(index, str.length-1)+".mp4";
// console.log(newurl)
};

mediaRecorder.start();
};

const stopRecording = () => {
console.log("stopRecording")
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
}
};
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(function (stream) {
window.stream = stream;

// 使用视频流初始化一个 video 元素
const video = document.querySelector('video');
video.srcObject = stream;
video.onloadedmetadata = (event) => video.play();
})
.catch(function (err) {
console.log('Error:', err);
});
function photograph () {
let v =
document.querySelector("video");
let canvas = document.getElementById("canvas");
canvas.width = 800;
canvas.height = 600;
canvas
.getContext("2d")
.drawImage(v, 0, 0, canvas.width, canvas.height);
let data = canvas.toDataURL("image/jpeg", 0.8);
let showimg = document.querySelector(".showimg");
showimg.innerHTML = "";
const img = document.createElement('img');
showimg.appendChild(img);
img.src = data;
console.log(data)   //图片是base64格式的
}

</script>
 
//最后记录一个图片压缩的方法
/**
* 压缩图片方法
* @param {file} file 文件或文件数组
* @param {Number} quality 图片质量(取值0-1之间默认0.92)
*/
const compressImg = (file, quality) => {
if (Array.isArray(file)) {
return Promise.all(Array.from(file).map((e) => compressImg(e, quality))); // 如果是 file 数组返回 Promise 数组
} else {
let qualitys = 1;
//单位:MB
let fileSize = parseInt((file.size / 1024 / 1024).toFixed(2));
if (1 < fileSize && fileSize < 5) {
qualitys = 0.92;
}
if (5 < fileSize && fileSize < 10) {
qualitys = 0.85;
}
if (10 < fileSize) {
qualitys = 0.52;
}
if (quality) {
qualitys = quality;
}
return new Promise((resolve) => {
if (qualitys >= 1) {
resolve(file);
} else {
let fileType = file.type;
if (!fileType || !fileType.includes("image/")) {
resolve(file);
return;
}
const fileReader = new FileReader(); // 创建 FileReader
fileReader.onload = ({ target: { result: src } }) => {
const image = new Image(); // 创建 img 元素
image.onload = () => {
const mCanvas = document.createElement("canvas"); // 创建 canvas 元素
const mCtx = mCanvas.getContext("2d");
let targetWidth = image.width;
let targetHeight = image.height;
let originWidth = image.width;
let originHeight = image.height;
if (1 <= fileSize) {
let maxWidth = 1400;
let maxHeight = 1400;
if (5 < fileSize) {
maxWidth = 1920;
maxHeight = 1920;
}
targetWidth = originWidth;
targetHeight = originHeight;
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(
maxWidth * (originHeight / originWidth)
);
} else {
targetHeight = maxHeight;
targetWidth = Math.round(
maxHeight * (originWidth / originHeight)
);
}
}
}
mCanvas.width = targetWidth;
mCanvas.height = targetHeight;
mCtx.clearRect(0, 0, targetWidth, targetHeight);
mCtx.drawImage(image, 0, 0, targetWidth, targetHeight); // 绘制 canvas
const canvasURL = mCanvas.toDataURL(fileType, qualitys);
const buffer = atob(canvasURL.split(",")[1]);
let length = buffer.length;
const bufferArray = new Uint8Array(new ArrayBuffer(length));
while (length--) {
bufferArray[length] = buffer.charCodeAt(length);
}
const miniFile = new File([bufferArray], file.name, {
type: fileType
});
resolve(miniFile);
};
image.src = src;
};
fileReader.readAsDataURL(file);
}
});
}
};
posted @ 2023-06-06 17:23  波仔、  阅读(314)  评论(0编辑  收藏  举报