如何使用JavaScript录制摄像头视频并存到服务器
实现方案
直接用浏览器原生MediaRecorder API处理录制逻辑,停止录制后自动把生成的视频文件上传到后端接口存储即可,不需要额外引入第三方库。
前端代码修改
原有摄像头调用逻辑可以保留,只需要补充录制相关逻辑、按钮事件绑定、上传逻辑即可。
修改后的script.js完整代码
let VIDEO = null; let CONTEXT = null; let mediaRecorder = null; let recordedChunks = []; let cameraStream = null; function main(){ CANVAS = document.getElementById("myCanvas"); CONTEXT = CANVAS.getContext("2d"); CANVAS.width = window.innerWidth; CANVAS.height = window.innerHeight; // 绑定按钮事件 const recordBtn = document.getElementById("record"); const stopBtn = document.getElementById("stop"); stopBtn.disabled = true; recordBtn.addEventListener("click", startRecord); stopBtn.addEventListener("click", stopRecord); // 调用摄像头,需要录声音就把audio设为true let promise = navigator.mediaDevices.getUserMedia({video:true, audio:false}); promise.then(function(signal){ cameraStream = signal; VIDEO = document.createElement("video"); VIDEO.srcObject = signal; VIDEO.play(); VIDEO.onloadeddata = function(){ updateCanvas(); } }).catch(function(err){ alert("Camera error: "+err); }) } function updateCanvas(){ CONTEXT.drawImage(VIDEO, 0, 0); window.requestAnimationFrame(updateCanvas); } // 开始录制 function startRecord() { recordedChunks = []; // 直接录制摄像头原始流,比录canvas画质好、性能高 mediaRecorder = new MediaRecorder(cameraStream, { mimeType: 'video/webm;codecs=vp9' }); // 收集录制片段 mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) { recordedChunks.push(e.data); } }; // 录制停止时自动触发上传 mediaRecorder.onstop = function() { const videoBlob = new Blob(recordedChunks, { type: 'video/webm' }); uploadVideo(videoBlob); }; mediaRecorder.start(); document.getElementById("record").disabled = true; document.getElementById("stop").disabled = false; } // 停止录制 function stopRecord() { mediaRecorder.stop(); document.getElementById("record").disabled = false; document.getElementById("stop").disabled = true; } // 上传视频到服务器 function uploadVideo(blob) { const formData = new FormData(); // 生成带时间戳的文件名,避免重名 const fileName = `record_${Date.now()}.webm`; formData.append('video', blob, fileName); fetch('/upload', { method: 'POST', body: formData }).then(res => res.text()) .then(msg => console.log('上传结果:', msg)) .catch(err => alert('上传失败: '+err)); }
原有index.html结构不需要改动,直接用即可。
后端接收存储示例(Node.js)
其他后端语言逻辑一致:接收前端上传的文件,写入服务器指定目录即可,这里给Node.js的最简实现:
- 先安装依赖:
npm install express multer cors - 新建
server.js,写入以下代码:const express = require('express'); const multer = require('multer'); const cors = require('cors'); const app = express(); const port = 3000; app.use(cors()); app.use(express.static('./')); // 托管前端静态文件 // 配置文件存储路径,文件统一存在服务器根目录的uploads文件夹下 const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads') }, filename: function (req, file, cb) { cb(null, file.originalname) } }) const upload = multer({ storage: storage }); // 接收上传的视频接口 app.post('/upload', upload.single('video'), (req, res) => { res.send(`视频已保存到服务器路径: ./uploads/${req.file.filename}`); }) app.listen(port, () => { console.log(`服务运行在 http://localhost:${port}`); }) - 在项目根目录手动新建
uploads文件夹,用来存录制好的视频,运行node server.js启动服务后,访问http://localhost:3000即可测试。
注意事项
- 不要直接双击打开本地html文件测试,必须通过http服务访问,否则浏览器会拦截摄像头权限和上传请求
- 如果需要录制声音,把前端getUserMedia参数里的
audio改为true即可 - 录制生成的视频默认是webm格式,如果需要mp4格式可以在后端加ffmpeg转码逻辑
- 生产环境使用时记得给上传接口加身份校验,同时限制上传文件大小、格式,避免恶意文件上传
内容的提问来源于stack exchange,提问作者Rodrigo Franco
相关产品推荐
相关产品推荐

