在进行用node搭建服务器时,有需要读取视频的需求,所以自己大概写了一下如何读取视频,也有利于对视频处理的理解。
视频请求路径:/fileUpload/video/测试视频.mp4
视频实际服务端存储路径:/bigFile/video/测试视频.mp4
代码部分
路由部分:
"use strict";
const path = require("path");
const fs = require("fs");
const Router = require('koa-router');
const router = new Router();
const routesFun = require('../utils/routesFun');
router.get("/fileUpload/video/*.mp4", async (ctx, next) => {
let uri = decodeURI(ctx.request.url);
uri = uri.substr(uri.lastIndexOf("/")+1);
let filePath = path.resolve(__dirname, "../bigFile/video/"+uri);//根据请求路径与实际路径适当修改
let resHred = routesFun.readFile(ctx.headers.range, filePath);
ctx.type = "video/mp4;charset=utf-8";
ctx.status = resHred.code
ctx.set(resHred.head);
let stream = fs.createReadStream(filePath, resHred.code == 200 ? {} : { start: resHred.start, end: resHred.end });
stream.pipe(ctx.res);
ctx.respond = false;
return;
});
视频流处理部分:
"use strict";
const path = require("path");
const fs = require("fs");
//mime类型
const mime = {
"css": "text/css",
"gif": "image/gif",
"html": "text/html",
"ico": "image/x-icon",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"js": "text/javascript",
"json": "application/json",
"pdf": "application/pdf",
"png": "image/png",
"svg": "image/svg+xml",
"swf": "application/x-shockwave-flash",
"tiff": "image/tiff",
"txt": "text/plain",
"mp3": "audio/mp3",
"wav": "audio/x-wav",
"wma": "audio/x-ms-wma",
"wmv": "video/x-ms-wmv",
"xml": "text/xml",
"mp4": "video/mp4"
};
/**
* [读文件]
* @param {String} range [数据起始位]
* @param {String} filePath [文件路径]
* @param {Number} chunkSize [每次请求碎片大小 (1MB 左右)]
*/
function readFile(range, filePath, chunkSize = 499999 * 2) {
// 获取后缀名
let ext = path.extname(filePath);
ext = ext ? ext.slice(1) : "unknown";
//未知的类型一律用"text/plain"类型
let contentType = mime[ext.toLowerCase()];
//建立流对象,读文件
let stat = fs.statSync(filePath)
let fileSize = stat.size;
let head = {
code: 206,
head: {
"Content-Length": fileSize,
"content-type": contentType,
"Content-Encoding": "identity"
}
};
if (range) {
// 大文件分片
let parts = range.replace(/bytes=/, "").split("-");
// console.log(parts)
let start = parseInt(parts[0], 10);
let end = parts[1] ? parseInt(parts[1], 10) : start + chunkSize;
end = end > fileSize - 1 ? fileSize - 1 : end;
chunkSize = (end - start) + 1;
head = {
code: 206,
filePath,
start,
end,
head: {
"Content-Range": `bytes ${start}-${end}/${fileSize}`,
"content-type": contentType,
"Content-Length": chunkSize,
"Accept-Ranges": "bytes",
"Content-Encoding": "identity"
}
}
}
return head;
}
问题
现在按照上面写的,暂时发现的错误就是:
- 安卓手机用微信自带浏览器打开网页进行视频播放时,视频进度条拖动无效,经发现微信自带浏览器进行视频播放时并未经过我所写的路由。所以会有部分问题。暂时不知道如何解决!
有问题或者有错误可以留言,谢谢指导!