写点什么

网站上的视频资源被偷偷转载了...

作者:为自己带盐
  • 2023-04-03
    河北
  • 本文字数:4393 字

    阅读完需:约 14 分钟

网站上的视频资源被偷偷转载了...

背景

昨天,公司大佬突然找我,说我们的一个网站上的视频资源被人偷偷转载到了 B 站...

听到这个消息,我内心其实是又惊又喜。

惊的是,我们这个是资源类网站,包括媒体,文字等等,虽然是对外免费开放,但免费不等于可以任意转载,盗版,这不光对我们自己不利,也是对资源中涉及到的各位老师的不尊重,所以要重视起来。

喜的是,竟然有人盗版我们这个小团队做的小网站里的资源了,高低还是在业界产生了点影响啊,哈哈。这也是给我们提了个醒。虽然类似的盗用,转载行为做不到 100%禁止,比如通过一些录屏软件,甚至直接用高清摄像头怼着屏幕录,但作为平台方,我们还是要把一些精力投入到防盗版等版权方面上,起码切断一些常规的盗版手段。剩下的就是法律法规的约束了。

技术手段

那要怎么从技术手段,最大可能的保护网站上的视频资源不被下载呢。

我这里总结了 2 个方案

方案一、视频加密

这里,有一些前提条件。

以我们的网站为例,我们收集到的原始视频,大多是 mp4,mpeg 等常见的视频格式,那我们的做法是把视频以指定的分辨率,码率,帧率进行转码,并分割成 hls 协议的 m3u8 索引文件和 ts 片段(转码分割过程如下图,借助的是 ffmpeg 提供的能力)。



那这次被盗,也正是因为我们的转码并没有进行加密操作,所以通过一些浏览器插件,或者脚本,还是可以很方便的把分段文件下载下来并进行合并的。

所以,目前来说最直接的手段就是在转码分割视频的时候,对分片文件进行加密。

这里加密的方法就是借助 ffmpeg 提供的 hls_key_info_file 参数(传送门👉:https://ffmpeg.org/ffmpeg-all.html,进入后全局搜索 hls_key_info_file 关键字即可)

那要使用这个参数,需要做一些前期准备

1.准备 openssl

如果是 Windows 电脑,且安装过 vm,git,或者 win10 以上安装过 linux 子系统,那可以直接唤起对应的软件,使用 openssl,比如,进入 git 的 bash 窗口,在调用 openssl;或者进入 linux 子系统,直接使用 openssl,就是版本可能有点早




也可以直接安装 Windows 系统下的 openssl 环境,这个我就不多介绍了,大家可以搜一下,方法有很多。

我这里使用的是安装文件进行的安装,安装完成后,再 windows 环境变量里配置好 openssl 的 bin 目录,就可以了




2.一个可以访问的站点

这个我就不多说了,需要创建一个站点,可以访问,如果是测试环境的话,比如 Windows 下,创建一个 iis 站点,对应的设置 mime 类型令其支持.key 和.m3u8 格式,其中.key 的类型设置成文本,json,流等格式都可以,如 application/octet-stream。m3u8 就设置成 application/x-mpegURL

3.生成密钥文件

进入到资源文件目录下,分别执行以下操作,或者整理到脚本里一键执行

openssl rand 16 > file.key #创建密钥文件,这个命令会把密钥写入到file.key文件里,因为是二进制文件,所以直接打开会显示乱码,注意不要自己修改里面的内容
复制代码


openssl rand -hex 16 #这个值要记录下来,如果是脚本生成的,就直接把他写道keyinfo里
复制代码

以上两部操作完成后,如果不是通过脚本操作,需要手动创建一个 file.keyinfo 文件(命名无所谓),最终整理好的 file.keyinfo 文件如下

http://localhost:82/public/upfile/video/file.keyD:\publish\cyscc\Public\upfile\video\file.keyc0b8382ed8f654e07a4f3cf34ff4743e
复制代码

具体解释我上面给的 ffmpeg 链接里都有,总的来说就是 key 的网络路径,本地路径和密钥.

4.加密分割

最终的分割脚本(例子)就成了这样。(注意,这里只介绍加密分片文件的参数,不解释分割,转码等参数,有需要的小伙伴可以到官网查看)

ffmpeg -y -i test2.mp4 -c:v copy -hls_time 10 -hls_list_size 0 -hls_key_info_file file.keyinfo -hls_playlist_type vod -hls_segment_filename test%d.ts -f hls playlist.m3u8
复制代码

上面这行代码是在 Windows 的终端窗口中直接执行,因为涉及到了分片文件的命名模板格式,所以用到了表达式。而如果把这段代码放到批处理脚本中,那上面的模板里的 %d 要改成 %%d

ffmpeg 的脚本准备好后,需要去生成相关的密钥。

如果不进行加密,最终分割完成后的 m3u8 文件长这样

#EXTM3U#EXT-X-VERSION:3#EXT-X-TARGETDURATION:25#EXT-X-MEDIA-SEQUENCE:0#EXTINF:25.000000,test0.ts#EXTINF:25.000000,test1.ts#EXTINF:25.000000,test2.ts#EXTINF:25.000000,.........此处省略很多行,就是分割文件的名称和时长#EXT-X-ENDLIST
复制代码

#EXTM3U:是 M3U8 的文件头;#EXT-X-VERSION:M3U8 文件的版本;

#EXT-X-MEDIA-SEQUENC:第一个 TS 分片的序列号,一般情况下是 0,直播时是动态的;

#EXT-X-TARGETDURATION:每个分片 TS 的最大的时长,单位是秒;

#EXTINF:分片 TS 的信息,如时长,带宽等;

#EXT-X-ENDLIST:结束,也可用来区分是直播或点播;

这几个就是不经过特殊处理,只是常规转码分割之后常见的文件参数,对应的我都给出了 rfc8216 标准文档的的锚点位置,大家感兴趣的可以详细了解下,这里面介绍了关于 HLS(HTTP Live Streaming)协议相关的基本内容,地址👉:https://datatracker.ietf.org/doc/html/rfc8216

最终完成后的么 m3u8 文件就长这样

#EXTM3U#EXT-X-VERSION:3#EXT-X-TARGETDURATION:12#EXT-X-MEDIA-SEQUENCE:0#EXT-X-PLAYLIST-TYPE:VOD#EXT-X-KEY:METHOD=AES-128,URI="http://localhost:82/public/upfile/video/file.key",IV=0xc0b8382ed8f654e07a4f3cf34ff4743e#EXTINF:12.023078,ocean0.ts#EXTINF:12.092211,ocean1.ts#EXTINF:1.818433,ocean2.ts#EXT-X-ENDLIST
复制代码

相比较上面的文件,多了EXT-X-PLAYLIST-TYPEEXT-X-KEY两个参数

其中第一个参数是表明流媒体类型,vod 标识点播

第二个参数就是标识是否进行了加密解析,更具体的解释,可以进入 rfc8216 文档进行查看。

加密完成后的文件是无法直接获取 ts 文件进行播放的,一定要通过索引文件获取到下发的 key 进行解密播放。



也就是说,即便盗版人员通过一些手段获取到了你全部的分片 ts 文件,也无法播放。那接下来,我们要做的就是结合业务,把 key 保护起来。


5.通过代码获取 key

正常来说,经过上面的操作,我们可以借助一些 web 端的播放器插件,完成对加密文件的在线播放。那如果我们要和业务整合,可以把获取 key 的过程写到服务端,在下发 key 之前,完成一些验证,比如是否登录等,如果完成登录,在进行正式 key 的下发。那后端的服务大概就可以这么写(这是测试的写法,正式肯定要结合业务)


[HttpGet]public IHttpActionResult Getkey(){    var path = HostingEnvironment.MapPath("/public/upfile/video/file.key");    var f = new FileInfo(path);    return new FileStreamResult(f.OpenRead(), "application/json");}
复制代码


前台结合 videojs,大概这样写

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>test</title>    <link href="/Public/video.js/8.x/node_modules/video.js/dist/video-js.css" rel="stylesheet"/></head><body style="text-align:center;"><video id="video" class="video-js vjs-default-skin vjs-big-play-centered" controls style="margin: auto">    <source src="playlist.m3u8" type="application/x-mpegURL"></video><script src="/Public/video.js/8.x/node_modules/video.js/dist/video.js""></script><script>    var myPlayer  = videojs('video');  	let initPlayer = new Promise((function(resolve,reject){  			myPlayer .src({  				src:"playlist.m3u8",  				type:"application/x-mpegURL",  				withCredentials: true  			})  			resolve();  		})  	);  	  	  	initPlayer.then(v => {      //这块必须得延时一下,才能调用出vhs属性,注意videojs的文档里有介绍      //tech属于运行时属性,直接调用时控制台窗口会打出一行警告  		 setTimeout(function(){  			 let vhs = myPlayer.tech().vhs  				vhs.xhr.beforeRequest = (options)=>{  					console.log(options)  					return options;  				}  		 },100)  			  	})</script></body></html>
复制代码

配置好后,播放,可以看到每次网络请求都会先请求一下播放密钥,才会播放。




这里要注意一下,因为客户端播放我们是使用了 videojs,并且通过 videojs-http-streaming 插件里提供的运行时属性对 m3u8 文件种 ext-x-key 种的 uri 路径进行了修改,实际这里是要结合业务进行一些逻辑判定的,肯定比我写这个案例要复杂的多。另外,修改的时候,由于 tech 属于运行时属性,所以,使用的时候,控制台会打出警告。



更多的,可以查看官方文档👉:https://github.com/videojs/http-streaming(码云镜像:https://gitee.com/wmlgl/http-streaming

至此我们就完成了一个通过 videojs 播放一个经过加密的 hls 协议的视频的基本流程,这其中还有很多需要完善的地方,比如如果黑客通过验证,获取到下发的 key,虽然它是二进制格式,通过普通的操作肯定是无法保持,相对安全,但其还是会暴露出来,所以应该进一步通过一些手段对 key 进行保护。

我这里只是结合文档初步跑通,后续肯定还会继续优化,分享出来,供不熟悉且有相关需求的小伙伴参考。

好了,这就是通过自主加密的方式,完成对自由平台上视频资源的保护方案了。


方案二、采用云服务

正如上面提到的,自己搞版权保护,技术上还是有一些门槛的,我上面写的实现方案也只是一个最简单的 demo,还要考虑安全之外的很多因素,比如性能,并发播放的流畅度等等。这些对小团队来说,要解决起来,不光是技术成本,还有很多硬件成本,还是要承担一些压力和风险的。

相比之下,采用大厂提供的云解决方案,也不失为一种好的选择。最起码,技术门槛降低了很多,而且不用考虑性能,并发等因素,可以轻松实现高可用。当然对应的就是要掏一些服务费了。

这个具体的对接方案,因为我们也还没有尝试,所以没有什么可写的,就把文档贴出来吧。

以腾讯云为例,实现媒体加密的方式主要是 2 种

一种是防盗链,这种要依赖播放器,而且严格意义上来说也做不到对视频资源的保护,但性价比很高,对接难度低,文档地址👉:https://cloud.tencent.com/document/product/266/11243

另一种就是媒体加密:看了文档,底层的实现逻辑应该是和我们自己加密的流程大体是一致的,只不过腾讯给的方案更加的严谨,高效,可用,只是产生了更高的费用,具体的,大家可以看文档了解👉:https://cloud.tencent.com/document/product/266/73073 (HLS 私有加密),https://cloud.tencent.com/document/product/266/79724(DRM)


最后还是要在强调一下,版权保护是一项复合且复杂的工作,技术层面只是手段之一,还要结合国家法律法规,对盗版者施以相应的举报,警告,要求赔偿金额等手段,多方面的对知识产权进行保护。

好了,差不多就这些了,后续我们应该是会基于方案一,和实际业务整合完善,有机会的话再来分享,果然涉足新鲜的领域很容易让人兴奋啊~~

发布于: 刚刚阅读数: 4
用户头像

学着码代码,学着码人生。 2019-04-11 加入

努力狂奔的小码农

评论

发布
暂无评论
网站上的视频资源被偷偷转载了..._知识产权_为自己带盐_InfoQ写作社区