一套简单的基于HLS流媒体协议,使用video。jsNodeJSFFmpeg等相关技术实现的m3u8tsaes128视频加密及播放的解决方案。目录项目简介项目启动项目原理技术栈源码简析建议项目简介 起初是为了将工作中已有的基于Flash的视频播放器替换为不依赖Flash的HTML5视频播放器,主要使用了现有的video。js开源播放器做的定制化开发。当完成视频播放器的制作后,在进一步延伸Web端视频加密的相关内容时,开始了解并逐渐深入的研究了相关视频加密内容。最终通过整理归纳,以及自身的理解,做了这个简单的Demo。目的是为了能够给在视频加密这方面有相同目的的道友提供微薄的帮助,要是能起到抛砖引玉的效果,自然是再好不过了。项目启动 1。安装项目环境安装node、npm环境根据app目录下的package。json安装对应的npm包安装ffmpeg 2。启动项目在app目录下,输入npmstart,启动项目在浏览器中访问http:localhost:3000按照页面中的顺序进行相关操作项目原理 本项目的核心原理其实就是讲解了一个视频源从正常的mp4格式如何变为加密后的m3u8文件ts文件key秘钥文件,之后又如何在服务端被限制访问,最终能够在客户端正常播放的视频加密、解密并播放的流程。技术栈NodeJSExpress实现服务器开发FFmpegfluentffmpeg实现node环境下的视频转码、加密socket。io通过websocket相关的类库,实现实时输出FFmpeg进行的视频转码、加密操作video。jsvideojscontribhls。js实现客户端的视频解密及播放htmlcssjs实现简单的前端开发源码简析 项目目录说明videohlsencrypt。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。hls视频加密项目根目录app。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架默认的app根目录bin。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架启动的bin目录www。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架启动的www文件controllers。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。项目控制器目录,服务器相关的逻辑代码encrypt。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。加密逻辑代码upload。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。上传逻辑代码nodemodules。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架需要的相关npm依赖包,即package。json文件相对应的依赖包。。。public。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架静态文件目录,客户端请求的相关静态文件javascripts。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。客户端的js文件目录encrypt。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。加密功能相关逻辑代码index。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。主页相关逻辑代码player。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。播放器相关逻辑代码socket。io。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。socket。io。js类库源文件utils。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。工具类key。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。秘钥相关目录encrypt。key。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。秘钥文件keyinfo。key。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。ffmpeg加密视频转换相关文件libs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。第三方类库目录videojs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。videojs相关代码videojscontribhls。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。videojscontribhls相关代码stylesheets。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。css样式目录common。css。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。通用样式表videos。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。视频资源目录encrypt。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。加密后的视频资源目录noencrypt。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。加密前的视频资源目录routes。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架路由目录router。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express路由views。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架ejs模板目录encrypt。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。视频加密页面error。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。错误页面index。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。主页login。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。登录页面player。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。播放器页面upload。ejs。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。上传视频页面app。js。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express程序入口nodemon。json。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。node服务器热更新插件nodemon对应的配置文件package。json。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。express框架需要的第三方依赖包配置文件。gitignoreREADME。md。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。项目说明文档TODOList。md。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。项目开发计划文档复制代码 源码简析简单的权限判断,app。js中:express的中间件判断请求的后缀判断session中是否有用户名,有则允许访问。key文件;没有则禁止访问主要是保护。key文件,可以加入其它的权限手段,比如token、session有效时长等等静态资源访问限制app。use(function(req,res,next){varsuffix(。key)g;后缀格式指定if(suffix。test(req。path)){console。log(req。session。username,请求key文件了);if((req。session。username!admin)){returnres。send(请求非法);}else{console。log(请求key文件了,并且已经登录,登录名为:,req。session。username);next();}}else{next();}});复制代码利用FFmpeg对视频进行加密、切片处理,在encrypt。js中:利用了FFmpeg的切片和加密方法建议可以深入研究FFmpeg框架的相关api可以根据实际业务来对视频进行更符合要求的切片处理加密处理方法paramoptions加密数据的相关参数paramsocketsocket输出paramcallback回调函数functionencryptFun(options,socket,callback){varnameoptions。fileName。split(。)〔0〕;vartypeoptions。fileName。split(。)〔1〕;varencryptPathoptions。encryptPathname;varvideoPathoptions。noencryptPathoptions。fileName;varkeyInfoPath。publickeykeyinfo。key;varoutputPathencryptPathplaylist。m3u8;console。log(beginencryptFun);if(typemp4){ffmpegCommand(videoPath)。addOption(hlstime,10)设置每个片段的长度。addOption(hlskeyinfofile,keyInfoPath)。save(outputPath)。on(end,function(){socket。emit(encryptevent,{msg:Encrypttheoptions。fileNamefileOK!,type:1});callback(null,Encrypttheoptions。fileNamefileOK!);})。on(stderr,function(stderrLine){console。log(Stderroutput:stderrLine);socket。emit(encryptevent,{msg:stderrLine});})。on(error,function(err,stdout,stderr){console。log(Cannotprocessvideo:err。message);socket。emit(encryptevent,{msg:err。message});callback(err,err。message);});}else{callback(typeerr,filetypeisnotmp4。);}}复制代码视频播放相关逻辑,player。ejs中:使用了videojs作为播放器插件使用了videojscontribhls作为切片流解码插件具体的逻辑代码在player。js中复制代码建议本项目更多的价值在于展示出一整套的加密原理,同时为了证明这套原理的可行性,做的比较简单的示例。本项目不会提供相关技术栈的使用教程。如果需要在实际应用中使用相关原理或技术栈,建议根据实际项目对部分或整体解决方案进行完善和扩展。