您好! ?
在本教程中,我将向您展示如何使用 WebCodec API 发送和接收视频。
首先让我们对服务器进行编码。
为了在对等点之间发送和接收数据包,我们需要一个 websocket 服务器。
为此,我们将使用 Nodejs 创建一个非常基本的服务器。首先初始化项目:
npm init -y
然后安装所需的模块:
npm i ws express
接下来创建一个名为“index.js”的新文件并使用以下代码填充它:
// server.js const WebSocket = require('ws'); const express = require('express'); const app = express(); const port = 3000; const connectedClients = new Set(); app.use(express.static(__dirname + '/public')); const wss = new WebSocket.Server({ noServer: true }); wss.on('connection', ws => { console.log('new connection'); connectedClients.add(ws); ws.on('message', message => { connectedClients.forEach(client => { if (client !== ws && client.readyState === WebSocket.OPEN) { client.send(message); } }); }); ws.once('close', () => { connectedClients.delete(ws); console.log('connection closed'); }); }); const server = app.listen(port, () => { console.log(`server running on port ${port}`); }); server.on('upgrade', (request, socket, head) => { wss.handleUpgrade(request, socket, head, (ws) => { wss.emit('connection', ws, request); }); });
上面的代码没有太复杂,它服务于公共目录并处理 websocket 连接,将数据包发送到所有连接的对等点。 ?
接下来我们将处理发件人部分,但首先创建一个名为“public”的新目录
mkdir public
我们将创建的第一个前端文件是广播的,在 public 下创建一个名为“sender.html”的新文件,并使用以下 HTML 填充它:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Sender</title> <style> video, canvas { width: 640px; height: 480px; border: 2px solid black; margin: 10px; } </style> </head> <body> <video id="video" autoplay playsinline></video> <canvas id="canvas" width="640" height="480"></canvas> <script> const videoElement = document.getElementById('video'); const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let videoEncoder; let socket; const initWebSocket = () => { socket = new WebSocket('ws://localhost:3000'); socket.onopen = () => console.log('WebSocket connected'); socket.onerror = error => console.error('WebSocket error:', error); }; const initEncoder = () => { videoEncoder = new VideoEncoder({ output: (encodedChunk) => { const chunkData = new Uint8Array(encodedChunk.byteLength); encodedChunk.copyTo(chunkData); if (socket.readyState === WebSocket.OPEN) { socket.send(chunkData.buffer); } }, error: (error) => console.error('Encoding error:', error) }); videoEncoder.configure({ codec: 'vp8', width: 640, height: 480, bitrate: 1_000_000, framerate: 30 }); }; navigator.mediaDevices.getUserMedia({ video: true }) .then((stream) => { videoElement.srcObject = stream; const videoTrack = stream.getVideoTracks()[0]; const processor = new MediaStreamTrackProcessor(videoTrack); const reader = processor.readable.getReader(); const processFrames = async () => { while (true) { const { value: videoFrame, done } = await reader.read(); if (done) break; ctx.drawImage(videoFrame, 0, 0, canvas.width, canvas.height); videoEncoder.encode(videoFrame, { keyFrame: true }); videoFrame.close(); } }; processFrames(); }) .catch((error) => console.error('Failed to get camera', error)); initEncoder(); initWebSocket(); </script> </body> </html>
分解并解释代码的作用。
唷!希望您能理解。接下来我们将创建将接收流的文件。 ?
此文件通过 WebSocket 接收编码的视频块,对其进行解码,并将它们显示在画布元素上。
在公共目录下创建一个名为“receiver.html”的新文件,并使用以下内容填充它:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Receiver</title> <style> canvas { width: 640px; height: 480px; border: 2px solid black; margin: 10px; } </style> </head> <body> <canvas id="canvas" width="640" height="480"></canvas> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let videoDecoder; const initWebSocket = () => { const socket = new WebSocket('ws://localhost:3000'); socket.binaryType = 'arraybuffer'; socket.onmessage = event => { decodeFrame(event.data); }; socket.onerror = error => console.error('WebSocket error:', error); }; const initDecoder = () => { videoDecoder = new VideoDecoder({ output: (videoFrame) => { ctx.drawImage(videoFrame, 0, 0, canvas.width, canvas.height); videoFrame.close(); }, error: (error) => console.error('Decoding error:', error) }); videoDecoder.configure({ codec: 'vp8', width: 640, height: 480 }); }; const decodeFrame = (encodedData) => { const chunk = new EncodedVideoChunk({ type: 'key', timestamp: performance.now(), data: new Uint8Array(encodedData) }); videoDecoder.decode(chunk); }; initDecoder(); initWebSocket(); </script> </body> </html>
分解上述文件:
唷!现在我们已经拥有了所需的所有部分,让我们实际运行它吧! ?
要运行代码,只需运行以下命令:
node index.js
然后将浏览器指向http://localhost:3000/sender.html
允许访问您的相机,然后打开另一个选项卡
http://localhost:3000/receiver.html
如下所示,您应该看到从发送者发送的流。
在本教程中,我展示了如何访问摄像头、对其进行编码、通过 WebSocket 发送数据块以及如何解码并在接收器端显示它们。我希望本教程对您有用。 ?
一如既往,您可以通过我的 github 获取代码:
https://github.com/ehand91/webcodec-stream
快乐编码! ?
喜欢我的作品吗?我的帖子内容很丰富,如果你想看更多,请点赞并关注我。
我也喜欢咖啡。
如果您想学习算法模式以在编码面试中取得好成绩,我推荐[以下课程](https://algolab.so/p/algorithms-and-data-struct-video-course?affcode=1413380_bzrepgch
以上是WebCodec - 发送和接收的详细内容。更多信息请关注PHP中文网其他相关文章!