I'm trying to create an HTTP server using Node.js where I can stream video files using video.js player. But it's taking a long time loading the web page.
I've tried to encode HTML codes Javascript files and CSS files using gzip, but it didn't improve the loading speed.
Here is my code:
const http = require('http');
const fs = require('fs');
const url = require('url');
const path = require('path');
const zlib = require('zlib');
const mime = require('mime');
http.createServer((req, res) => {
let uri = url.parse(req.url).pathname;
// Serve index page for root path
if (uri !== '/') {
let filename = path.join("./", uri);
fs.exists(filename, exists => {
if (!exists) {
res.writeHead(404);
res.end();
} else {
let stat = fs.statSync(filename);
let headers = {
'Accept-Ranges': 'bytes',
'Content-Type' = mime.getType(filename),
'Content-Length': stat.size,
'Vary': 'Accept-Encoding'
};
// Handle `Accept-Ranges` header
let range = req.headers.range;
let stream;
if (range) {
let parts = range.replace(/bytes=/, '').split('-');
let start = parseInt(parts[0]);
let end = parts[1] ? parseInt(parts[1]) : stat.size - 1;
let chunk_size = end - start + 1;
stream = fs.createReadStream(filename, {start, end});
headers['Content-Length'] = chunk_size;
headers['Content-Range'] = `bytes ${start}-${end}/${stat.size}`;
} else {
stream = fs.createReadStream(filename);
}
stream.on('error', err => {
res.writeHead(500);
res.end();
});
// gzip encode javascript and css files.
if (/\.(js)|(css)$/.test(filename.toLowerCase())) {
let gzip = zlib.createGzip();
gzip.on('error', err => {
throw err;
});
headers['Content-Encoding'] = 'gzip';
res.writeHead(200, headers);
stream.pipe(gzip).pipe(res);
} else {
if (range) {
res.writeHead(206, headers);
} else {
res.writeHead(200, headers);
}
stream.pipe(res);
}
}
});
} else {
let page = `<!DOCTYPE html>
<html lang="en">
<head>
<title>Video</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="assets/css/video-js.min.css">
<script src="assets/js/video.min.js"></script>
</head>
<body>
<div id="video_area">
<video id="video" class="video-js vjs-big-play-centered">
<source src="video.mkv" type="video/webm"/>
<track kind="subtitles" lang="en" src="en.vtt" default/>
</video>
</div>
<script>
window.player = videojs('video', {
controls: true,
autoplay: false,
preload: 'auto',
fluid: true,
playbackRates: [0.5, 1, 1.5, 2]
});
</script>
</body>
</html>`;
let headers = {
'Accept-Ranges': 'bytes',
'Content-Encoding': 'gzip',
'Content-Length': Buffer.byteLength(page),
'Content-Type': 'text/html'
};
res.writeHead(200, headers);
zlib.gzip(page, (err, data) => {
if (err) {
log.e(err);
throw err;
}
res.end(data);
});
}
}).listen(80);
This is a screenshot I captured from my Google Chrome's DevTools.
答案 0 :(得分:2)
首先确保将视频autoplay
设置为false
和preload="none"
在您的代码中添加异步
http.createServer(async(req, res)
现在将html放入函数中,并在您的else块中使用await执行该函数
else{
await htmlFunction()
}