首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MediaRecorder录制和传输视频

MediaRecorder 是 HTML5 提供的一个 API,用于在浏览器中录制音频和视频。结合 WebRTCWebSocket 或其他传输协议,你可以将录制的视频实时传输到服务器或其他客户端。以下是一个简单的示例,展示如何使用 MediaRecorder 录制视频并通过 WebSocket 传输到服务器。

1. 录制视频

首先,使用 MediaRecorder 录制视频:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MediaRecorder Example</title>
</head>
<body>
    <video id="localVideo" autoplay playsinline></video>
    <button id="startButton">Start Recording</button>
    <button id="stopButton" disabled>Stop Recording</button>

    <script>
        let mediaRecorder;
        let recordedChunks = [];

        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');
        const localVideo = document.getElementById('localVideo');

        startButton.addEventListener('click', async () => {
            const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
            localVideo.srcObject = stream;

            mediaRecorder = new MediaRecorder(stream);

            mediaRecorder.ondataavailable = event => {
                if (event.data.size > 0) {
                    recordedChunks.push(event.data);
                }
            };

            mediaRecorder.onstop = () => {
                const blob = new Blob(recordedChunks, { type: 'video/webm' });
                uploadVideo(blob);
                recordedChunks = [];
            };

            mediaRecorder.start();
            startButton.disabled = true;
            stopButton.disabled = false;
        });

        stopButton.addEventListener('click', () => {
            mediaRecorder.stop();
            startButton.disabled = false;
            stopButton.disabled = true;
        });

        async function uploadVideo(blob) {
            const formData = new FormData();
            formData.append('video', blob, 'recording.webm');

            try {
                const response = await fetch('/upload', {
                    method: 'POST',
                    body: formData,
                });

                if (response.ok) {
                    console.log('Video uploaded successfully');
                } else {
                    console.error('Video upload failed');
                }
            } catch (error) {
                console.error('Error uploading video:', error);
            }
        }
    </script>
</body>
</html>

2. 服务器端处理

在服务器端,你可以使用 Node.js 和 express 来处理上传的视频文件。以下是一个简单的示例:

代码语言:javascript
复制
const express = require('express');
const multer = require('multer');
const path = require('path');

const app = express();
const upload = multer({ dest: 'uploads/' });

app.post('/upload', upload.single('video'), (req, res) => {
    if (!req.file) {
        return res.status(400).send('No file uploaded.');
    }

    console.log('File uploaded:', req.file);
    res.send('File uploaded successfully.');
});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

3. 实时传输

如果你希望实时传输视频流,而不是录制后再上传,可以使用 WebRTCWebSocket。以下是一个简单的示例:

代码语言:javascript
复制
const startButton = document.getElementById('startButton');
const stopButton = document.getElementById('stopButton');
const localVideo = document.getElementById('localVideo');

let mediaStream;
let peerConnection;
let socket;

startButton.addEventListener('click', async () => {
    mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    localVideo.srcObject = mediaStream;

    // 连接到 WebSocket 服务器
    socket = new WebSocket('ws://localhost:8080');

    socket.onopen = () => {
        console.log('WebSocket connection established');
        startWebRTC();
    };

    socket.onmessage = async (event) => {
        const message = JSON.parse(event.data);
        if (message.sdp) {
            await peerConnection.setRemoteDescription(new RTCSessionDescription(message.sdp));
        } else if (message.ice) {
            await peerConnection.addIceCandidate(new RTCIceCandidate(message.ice));
        }
    };

    startButton.disabled = true;
    stopButton.disabled = false;
});

stopButton.addEventListener('click', () => {
    mediaStream.getTracks().forEach(track => track.stop());
    socket.close();
    startButton.disabled = false;
    stopButton.disabled = true;
});

async function startWebRTC() {
    peerConnection = new RTCPeerConnection();

    mediaStream.getTracks().forEach(track => {
        peerConnection.addTrack(track, mediaStream);
    });

    peerConnection.onicecandidate = event => {
        if (event.candidate) {
            socket.send(JSON.stringify({ ice: event.candidate }));
        }
    };

    peerConnection.ontrack = event => {
        const remoteVideo = document.createElement('video');
        remoteVideo.srcObject = event.streams[0];
        remoteVideo.autoplay = true;
        document.body.appendChild(remoteVideo);
    };

    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);

    socket.send(JSON.stringify({ sdp: offer }));
}

在服务器端,你需要处理 WebSocket 消息并转发 SDP 和 ICE 候选者:

代码语言:javascript
复制
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
    ws.on('message', (message) => {
        const parsedMessage = JSON.parse(message);
        if (parsedMessage.sdp) {
            // 转发 SDP 到其他客户端
            wss.clients.forEach(client => {
                if (client !== ws && client.readyState === WebSocket.OPEN) {
                    client.send(JSON.stringify(parsedMessage));
                }
            });
        } else if (parsedMessage.ice) {
            // 转发 ICE 候选者到其他客户端
            wss.clients.forEach(client => {
                if (client !== ws && client.readyState === WebSocket.OPEN) {
                    client.send(JSON.stringify(parsedMessage));
                }
            });
        }
    });
});

4. 注意事项

  • ​跨浏览器兼容性​​:MediaRecorderWebRTC 在不同浏览器中的支持程度可能有所不同,建议在使用前检查兼容性。
  • ​安全性​​:在处理用户媒体流时,确保遵守隐私和安全最佳实践,例如仅在用户明确同意的情况下访问摄像头和麦克风。
  • ​性能​​:实时视频传输对网络带宽和服务器性能要求较高,确保你的基础设施能够处理这些负载。

通过这些步骤,你可以使用 MediaRecorder 录制视频并将其传输到服务器或其他客户端。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券