javascript 如何使用 HTML5 将网络摄像头捕获的 jpg 图像/视频保存在本地硬盘驱动器中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46882550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to save a jpg image/video captured with webcam in the local hard drive with HTML5
提问by Della
The problem appears simple, although I cannot find a suitable solution because of my lack of knowledge of HTML and Javascript.
问题看起来很简单,但由于我缺乏 HTML 和 Javascript 知识,我找不到合适的解决方案。
The task is simply to design a webpage where a button will activate the webcam and store either a still image or a video (preferable) in the local hard drive. No upload/download required for the time being.
任务只是设计一个网页,其中一个按钮将激活网络摄像头并将静态图像或视频(最好)存储在本地硬盘驱动器中。暂时不需要上传/下载。
After some attempts, I am able to use the getusermedia() api to activate the webcam and render the video in the browser window, but unable to save it. This is what my code looks like.
经过一些尝试,我能够使用 getusermedia() api 来激活网络摄像头并在浏览器窗口中呈现视频,但无法保存它。这就是我的代码的样子。
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true}, handleVideo, videoError);
}
function handleVideo(stream) {
video.src = window.URL.createObjectURL(stream);
}
So any idea on how to save either a still image or a video in the hard drive captured the same way?
那么关于如何在以相同方式捕获的硬盘驱动器中保存静止图像或视频的任何想法?
回答by Kaiido
First, the navigator.getUserMediaAPI is being deprecated, you should now use the navigator.mediaDevices.getUserMediamethod.
首先,该navigator.getUserMediaAPI 已被弃用,您现在应该使用该navigator.mediaDevices.getUserMedia方法。
Then to take a still image, you can indeed use a canvas which can drawa video element.
然后要拍摄静止图像,您确实可以使用可以绘制视频元素的画布。
const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
vid.srcObject = stream; // don't use createObjectURL(MediaStream)
return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
const btn = document.querySelector('button');
btn.disabled = false;
btn.onclick = e => {
takeASnap()
.then(download);
};
})
.catch(e=>console.log('please use the fiddle instead'));
function takeASnap(){
const canvas = document.createElement('canvas'); // create a canvas
const ctx = canvas.getContext('2d'); // get its context
canvas.width = vid.videoWidth; // set its size to the one of the video
canvas.height = vid.videoHeight;
ctx.drawImage(vid, 0,0); // the video
return new Promise((res, rej)=>{
canvas.toBlob(res, 'image/jpeg'); // request a Blob from the canvas
});
}
function download(blob){
// uses the <a download> to download a Blob
let a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'screenshot.jpg';
document.body.appendChild(a);
a.click();
}
<button>take a snapshot</button>
<video id="vid"></video>
As a fiddlesince Stacksnippets may block gUM requests...
作为一个小提琴,因为 Stacksnippets 可能会阻止 gUM 请求......
And to save as a video, you can use the [MediaRecorder API](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorderà, which will allow you to save a MediaStream as webm:
并且要保存为视频,您可以使用 [MediaRecorder API]( https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorderà,这将允许您将 MediaStream 保存为 webm:
const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
vid.srcObject = stream; // don't use createObjectURL(MediaStream)
return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
const btn = document.querySelector('button');
btn.disabled = false;
btn.onclick = startRecording;
})
.catch(e=>console.log('please use the fiddle instead'));
function startRecording(){
// switch button's behavior
const btn = this;
btn.textContent = 'stop recording';
btn.onclick = stopRecording;
const chunks = []; // here we will save all video data
const rec = new MediaRecorder(vid.srcObject);
// this event contains our data
rec.ondataavailable = e => chunks.push(e.data);
// when done, concatenate our chunks in a single Blob
rec.onstop = e => download(new Blob(chunks));
rec.start();
function stopRecording(){
rec.stop();
// switch button's behavior
btn.textContent = 'start recording';
btn.onclick = startRecording;
}
}
function download(blob){
// uses the <a download> to download a Blob
let a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'recorded.webm';
document.body.appendChild(a);
a.click();
}
<button disabled>start recording</button>
<video></video>
And as a fiddle
Notes:
笔记:
The MediaRecorder API is still a quite new API and there are still some bugs in the [little set of browser implementations.
MediaRecorder API 仍然是一个相当新的 API,并且在 [小浏览器实现集合中仍然存在一些错误。
回答by Marc Dix
What you did is a good start. You can now 'paint' the webcam picture into a canvasand then create an image from the canvas information. You can then use some tricks to prevent the browser from displaying the image and get it to download it instead.
你所做的是一个好的开始。您现在可以将网络摄像头图片“绘制”到画布中,然后根据画布信息创建图像。然后您可以使用一些技巧来阻止浏览器显示图像并让它下载它。

