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

如何在JS中对摄像头录制视频进行水平镜像/翻转?

实现摄像头视频水平镜像录制的方法

你当前的代码是直接录制摄像头的原始流,要实现水平镜像翻转,需要通过Canvas对视频帧做处理后再录制,具体实现代码和关键说明如下:

window.navigator.mediaDevices
    .getUserMedia({
        video: {
            width: { ideal: 1920 },
            height: { ideal: 1080 },
            frameRate: 30,
        },
    })
    .then(async (stream) => {
        // 创建video元素承载原始摄像头流
        const video = document.createElement('video');
        video.srcObject = stream;
        video.muted = true; // 静音避免回声
        await video.play(); // 必须等待视频播放才能获取有效帧

        // 创建canvas处理镜像画面
        const canvas = document.createElement('canvas');
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const ctx = canvas.getContext('2d');

        // 循环绘制水平镜像的视频帧
        function drawMirrorFrame() {
            ctx.save();
            // 水平翻转:缩放X轴为-1实现镜像,平移画布抵消翻转后的偏移
            ctx.scale(-1, 1);
            ctx.translate(-canvas.width, 0);
            // 将视频帧绘制到canvas
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            ctx.restore();
            requestAnimationFrame(drawMirrorFrame);
        }
        drawMirrorFrame();

        // 从canvas捕获处理后的镜像流
        const mirroredStream = canvas.captureStream(30); // 帧率与摄像头保持一致

        // 录制镜像流
        const mediaRecorder = new MediaRecorder(mirroredStream);
        const blobParts = [];
        mediaRecorder.addEventListener('dataavailable', (event) => {
            blobParts.push(event.data);
        });
        mediaRecorder.addEventListener('stop', () => {
            const blob = new Blob(blobParts, { type: 'video/webm' });
            console.log(blob);
            // 可选:添加下载逻辑
            // const url = URL.createObjectURL(blob);
            // const a = document.createElement('a');
            // a.href = url;
            // a.download = 'mirrored-video.webm';
            // a.click();
        });

        mediaRecorder.start();
        setTimeout(() => {
            mediaRecorder.stop();
            stream.getTracks().forEach(track => track.stop()); // 释放摄像头资源
        }, 10000);
    })
    .catch((error) => {
        console.error(error);
    });

关键逻辑说明

  • 必须通过video元素加载原始流并播放,否则无法获取有效视频帧和尺寸
  • ctx.scale(-1, 1)实现水平翻转,但翻转后画面会移出画布,需要用translate(-canvas.width, 0)将画面移回画布范围内
  • canvas.captureStream()生成包含Canvas绘制内容的媒体流,录制这个流就能得到镜像后的视频
  • 录制结束后记得停止原始摄像头流,避免占用设备资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:35:04