Last active
March 30, 2023 17:45
-
-
Save julianfresco/c921d0102c1cdde5b78749ce660cb748 to your computer and use it in GitHub Desktop.
Restricted access HLS video streaming with node.js and express.js router
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var fs = require('fs'); | |
var config = require('../../config'); // developer-defined configs (Ex: config.video.localPath = "server/storage/") | |
/** Serves HLS videos to user */ | |
exports.serveHLSVideo = function(req, res){ | |
var appRoot = (__dirname + '/../../../'), | |
filePath = appRoot + config.video.localPath + req.params[0]; | |
// ... Here you would do some Auth (userId, sessionId/cookie info validation) | |
fs.stat(filePath, function (err, stats) { | |
if(!stats || err){ | |
res.status(404).end(); | |
} | |
else { | |
var fileExt = filePath.slice(filePath.lastIndexOf('.')); | |
fileExt = fileExt && fileExt.toLowerCase() || fileExt; | |
switch(fileExt) { | |
case '.m3u8': | |
res.status(200).set('Content-Type', 'application/vnd.apple.mpegurl'); | |
fs.createReadStream(filePath).pipe(res); | |
break; | |
case '.ts': | |
res.status(200).set('Content-Type', 'video/MP2T'); | |
fs.createReadStream(filePath).pipe(res); | |
break; | |
default: | |
res.status(400).send('Unexpected file type '+fileExt); | |
} | |
} | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var express = require('express'); | |
var controller = require('./my.controller'); | |
var router = express.Router(); | |
// ... other routes here | |
router.get('/:userId/hls/*', controller.serveHLSVideo); // PUBLIC API (add rule to public nginx) | |
module.exports = router; // Note: router is added to express app elsewhere, i.e. `app.use('/user', require('./my.router.js'))` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@mahdidavoodi7 Sorry, I never got a notification about your comment, and I am just seeing this for the first time in 2023 😅
You experienced exactly what is intended. This express controller was written to serve HLS video assets, which includes the ".m3u8" and the ".ts" files. Your video player on the front-end starts by requesting the ".m3u8", then decides which ".ts" files to request next based on the .m3u8's contents and server response times...
When you say you want a preview, it's unclear what you mean. This could be a thumbnail image, or perhaps a GIF-like preview video with key frames in the video? In either case, this would require extra work that is not covered in the Gist above.