HLS streaming media protocol based video encryption solution
A set of simple HLS streaming media protocol based on video. Js + NodeJS + FFmpeg and other related technologies to achieve m3U8 + TS + AES128 video encryption and playback solution example.
directory
- Project introduction
- Project start
- Principle of the project
- Technology stack
- Source analysis
- advice
Project introduction
At first, in order to replace the existing Flash-based video player with the HTML5 video player that does not rely on Flash, we mainly used the customization of the existing video.js open source player. After the completion of the production of video player, I began to understand and gradually in-depth study related video encryption content when further extending the content related to Web end video encryption. Finally, through sorting and induction, as well as their own understanding, made this simple Demo. The purpose is to be able to give in video encryption in this respect have the same purpose of the road friends to provide meager help, if can play the effect of casting a brick to attract jade, natural is very good.
Project start
1. Install the project environment
- Install the Node and NPM environment
- Install the corresponding NPM package according to package.json in app directory
- Install ffmpeg
2. Start the project
- In the app directory, type
npm start
, start the project - Access it in a browser
http://localhost:3000
- Perform related operations in the order specified on the page
Principle of the project
The core principle of this project is to explain a video source from the normal MP4 format how to change into encrypted M3U8 file + TS file +key secret key file, and then how to access the server is restricted, and finally can play in the client normally video encryption, decryption and playback process.
Schematic diagram of project principle
Technology stack
- NodeJS + Express server development
- FFmpeg + Fluent – FFmpeg realizes video transcoding and encryption under node environment
- Socket. IO realizes real-time output of video transcoding and encryption operations by FFmpeg through websocket-related class library
- Video.js + videojs-contrib-hls.js enables video decryption and playback on the client
- HTML + CSS + JS to achieve simple front-end development
Source analysis
Project Directory Description
video-hls-encrypt/ .............................. HLS video encryption project root directory ├ ─ ─ app /... The root directory of the default app │ express framework ├ ─ ─ bin /... Express frame start bin directory │ │ └ ─ ─ the WWW... Express frame start WWW file │ ├ ─ ─ controllers /... Project controller directory server related logic code │ │ ├ ─ ─ encrypt. Js... Encryption logic code │ │ └ ─ ─ the upload. Js... Upload the logic code │ ├ ─ ─ node_modules /... └ │ ├ ─ garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage, garbage │ ├ ─ ─ public /... Express framework static file directory, the client requests the related static file │ │ ├ ─ ─ javascripts... The client js file directory │ │ │ ├ ─ ─ encrypt. Js... Encryption related logic code │ │ │ ├ ─ ─ index. The js... Home page related logic code │ │ │ ├ ─ ─ player. Js... Player related logic code │ │ │ ├ ─ ─ socket. IO. Js... Socket. IO. Js library source files │ │ │ └ ─ ─ utils. Js... Utility class │ │ ├ ─ ─ key /... The secret key related directory │ │ │ ├ ─ ─ encrypt. Key... The secret key file │ │ │ └ ─ ─ key_info. Key... Ffmpeg encrypt video conversion related documents │ │ ├ ─ ─ libs /... Third-party libraries directory │ │ │ ├ ─ ─ videojs /... Videojs relevant code │ │ │ └ ─ ─ videojs - contrib - HLS /... Videojs - contrib - HLS related code │ │ ├ ─ ─ stylesheets /... CSS style directory │ │ │ └ ─ ─. Common CSS... General stylesheet │ │ └ ─ ─ videos /... Video resource directory │ │ ├ ─ ─ encrypt /... The encrypted video resource directory │ │ └ ─ ─ noencrypt /... Encrypt the video before the resource directory │ ├ ─ ─ routes /... Express framework routing directory │ │ └ ─ ─ the router, js... Express routing │ ├ ─ ─ views /... Express framework ejs template directory │ │ ├ ─ ─ encrypt the ejs... Video encryption page │ │ ├ ─ ─ the error. The ejs... Error page │ │ ├ ─ ─ index. The ejs... Home page │ │ ├ ─ ─ the login. The ejs... The login page │ │ ├ ─ ─ player. Ejs... Player page │ │ └ ─ ─ the upload. Ejs... Upload video page │ ├ ─ ─ app. Js... Express program entrance │ ├ ─ ─ nodemon. Json... Hot update plug-in node server nodemon corresponding configuration file │ └ ─ ─ package. The json... Express framework needs to be a third party relying on package configuration file ├ ─ ─ the gitignore ├ ─ ─ the README. Md... Project documentation └ ─ ─ TODO - List. Md... Project development plan document
Copy the code
Source analysis
- Simple permission judgment, app.js:
- Middleware for Express
- Determine the suffix of the request
- Check whether there is a user name in the session. If there is, the.key file is allowed to be accessed. If not, access is prohibited
- Key files can be protected, and other permissions can be added, such as tokens, session validity duration, etc
Use (function (req, res, next) {var suffix = /(\.key)$/g; // Suffix format specifies if (suffix.test(req.path)) {console.log(req.session.username,'++++ requested the key file '); if((req.session.username ! = 'admin')){return res.send(' request invalid '); }else{console.log('+++++ requested key file, and already logged, login name: ',req.session.username); next(); } } else { next(); }});
Copy the code
- Encrypt and slice the video with FFmpeg. In encrypt.js:
- Using FFmpeg slicing and encryption methods
- It is recommended to delve into the API of FFmpeg framework
- You can slice the video according to the actual business
@param socket Socket output @param callback function */ function encryptFun(options,socket, callback) { var _name = options.fileName.split('.')[0]; var _type = options.fileName.split('.')[1]; var _encryptPath = options.encryptPath + '/' + _name; var _videoPath = options.noencryptPath + '/' + options.fileName; var _keyInfoPath = './public/key/key_info.key'; var _outputPath = _encryptPath + '/playlist.m3u8'; console.log('begin encrypt Fun'); if (_type == 'mp4') { ffmpegCommand(_videoPath) .addOption('-hls_time', '10') // Set the length of each fragment. AddOption (' -hlS_KEY_info_file ', _keyInfoPath).save(_outputPath).on('end', function () { socket.emit('encrypt-event',{msg:'Encrypt the ' + options.fileName + ' file OK! ',type:1}); callback(null, 'Encrypt the ' + options.fileName + ' file OK! '); }) .on('stderr', function (stderrLine) { console.log('Stderr output: ' + stderrLine); socket.emit('encrypt-event',{msg:stderrLine}); }) .on('error', function (err, stdout, stderr) { console.log('Cannot process video: ' + err.message); socket.emit('encrypt-event',{msg:err.message}); callback(err, err.message); }); } else{ callback('type err','file type is not mp4.'); }}
Copy the code
- Player. ejs:
- Videojs is used as a player plug-in
- Videojs-contrib-hls was used as the slice stream decoder plug-in
- The logic is in player.js
<script src="javascripts/utils.js"></script>
<script src="libs/videojs/video.min.js"></script>
<script src="libs/videojs-contrib-hls/videojs-contrib-hls.js"></script>
<script src="javascripts/player.js"></script>
Copy the code
advice
- The value of this project is to show a whole set of encryption principles, and to prove the feasibility of this principle, to do a relatively simple example.
- This project does not provide a tutorial on how to use the relevant technology stack.
- If you need to use related principles or technology stacks in actual applications, you are advised to improve or expand part or the whole solution based on the actual project.
gossip
The following contents are personal views for reference only
As I do front-end development myself, many relevant examples are based on front-end considerations, and the corresponding strategies for the back-end are not very professional. Back-end servers, for example, also use front-end NodeJS. I would like to express that in the whole solution, I mainly did three things:
- First, get the MP4 video source through
FFmpeg
Convert to encryptedm3u8
Files andts
Files and key encryption keyskey
File; - Second, through the simplest access to protect the encryption key file;
- Third, use
video.js
And relatedvideojs-contrib-hls.js
Achieve client video file decryption, and play.
Therefore, it can be seen that in the video encryption solution, the most important thing is how to protect the encryption key file, and this part of the work is more related to the server side strategy. For example, you can use cookies, session-related technologies, add custom token verification, and validity period mechanism to ensure the relative security and reliability of key files.
And how to convert video source files into corresponding encrypted files, we can study the use of open source library FFmpeg more, or even consider using relevant solutions of third-party video cloud service providers if there is no urgent need. As for video decryption on the client side, you can also study the content related to video.js.