深入浅出基于HLS流媒体协议视频加密的解决方案

news2025/7/19 10:17:47

一套简单的基于HLS流媒体协议,使用video.js + NodeJS + FFmpeg等相关技术实现的m3u8+ts+aes128视频加密及播放的解决方案示例。

项目简介

  起初是为了将工作中已有的基于Flash的视频播放器替换为不依赖Flash的HTML5视频播放器,主要使用了现有的video.js开源播放器做的定制化开发。当完成视频播放器的制作后,在进一步延伸Web端视频加密的相关内容时,开始了解并逐渐深入的研究了相关视频加密内容。最终通过整理归纳,以及自身的理解,做了这个简单的Demo。目的是为了能够给在视频加密这方面有相同目的的道友提供微薄的帮助,要是能起到抛砖引玉的效果,自然是再好不过了。

项目启动

1.安装项目环境

  • 安装node、npm环境

  • 根据app目录下的package.json安装对应的npm包

  • 安装ffmpeg

2.启动项目

  • 在app目录下,输入npm start,启动项目

  • 在浏览器中访问 http://localhost:3000

  • 按照页面中的顺序进行相关操作

项目原理

  本项目的核心原理其实就是讲解了一个视频源从正常的mp4格式如何变为加密后的m3u8文件+ts文件+key秘钥文件,之后又如何在服务端被限制访问,最终能够在客户端正常播放的视频加密、解密并播放的流程。

项目原理图示

技术栈

  • NodeJS + Express 实现服务器开发

  • FFmpeg + fluent-ffmpeg 实现node环境下的视频转码、加密

  • socket.io 通过websocket相关的类库,实现实时输出FFmpeg进行的视频转码、加密操作

  • video.js + videojs-contrib-hls.js 实现客户端的视频解密及播放

  • html + css + js 实现简单的前端开发

源码简析

项目目录说明

video-hls-encrypt/                   .............................. hls视频加密项目根目录
├── app/                             .............................. express框架默认的app根目录
│   ├── bin/                         .............................. express框架启动的bin目录
│   │   └── www                      .............................. express框架启动的www文件
│   ├── controllers/                 .............................. 项目控制器目录,服务器相关的逻辑代码
│   │   ├── encrypt.js               .............................. 加密逻辑代码
│   │   └── upload.js                .............................. 上传逻辑代码
│   ├── node_modules/                .............................. 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          .............................. 秘钥文件
│   │   │   └── key_info.key         .............................. ffmpeg加密视频转换相关文件
│   │   ├── libs/                    .............................. 第三方类库目录
│   │   │   ├── videojs/             .............................. videojs 相关代码
│   │   │   └── videojs-contrib-hls/ .............................. videojs-contrib-hls 相关代码
│   │   ├── 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框架需要的第三方依赖包配置文件
├── .gitignore
├── README.md                        .............................. 项目说明文档
└── TODO-List.md                     .............................. 项目开发计划文档

源码简析

文末名片免费领取音视频开发学习资料,内容包括(C/C++,Linux 服务器开发,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

  • 简单的权限判断,app.js中:

    • express的中间件

    • 判断请求的后缀

    • 判断session中是否有用户名,有则允许访问 .key文件;没有则禁止访问

    • 主要是保护.key文件,可以加入其它的权限手段,比如token、session有效时长等等

//静态资源访问限制
app.use(function (req, res, next) {
    var suffix = /(\.key)$/g;//后缀格式指定
    if ( suffix.test(req.path)) {
        console.log(req.session.username,'++++请求key文件了');
        if((req.session.username != 'admin')){
            return res.send('请求非法');
        }else{
            console.log('+++++请求key文件了,并且已经登录,登录名为:',req.session.username);
            next();
        }
    }
    else {
        next();
    }
});
  • 利用FFmpeg对视频进行加密、切片处理,在encrypt.js中:

    • 利用了FFmpeg的切片和加密方法

    • 建议可以深入研究FFmpeg框架的相关api

    • 可以根据实际业务来对视频进行更符合要求的切片处理

/**
 * 加密处理方法
 * @param options 加密数据的相关参数
 * @param socket socket输出
 * @param callback 回调函数
 */
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')   //设置每个片段的长度
            .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.');
    }
}
  • 视频播放相关逻辑,player.ejs中:

    • 使用了videojs作为播放器插件

    • 使用了videojs-contrib-hls作为切片流解码插件

    • 具体的逻辑代码在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>

建议

  • 本项目更多的价值在于展示出一整套的加密原理,同时为了证明这套原理的可行性,做的比较简单的示例。

  • 本项目不会提供相关技术栈的使用教程。

  • 如果需要在实际应用中使用相关原理或技术栈,建议根据实际项目对部分或整体解决方案进行完善和扩展。

杂谈

以下的内容均为个人观点,仅供参考

  由于本人自身是做前端开发的,所以很多相关的示例都是基于前端考虑,对于后端的相应的策略并不是很专业。比如后端服务器,也采用的是偏前端的NodeJS。我想表达的是,在整套解决方案中,我主要做了3件事:

  • 第一,把mp4的视频源通过FFmpeg转换为加密后的m3u8文件和ts文件以及关键的加密密钥key文件;

  • 第二,通过最简单的权限访问,保护加密密钥key文件;

  • 第三,利用video.js及相关的videojs-contrib-hls.js实现客户端的视频文件解密,并播放。

  因此可以看出关于视频加密的解决方案中,最重要的其实是如何保护加密密钥key文件,而这部分工作更多的是在于服务器端的相关策略,比如可以使用cookiesession相关技术、添加自定义token校验、有效时长机制等等方法保证秘钥key文件的相对安全性、可靠性。  

  而如何将视频源文件转化为对应的加密后的文件,可以更多的研究开源库FFmpeg的使用,甚至如果没有迫切需求,可以考虑使用第三方视频云服务商的相关解决方案。至于客户端的视频解密,也可以研究video.js相关的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/36001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows内核--HAL在抽象什么?(3.4)

From: HAL在Kernel和硬件之间 HAL在抽象什么&#xff1f; HAL位于内核最底层。“与硬件直接打交道“的这一层被称为硬件抽象层。顾名思义&#xff0c;Windows内核希望把硬件相关的代码放在HAL模块&#xff0c;而这似乎与WRK众多amd64或x86目录相违背。 注意&#xff0c;任何代…

如何优雅的终止线程 Java

目录 终止线程的方法 打断sleep函数 打断正常执行的线程 两阶段终止模式 错误的方法 使用线程对象的 stop() 方法停止线程 使用 System.exit(int) 方法停止线程 正确的方法&#xff1a;使用 interrrupt 终止线程的方法 XXXThread.interrupt(); 在线程的 run函数中对该线…

NFT+体育,卡塔尔世界杯有哪些NFT看点!

有人说没有冷门的世界杯不是真正的世界杯&#xff01;11月22日&#xff0c;卡塔尔世界杯小组赛C组第1轮比赛中&#xff0c;沙特爆冷2:1逆转阿根廷队&#xff0c;成了今年世界杯的第一个冷门。世界排名第51位的沙特队战胜了排名第3的阿根廷队&#xff0c;结束了阿根廷队此前的36…

vue拖拽删除实现

拖拽删除 背景 自营上传图片&#xff0c;但是需要排序和删除功能&#xff0c;所以用到了h5的拖拽 源元素&#xff1a; 即被拖拽的元素。 目标元素&#xff1a; 即合法的可释放元素。 每个事件的事件主体都是两者之一。 拖拽事件 触发顺序及次数 被拖拽元素&#xff0c;事…

day5-day6【代码随想录】螺旋矩阵II

文章目录前言一、螺旋矩阵||&#xff08;力扣59&#xff09;二、螺旋矩阵&#xff08;力扣54&#xff09;前言 坚持循环不变量原则。 模拟顺时针画矩阵的过程: 填充上行从左到右 填充右列从上到下 填充下行从右到左 填充左列从下到上 由外向内一圈一圈这么画下去 一、螺旋矩阵…

大三保研夏令营须知及前期准备工作

前言 对于大三保研学生而言&#xff0c;学期将近结束&#xff1b;接踵而来的是接下来的保研准备。保研阶段通常可以分为&#xff1a;夏令营、预推免、九推(捡漏)。很多同学往往都是在前两个阶段就能获得满意的offer。 对于计算机专业来说&#xff0c;经历过2022年的“推免季”&…

项目实战——匹配系统(下)

目录 一、整体梳理 二、创建SpringCloud目录 三、创建子项目 四、实现接口 五、config网关配置 六、放行API 七、封装后端逻辑 八、对接匹配系统 九、修改数据库 十、实现匹配之后的逻辑 十一、线程锁 十二、匹配函数 上节课知识梳理&#xff1a; 用户浏览器打开之…

天津专升本报名时的报名点

2023年天津专升本报名区县及应届生、往届生报名点 天津市在校大三应届生报名点选自己的专科院校&#xff0c;往届生及在外省就读的应届生选户籍所在区招办。 退役士兵从天津入伍的选择学校作为报名点&#xff0c;外省市入伍的选择区招办。

slambook2(ch2)—— Ubuntu20.04 使用cmake + make自动化编译过程

slambook2&#xff08;ch2&#xff09;—— Ubuntu20.04 使用cmake make自动化编译过程主函数库函数libhello.cpplibhello.hCMakeLists.txt编译重新编译vim加行号主函数 main.cpp 库函数 libhello.cpp libhello.h CMakeLists.txt 编译 mkdir build && cd build c…

ASEMI肖特基二极管MBR30100CT特征,MBR30100CT应用

编辑-Z ASEMI肖特基二极管MBR30100CT参数&#xff1a; 型号&#xff1a;MBR30100CT 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;100V 最大平均正向整流输出电流&#xff08;IF&#xff09;&#xff1a;30A 峰值正向浪涌电流&#xff08;IFSM&#xff0…

通达信l1l2行情接口-十档行情有哪些优势?

据提供系统或用户编制的条件选股公式进行选股选定一个条件选股公式或多个组合条件后&#xff0c;计算机自动帮您选出当时或历史上某一段时间内满足条件的所有股票十档行情 英文&#xff0c;列在行情下载显示窗口&#xff0c;同时可保留成板块。 那通达信l1l2行情接口-十档行情…

map容器(20221125)

一、map/multimap容器 1、map基本概念 map中所有元素都是pair&#xff1b; pair第一个元素为key&#xff08;键值&#xff09;,起到索引的作用&#xff0c;第二个元素为value(实值)&#xff1b; 所有元素会根据元素的键值&#xff08;key&#xff09;自动排序。 map/multi…

论文阅读笔记 | 三维目标检测——PartA2算法

如有错误&#xff0c;恳请指出。 文章目录0. 前言与补充知识1. 背景2. 相关工作3. 网络结构3.1 Part-aware stageAnchor-free Proposal GenerationAnchor-based Proposal GenerationDiscussion Two Proposal Generation Strategies3.2 Part-aggregation stageROI-aware feature…

ORB-SLAM2 ---- Frame::ComputeBoW函数(TrackReferenceKeyFrame调用版)

目录 1.函数作用 2.什么是BowVec和FeatVec 3.代码 3.1 Frame::ComputeBoW解释 3.2 transform主函数&#xff1a;将一幅图像所有的特征点转化为BowVector和FeatureVector 3.3 transform&#xff1a;将描述子转化为Word id&#xff0c; Word weight&#xff0c;节点所属的…

[毕业设计]机器学习水域检测标注算法

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投…

uniapp里接入lottie-miniprogram详细指南

包工头&#xff1a;小张啊&#xff0c;我们页面里那几个gif也太low了&#xff0c;你能不能追求远大点。ui妹子&#xff1a;软件推荐可以用lottie实现。我&#xff1a;这玩意我耍过&#xff0c;交给我了。 牛逼已经吹出去了&#xff0c;开干&#xff0c; 遇到问题有&#xff0…

基于MxNet实现目标检测-YoloV3【附部分源码及模型】

文章目录前言目标检测发展史及意义一、数据集的准备1.标注工具的安装2.数据集的准备3.标注数据4.解释xml文件的内容二、网络结构的介绍三、代码实现0.工程目录结构如下1.导入库2.配置GPU/CPU环境3.数据加载器4.模型构建YoloV3-tinyYoloV35.模型训练1.学习率设置2.优化器设置3.损…

XSS绕过安全狗WAF

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是XSS绕过安全狗WAF。 一、测试环境搭建 我们使用Vmware虚拟机搭建靶场环境。在Vmware虚拟机上&#xff0c;安装有PHPStudy&#xff0c;如下所示&#xff1a; 然后安装安全狗WAF&#xff0c;安全狗WAF有一系列的…

深度学习入门(五十二)计算机视觉——风格迁移

深度学习入门&#xff08;五十二&#xff09;计算机视觉——风格迁移前言计算机视觉——风格迁移课件样式迁移易于CNN的样式迁移教材1 方法2 阅读内容和风格图像3 预处理和后处理4 抽取图像特征5 定义损失函数5.1 内容损失5.2 风格损失5.3 全变分损失5.4 损失函数6 初始化合成图…

【瑞萨RA4M2】开发环境搭建和点灯指南

【瑞萨RA4系列开发板体验】开发环境搭建和新手点灯指南 文章目录【瑞萨RA4系列开发板体验】开发环境搭建和新手点灯指南一、简单开箱二、芯片简介三、开发环境搭建2.1 安装FSP(RASC)2.2 安装Keil MDK2.3 安装RA4M2 Keil Pack2.4 安装RFP(瑞萨烧录工具)三、新手点灯指南3.1 创建…