node.js - 在 Node js 中制作简单视频 API 的最佳方法是什么?
问题描述
嘿,我一直在寻找一个简单的视频 API。我想在一个简单的页面上流式传输视频并将它们实现到我的 html 中。有什么建议可以让我完成这项工作吗?
解决方案
我们可以使用Node.js 中模块HTTP range requests
的流 APIfs
来创建视频流 API。
HTTP 范围请求只允许从服务器向客户端发送 HTTP 消息的一部分。例如,部分请求对于大型媒体或下载具有暂停和恢复功能的文件很有用。
我们将使用该http
模块在 Node.js 中创建一个简单的服务器,并使用该promisify
实用程序将回调转换为来自fs module
.
使用范围请求,我们可以控制要发送给客户端的数据量。在下面的示例中,我们只是查找范围标头,如果它们存在,我们可以从中解析开始和结束字节,range header
并且我们只会发送文件的那部分。
我们将创建文件的读取流并将其通过管道传输到res
(http.ServerResponse
是可写流)。
const { createServer } = require('http');
const path = require('path');
const { promisify } = require('util');
const { stat, createReadStream } = require('fs');
const fileInfo = promisify(stat);
const filename = './streams/test-video.mp4';
createServer( async (req, res) => {
const { size } = await fileInfo(filename);
const fileExtension = path.extname(filename).replace('.', '');
const { range } = req.headers;
if (range) {
let [start, end] = range.replace(/bytes=/, '').split('-')
start = parseInt(start, 10); // starting bytes
// end = end ? parseInt(end, 10) : size - 1 // end of file unless specified
end = Math.min(start + 5000, size - 1); // 5000 bytes starting from start byte or end of file, whichever is smaller
res.writeHead(206, { // HTTP 206 - Because it is Partial Content
'Content-Range': `bytes ${start}-${end}/${size}`,
'Accept-Ranges': 'bytes',
'Content-Length': (end - start) + 1,// denotes the number of bytes requested and not the entire file size
'Content-Type': `video/${fileExtension}`,
});
createReadStream(filename, { start, end }).pipe(res);
} else {
res.writeHead(200, {
'Content-Type': `video/${fileExtension}`,
'Content-Length': size,
});
createReadStream(filename).pipe(res);
}
}).listen(3000, () => {
console.log('Server listening on port 3000');
})
推荐阅读
- spring-integration - 行号:54;列号:26;匹配的通配符是严格的,但找不到元素“int:scatter-gather”的声明
- python - Python Tkinter 事件 x、y、xroot、yroot 显示不正确的值
- python - 理解 MLP 神经网络——没有库的 Python
- javascript - Angular 10 ng-content 投影导致表格冻结
- angular - 为什么在 Angular 服务中使用 HTTP 客户端时要对 Observable 进行 Typecast
- c - Xcode 11.5 使用 .C 源时架构 arm64 的未定义符号
- javascript - 如何在页面刷新时显示加载器/微调器并且需要等待 React JS 中的 authUser 结果?
- c# - 如何在 xamarin.forms 的 viewcell 中设置按钮以从内容页面视图模型中调用命令?
- mysql - 谷歌云平台 - 来自具有公共 IP 的计算引擎实例的 mySQL 访问被拒绝
- java - Java 将 object 类型的 ArrayList 转换为 object 类型的另一个 ArrayList