Node.js視頻流應(yīng)用創(chuàng)建之后端的全過(guò)程
前言
在本文中,將展示一個(gè)非常簡(jiǎn)單的 Node.js 應(yīng)用程序,用于在線(xiàn)流媒體視頻傳輸。本文僅涵蓋后端,在下一部分中,將使用 Vue.js 創(chuàng)建前端。話(huà)不多說(shuō),下面開(kāi)始進(jìn)入主題。
初始化
創(chuàng)建項(xiàng)目文件夾 vue-video-stream ,進(jìn)入文件夾,再創(chuàng)建文件夾 express-service ,用戶(hù)存放后端服務(wù)相關(guān)代碼,進(jìn)入express-service ,運(yùn)行 npm init 初始化配置并安裝相關(guān)依賴(lài)項(xiàng),如下:
npm install express cors --save npm install -D nodemon
安裝完成后修改 package.json 中的調(diào)試及啟動(dòng)腳本,如下:
"scripts": {
"start": "node ./index.js",
"debug": "nodemon --trace-warnings --inspect=0.0.0.0:9229 ./index.js"
}至此完成了后端服務(wù)的初始化,接下來(lái)完成主體部分。
主體邏輯
主體邏輯的代碼主要在文件 index.js 文件中,如下:
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.get("/", (req, res) => {
// 根目錄路由
});
const PORT = process.env.PORT || 8100;
app.listen(PORT, () => {
console.log(`服務(wù)運(yùn)行端口:${PORT}`);
});在流媒體傳輸視頻的目錄中 express-service 添加一個(gè)新的 index.html 文件。文件的 src 必須指向要繼續(xù)進(jìn)行流媒體傳輸?shù)姆?wù)器端點(diǎn)。
注意:這里的 index.html 文件主要用于演示后臺(tái)服務(wù),后續(xù)將會(huì)使用 VUE 來(lái)替換。
<!DOCTYPE html>
<html lang="zh">
<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>流媒體傳輸 Express 服務(wù)</title>
<style type="text/css">
body {
margin: 0px;
padding: 0px;
background-color: #000;
}
video {
position: absolute;
width: 800px;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<video src="/video/20220315" width="800px" height="auto" controls autoplay id="videoPlayer"></video>
</body>
</html>現(xiàn)在需要設(shè)置 /video 路由和控制器邏輯,作為索引路由,還需要發(fā)送這個(gè) HTML 文件進(jìn)行渲染。接下來(lái)更新 index.js 文件代碼,如下:
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.get("/", (req, res) => {
// 根目錄路由
res.sendFile(__dirname + "/index.html");
});
// 視頻路由
app.use("/video", require("./routes/index"));
const PORT = process.env.PORT || 8100;
app.listen(PORT, () => {
console.log(`服務(wù)運(yùn)行端口:${PORT}`);
});接下來(lái)在目錄 express-service 創(chuàng)建文件夾 routes ,在文件夾中創(chuàng)建腳本文件 index.js ,代碼如下:
const router = require("express").Router();
const videoController = require("../controller/videoController");
router.get("/:videoId", videoController.streamVideo);
module.exports = router;在目錄 express-service 創(chuàng)建文件夾 controller ,在文件夾中創(chuàng)建腳本文件 videoController.js ,代碼如下:
const fs = require("fs");
module.exports.streamVideo = (req, res) => {
const range = req.headers.range;
const videoId = req.params.videoId; // ID或者視頻文件名稱(chēng)
if (!range) {
res.status(400).send("無(wú)效Range");
}
const processPath = process.cwd(); // 獲取服務(wù)運(yùn)行路徑
const videoPath = `${processPath}/resources/${videoId}.mp4`;
const videoSize = fs.statSync(videoPath).size;
const chunkSize = 10 ** 6; // 1 mb
const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + chunkSize, videoSize - 1);
const contentLength = end - start + 1;
const headers = {
"Content-Range": `bytes ${start}-${end}/${videoSize}`,
"Accept-Ranges": "bytes",
"Content-Length": contentLength,
"Content-Type": "video/mp4",
};
res.writeHead(206, headers);
const videoStream = fs.createReadStream(videoPath, { start, end });
videoStream.pipe(res);
};下面就來(lái)介紹 videoController 的主要邏輯,在請(qǐng)求 headers 中,提取了 range( range 是當(dāng)前在視頻緩沖區(qū)中的部分)。如果range不存在,拋出一個(gè)錯(cuò)誤。否則,在文件系統(tǒng)中找到該文件。
然后,設(shè)置要隨每個(gè)并發(fā)請(qǐng)求發(fā)送的塊大?。ùa中設(shè)置為 1 MB , Math.pow(10,6) 或簡(jiǎn)單的 10 ** 6)。然后定義開(kāi)始和結(jié)束變量,start 變量決定了發(fā)送的視頻的起點(diǎn),對(duì)于 end 變量,需要確定 (start +chunk) 或視頻大小長(zhǎng)度之間的最小值,避免超出。
最后,確定實(shí)際發(fā)送的內(nèi)容長(zhǎng)度,內(nèi)容長(zhǎng)度是開(kāi)始值和結(jié)束值之間的差異。然后使用剛剛在它上面計(jì)算的值生成的 headers 對(duì)象。在代碼的最后一部分,發(fā)送一個(gè)內(nèi)容響應(yīng) (206),它是 express 框架的一部分,并使用 fs(Node.js 核心)模塊將該響應(yīng)與讀取流進(jìn)行管道傳輸。
現(xiàn)在來(lái)啟動(dòng)服務(wù),執(zhí)行如下:
npm run start
如果是要調(diào)試代碼,避免手動(dòng)重啟,可以執(zhí)行一下命令:
npm run debug
這樣在修改 js 代碼后服務(wù)將會(huì)自動(dòng)重啟。
啟動(dòng)后在瀏覽器中輸入 http://127.0.0.1:8100/,就可以看到如下效果:

在下一部分中,將使用 Vue.js 設(shè)計(jì)前端《VUE創(chuàng)建視頻流應(yīng)用》。
總結(jié)
到此這篇關(guān)于創(chuàng)建Node.js視頻流應(yīng)用之后端的文章就介紹到這了,更多相關(guān)Node.js視頻流應(yīng)用后端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Nodejs基于LRU算法實(shí)現(xiàn)的緩存處理操作示例
這篇文章主要介紹了Nodejs基于LRU算法實(shí)現(xiàn)的緩存處理操作,結(jié)合具體實(shí)例形式分析了LRU算法的原理、功能以及nodejs使用LRU算法實(shí)現(xiàn)緩存處理操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03
npm報(bào)錯(cuò)"A?complete?log?of?this?run?can?be?found?
這篇文章主要給大家介紹了關(guān)于npm報(bào)錯(cuò)"A?complete?log?of?this?run?can?be?found?in:"的解決辦法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-04-04
nodeJS(express4.x)+vue(vue-cli)構(gòu)建前后端分離實(shí)例(帶跨域)
這篇文章主要介紹了nodeJS(express4.x)+vue(vue-cli)構(gòu)建前后端分離實(shí)例(帶跨域) ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
提升node.js中使用redis的性能遇到的問(wèn)題及解決方法
本文中提到的node redis client采用的基于node-redis封裝的二方包,因此問(wèn)題排查也基于node-redis這個(gè)模塊。接下來(lái)通過(guò)本文給大家分享提升node.js中使用redis的性能2018-10-10
node.js博客項(xiàng)目開(kāi)發(fā)手記
本篇文章給大家總結(jié)了node.js博客項(xiàng)目開(kāi)發(fā)的相關(guān)步驟以及知識(shí)點(diǎn)分享,有興趣的朋友參考下。2018-03-03

