You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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的最简实现:

  1. 先安装依赖:
    npm install express multer cors
    
  2. 新建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}`);
    })
    
  3. 在项目根目录手动新建uploads文件夹,用来存录制好的视频,运行node server.js启动服务后,访问http://localhost:3000即可测试。

注意事项

  • 不要直接双击打开本地html文件测试,必须通过http服务访问,否则浏览器会拦截摄像头权限和上传请求
  • 如果需要录制声音,把前端getUserMedia参数里的audio改为true即可
  • 录制生成的视频默认是webm格式,如果需要mp4格式可以在后端加ffmpeg转码逻辑
  • 生产环境使用时记得给上传接口加身份校验,同时限制上传文件大小、格式,避免恶意文件上传

内容的提问来源于stack exchange,提问作者Rodrigo Franco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:33:22