用node.js搭建一个视频推流服务

由于业务中有不少视频使用的场景,今天来说说如何使用node完成一个视频推流服务。

先看看效果:

这里的播放的视频是一个多个Partial Content组合起来的,每个Partial Content大小是1M。

一,项目搭建

(1)初始化项目,创建package.json

复制代码
npm init

(2)安装express和nodemon

复制代码
npm install --save express nodemon

(3)创建html文件

复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Video Streaming With Node</title>
    <style>
      body {
        max-width: 100%;
        height: 100vh;
        background-color: rgb(14, 14, 14);
        display: flex;
        margin: auto;
        align-items: center;
        justify-content: center;
      }
    </style>
  </head>
  <body>
    <video id="videoPlayer" width="70%" controls autoplay >
      <source src="/video" type="video/mp4" />
    </video>
  </body>
</html>

(4)创建index.js作为video接口服务

二,编写video接口

最终实现的效果如刚开始的实例,在浏览器中打开视频,会请求/video,该接口返回media类型的数据流片段。

首先引入express和fs。前者提供服务,后者操作文件系统,将视频文件序列化成流pipe出去。下面看看代码实现

复制代码

const express = require("express");
const app = express();
const fs = require("fs");

app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});

// more code will go in here just befor the listening function

app.listen(8000, function () {
console.log("Listening on port 8000!");
});

创建服务,serve Index.html文件。

复制代码
app.get("/video", function (req, res) {
    const range = req.headers.range;
    if (!range) {
        res.status(400).send("Requires Range header");
    }
});

保证request的header里面有range,没有range就无法判断需要把那一部分content写入response。

复制代码
const videoPath = "Chris-Do.mp4";
const videoSize = fs.statSync("Chris-Do.mp4").size;

还需要资源的路径和资源的大小,资源的大小会用来计算那一部分content要被send。这里简单放在相对index.js的位置。

复制代码
const CHUNK_SIZE = 10 ** 6; // 1MB
const start = Number(range.replace(/\D/g, ""));

这里规定每次返回1M的内容,开始位置从request的header里获取并将其转成Number类型。

复制代码
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);

计算结束位置,这里取开始位置加上1M数据和结束位置两者之间的最小值。

三、创建Response headers。

在响应头里面我们需要返回Content的大小,Content-range,Accept-ranges,Content-type。

复制代码
const headers = {
    "Content-Range": `bytes ${start}-${end}/${videoSize}`,
    "Accept-Ranges": "bytes",
    "Content-Length": contentLength,
    "Content-Type": "video/mp4",
};

状态码设置为206表明我们返回的部分内容。

复制代码
// HTTP Status 206 for Partial Content
res.writeHead(206, headers);

四、创建Stream并返回。

这里需要使用fs来创建一个videoSteam,使用videoPath和start和end作为参数。这里只需要把videoStream pipe到response即可。

复制代码
// create video read stream for this particular chunk
  const videoStream = fs.createReadStream(videoPath, { start, end });

  // Stream the video chunk to the client
  videoStream.pipe(res);

启动服务,看到视频被正常推流。好了,这里一个简易的视频推流服务就写好了。

-- End --

相关推荐
king13598745503 小时前
AI Agent 端云协同选型:Node.js 任务成本算例与权限检查清单(2027—2028 展望)
人工智能·ai·node.js·ai agent
居里先生7526 小时前
PDF 批注到底存在文件的哪里?从 /Annots 讲到导出验证
node.js
MasonYyp1 天前
安装npm依赖仓库Verdaccio
前端·npm·node.js
编程的一拳超人2 天前
【元宝搜索开发者征文大赛】四语实战:Java/Python/Go/Node.js 构建 AI 搜索应用全攻略
java·python·golang·node.js·agent
lucas_AI2 天前
今年 2 月就修好的漏洞,10 月才炸:HTTP2Shell 把 Node、Python 一锅端
node.js
SEO_juper3 天前
Node.js 全站死链检测工具:从 sitemap 出发一次找全 404
开发语言·人工智能·python·node.js·seo·外贸独立站
孟陬4 天前
解决动态 import 类型 Any 痼癖
typescript·node.js·bun
Dumbness4 天前
后台管理员把自己锁在门外:RBAC 里「自己的权限只能由别人来减」
安全·node.js
攻城狮白玉4 天前
Node.js 发布紧急安全更新:10 个漏洞,8 枚危险证书被拉黑。附AI修复提示词
node.js
Json____5 天前
用 FastAPI + Vue3 打造一套完整的在线考试系统:从组卷到阅卷的业务闭环实践
后端·node.js·fastapi·it学习·wwwoop.com