音视频-加密技术方案

2022-03-14 项目 阅读 980 次

问题

针对音视频-加密技术需求,基于现有技术成果基础上,设计音视频被盗方案

首先,想要杜绝音视频被盗,是不可能的。只能提高技术门槛,让有心者盗取相对麻烦,并且我们可以轻松调节密钥,慢慢的让较低损失,逐步集成成熟的防盗方案

为什么选择开源技术

成本低廉,技术成熟,对专业有一定门槛,只需要技术自定义加密手段(这是核心,一切核心在于加密)

注意:我们不该轻易造轮子,利用现有技术,加上核心诉求,成本合理的情况,迅速找到技术解决方案

初步方案设计

技术方案梳理-手稿

音视频-加密技术方案-黄继鹏博客

技术方案梳理-架构图

音视频-加密技术方案-黄继鹏博客

流程补充

音视频-加密技术方案-黄继鹏博客

调研实例

播放器与资源与服务端的交互

m3u8加密是怎么回事

我们看下加密的m3u8文件的格式

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-KEY:METHOD=AES-128,URI="http://xxxxxx:5555//test/1102/test/segments.key"
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXTINF:13.966667,
http://xxxxxx:5555/test/1102/test/segments0.ts
#EXTINF:10.000000,
http://xxxxxx:5555/test/1102/test/segments1.ts
#EXTINF:10.000000,
http://xxxxxx:5555/test/1102/test/segments2.ts
#EXTINF:10.000000,
http://xxxxxx.cn:5555/test/1102/test/segments3.ts
#EXTINF:10.000000,
http://xxxxxxn.cn:5555/test/1102/test/segments4.ts
#EXTINF:7.033333,
http://xxxxxx:5555/test/1102/test/segments5.ts
#EXTINF:10.000000,

看到了多了个字段EXT-X-KEY,这个也是m3u8给规定好的加密字段,如果包含这个字段播放器就会先去请求这个key,然后拿这个这个key去访问加密的TS视频就可以播放了(我们可以在这里做文章,服务端在上传文件使用FFmpeg 分片的时候,自定义加密逻辑,客户端每次播放完一个分片后,会通过自定义key解密,才可以读取正确的next ts,才可以继续播放,这是加密的核心)。

在线演示

  1. 打开网址:http://videojs.github.io/videojs-contrib-hls/

  2. 输入加密视频地址:https://test-streams.mux.dev/dai-discontinuity-deltatre/manifest.m3u8

  3. 打开控制台查看,三端交互

音视频-加密技术方案-黄继鹏博客

客户端实现播放加密缓存的思路

  1. 我们首先按照特定的格式去解析这m3u8文件。
  2. 按照解析出来的ts文件按照我们知道的规则组拼起来,下载这些ts文件,存放在手机的sd卡,这些下载下来的TS视频文件是播放不了的,需要把正确的key下载下来,加上定期的key解密算法,才可以读取这些TS。
  3. 我们需要在本地搭建一个本地http服务。本地服务器我们通过过滤特定的接口名字,来实现根据不同ts名字返回不同的视频文件(这里最好生成和原始的ts文件的名字一样)
  4. 我们如何知道播放器播完一段视频呢,因为他是一段一段播放的,所以这里就需要我们在本地生成一份本地指向我们本地服务器的m3u8文件,直接播放本地的时候直接返给播放器,这里多了我们需要多个加密的key。我们本地增加一个过滤接口的方法,判断如果是访问加密的key就先把key返给播放器,然后播放器会紧接着去请求拿去ts视频这样我们就可以把视频返给他,它内部就会去解密进行播放了。

技术栈

NODE.JS + FFmpeg + HLS + WEB + REACT NATIVE

客户端,沙箱存储逻辑

解析

var fs=RNFetchBlob.fs
var path=RNFetchBlob.fs.dirs.DocumentDir

//建音视频主文件
var videocache=path+'/videocache'
let isDir=await fs.isDir(videocache)
if(!isDir){
  await fs.mkdir(videocache)
    .then(() => {console.log('创建 videocache 文件成功')})
    .catch((err) => {console.log('创建 videocache 文件失败')})
}

var url='http://video.samuredwonder.com/6f94765277492f9b8ab181ce6a22b387%3D%2FlrOn4B7V9FewWz96xCggAUHObdPc%2F0?pm3u8/0/expires/90384&e=1524169405&token=vcZj_ZMWMJ8gU759Lfsd8_A2jgriPXGS6tBJX1Ss:u5YUx1lI_8VzrXrgTOGOvkurKUs=';

let dirs = videocache+'/test.m3u8'
var dirsRes=await this.downloadVideo(url,dirs)
console.log(dirsRes)

//得到m3u8内容
var manifest = await dirsRes.text()
console.log(manifest)

//解析主体m3u8
var parser = new m3u8Parser.Parser();
parser.push(manifest);
parser.end();
var parsedManifest = parser.manifest;
console.log(parsedManifest)

//得到媒体源列表
var segments=parsedManifest.segments
console.log(segments)
if(segments){
  this.walk(segments,videocache)
}

下载切片列表,加密ts文件,创建对应音视频目录

async walk(segments,videocache){
  this.asyncForEach(segments, async x => {
    var qianzui='http://video.samuredwonder.com'
    let dirs = videocache+'/'+x.uri
    let url = qianzui+x.uri
    var res = this.downloadVideo(url,dirs)
    console.log(res)
  })
}

downloadVideo(fromUrl, toFile){
  const activeDownloads = {};
  activeDownloads[toFile] = new Promise((resolve, reject) => {
      RNFetchBlob
          .config({path: toFile})
          .fetch('GET', fromUrl)
          .then(res => {
              if (Math.floor(res.respInfo.status / 100) !== 2) {
                  throw new Error('Failed to successfully download video');
              }
              //resolve(toFile);
              resolve(res);
          })
          .catch(err => {
              return deleteFile(toFile)
                .then(() => reject(err));
          })
          .finally(() => {
              // cleanup
              delete activeDownloads[toFile];
          });
  });
  return activeDownloads[toFile];
}

播放沙箱加密音视频

参考

http://ffmpeg.org/

https://github.com/fluent-ffmpeg/node-fluent-ffmpeg

https://zhuanlan.zhihu.com/p/435343511

https://www.cnblogs.com/TheViper/p/4363383.html

https://github.com/videojs/videojs-contrib-hls/blob/master/README.md

https://www.npmjs.com/package/react-native-video

0条评论
...