前后端分离djangorestframework——在线视频平台接入第三方加密防盗录视...

前后端分离djangorestframework——在线视频平台接入第三方加密防盗录视...

2023年7月14日发(作者:)

前后端分离djangorestframework——在线视频平台接⼊第三⽅加密防盗录视频

加密视频在以后的开发项⽬中,很可能有做在线视频的,⽽在线视频就有个问题,因为在线播放,就很有可能视频数据被抓包,如果这个在线视频平台有付费视频的话,这样就会有⼈做点倒卖视频的⽣意了,针对这个问题,⽬前国内有很多不错的加密视频平台,可以把你平台的视频放在他们那⾥,然后通过他们的机制进⾏加密,然后做⼀套机制,当⽤户使⽤平台播放时,其实是平台去加密视频⽅请求过来的加密视频,这样就可以保证视频的安全性了常⽤加密视频平台鄙⼈听说的,有保利威,⾦盾,还有很多很多我叫不上名,搜索引擎⼀搜就有⼀⼤堆的,本次教程说的是保利威

保利威官⽹: 有直播和点播的服务,直播是什么不⽤多说了吧,点播的意思就是我上⾯说的,把录制好的视频放到平台那种

本教程只介绍使⽤云点播功能

⽂档⼿册点击使⽤⼿册的云点播:使⽤⼿册⽂档:

选到h5视频播放:当然你也可以使⽤flash,但是现在的平台基本都⽤的是h5了,所以本次选⽤h5的

官⽅⽂档案例演⽰

复制这段代码放到⼀个html⽂档⾥,直接点那个浏览器标识打开测试: 这个页⾯整个都是保利威给我我们提供的,可以加速播放,可以查看视频参数,可以看列表,然后还有个【test】这个就是跑马灯,相信有过购买视频的朋友都知道,你看你的付费视频时,都有⾃⼰的⽤户名啥的,假如你⾃⼰私⾃录制,传出去,就是⽤这个跑马灯就可以追踪到你的,他官⽅给的实例就是这样

但其实,因为我电脑装了IDM⼯具,且它这个视频只是展⽰,还没有真正的加密(看到后⾯的你就知道为什么没有真正的加密了),所以我的IDM⾃动嗅探视频地址

且还⽀持持断点播放

但是这个由于是案例,所以利⽤IDM直接就可以下载,且播放时还没有⽔印:

好的,演⽰的视频就是这样了。

代码实现

前期准备:你需要注册⼀个保利威的账号,然后拿到id和secret,点设置 - API接⼝:

注意id和secretkey以及token,这⾥的token有读的和写的,后期会⽤到

上传视频上传⼀个测试的视频,上传的时候设置加密参数 上传之前开启加密设置把加密设置打开,然后下⾯的移动端加密按你⾃⼰的需求来,我这⾥暂且不设置

相关的更多的视频配置参数:

好的,我这⾥开始上传,我上传了⼀⾸歌的MV:

上传完之后平台⾃动解码,然后就会有⼀个视频加密的id了:转码之后,审核:

在审核的时候你就可以做⼀些相关的视频设置: 这⾥还有很多的设置,不⼀⼀展⽰,⾃⼰体验了

等待⼤概⼀两分钟之后,显⽰已发布,表⽰可以⽤了:

其他参数配置这⾥还有⼀些设置,⽐如播放域名设置,这些就⾃⼰去体验了,我这⾥这些都直接⽤默认的

查看官⽅⽂档:

看⽂档得知有两个步骤:服务端获取token,将token给客户端客户端拿到token,开始播放视频

获取token

他官⽅⽂档给的是php的,不存在,后⾯重构成Python的就⾏了

播放: 播放有两种播放形式,⼀种是直接在playsafe⾥传⼀个token,⼀种是给⼀个函数,函数必须带视频id和next,next是⼀个函数,在获取token之后将token传到next⾥即可,⽽这官⽅给的⽂档是next(playsafe),这⾥有个坑,不是传playsafe,⽽是传token,我在这卡了很久

再次强调:视频如果是加密的,需要设置加密参数 playsafe,playsafe有两种形式,⼀个是传token,⼀个是传函数+next回调函数,且函数必须把token作为值传进去

下⾯还有更多的配置,切换视频之类的,不⼀⼀展⽰了,⾃⼰研究

代码实现:创建⼀个djangorestframework的项⽬,项⽬名为EncryptVideo,app名为app: url:

polyv对象,在项⽬根⽬录创建utils⽂件夹,该⽂件夹下创建polyv⽂件,定义⼀个Polyv对象 利⽤了设计模式⾥的单例模式返回⼀个polyv_video对象

view:('REMOTE_ADDR') 可以获取客户端的IP地址 导⼊那个polyv对象

html,注意返回数据的层级,这个得根据你返回的数据来定在这之前,我建议最好写⼀个解决跨域请求的中间件,也放在utils⽬录下:

启动项⽬:Python runserver localhost:8000

那个html⽂件利⽤pycharm的功能从浏览器打开:

展⽰结果,朋友们,如果你遇到了这些坑,可以按我的⽅法试试

第⼀个坑(为了不浪费⼤家时间,我上⾯给的截图其实已经是我修改过并且正确的了)发现返回的结果,sign params invild,意思就是说sign参数⽆效,那么再看官⽅⽂档:sign的计算规则根本由这个concated⽣成的:但是这句话,有歧义,按照ASCII升序拼接,到底是先拼接了之后再按ASCII升序还是先按ASCII升序之后再拼接,⽽且他这句,按照ASCKII升序 key + value + key + value ... +value 拼接,确实不知道到底怎么拼接,所以我是这样的:当然你也可以⽤列表⽣成式,反正怎么舒服怎么来,反正拼接顺序就是先按key排序之后再key+value组合

第⼆个坑,这个坑我个⼈认为操作的问题,其实不算坑,如果你遇到跟我⼀样的问题,那恭喜你 嘻嘻(上⾯的截图也是正确的了,不浪费⼤家时间)可以显⽰,但是点击播放放不了,打开控制台,报错了:(ip地址可以忽略,这是我之前测试的时候遇到的问题 )这个问题,我跟你说,看似是同源策略的问题,其实并不是,就是我前⾯标注的那⾥:就是因为两个url没有统⼀导致的,所以必须要统⼀,要嘛都在结束符【/】,要嘛都不带

第三个坑,错误的以为保利威⽅给你报同源策略错误(上⾯截图也是已经是正确的了)

展⽰结果还是不能播放,并且连视频缩略图都没了,⽽且如图:

这个问题我是耗在这耗时最久的,报错的意思就是跨域请求了,浏览器同源策略的问题,但是我把本地的启动ip改成了我局域⽹的ip【192.168.0.8:8000】,html部分axios异步请求那⾥的也是【192.168.0.8:8000】,然后在django配置⽂件的这⾥,我添加了这个

中间价对response的设置前⾯也设置了,启动还是不⾏,后⾯突然醒悟过来,打印看token是否有拿到,确实有拿到

⽽且在我们这个平台,保利威,客户三者之间的关系,其实是这样的:

也就是说,这个问题就是因为第2步之后的第3步上卡住,产⽣了跨域请求,所以这跟我们没多⼤关系了,是保利威视频那边的问题。前⾯这句话前半句是对的(“第2步之后的第3步上卡住了”),后⾯的分析都是错的,但是当时的我不知道啊,按着错误的思路,我想了想,我在保利威后台设置了⼀个视频域名⽩名单:localhost:8000 有朋友回问,保利威那边默认不就是对任何域名都没有限制的吗?是啊,但是我还是设置了,设置之后,果然还是不⾏,我还溯源,准备从这个next参数的开始:

我还去分析了他们的那个js⽂件,想找找next到底是什么:

发现简直⽆从下⼿的。最后我就真的以为是保利威那边的问题域名问题,就是要设置那个域名才⾏,但是我这⾥改下,那⾥改下还成功了: 可以播放了,可以调播放速度啥的,注意,默认打开没有声,是因为默认⾳量按钮没开,⾃⼰点那个喇叭图标打开⾳量

那按着这个错误的思路,有朋友会说,我设置域名是127.0.0.1:8000,把项⽬的启动ip也启动为本地地址看看:访问:

所以还是不能直接是ip地址。 但是!但是,根据我的经验,我还是不太放⼼,我⼜新建了⼀个django项⽬:

逻辑⼀样,然后启动的就是127.0.0.1:8001,然后保利威视频域名限制我也删了:

发现照样能播放:最后经我的研究发现,还是获取token那⾥有问题,我把代码重新写的⾮常浅显明了,什么列表⽣成式的写法都弃了,就为了读代码顺畅(上⾯的代码截图给的已经是正确的了)

结果这样确实可以正常获取token,然后next函数传⼊token就直接播放了。所以我错误的以为保利威那边的问题,饶了很久才发现。以上是我个⼈的从分析问题,⾛错分析的路掉进坑了,然后得到的总结,如果你们没有遇到,⼀⽓呵成,那么你很棒,反正我是遇到了这些坑,最后不放⼼⼜测试了⼀次才找到根本问题的。当然以上都是我个⼈推断,不代表绝对正确

好的,怎么代表我们真的配置好了呢?再上传⼀个视频,然后播放看看,如果真的没问题,那以后就没问题了,我开始上传,并修改html上的id浏览器打开:

相关代码: 保利威视频测试

html

from b import adminfrom import pathfrom import Polyvurlpatterns = [ path('admin/', ), path('polyv', _view()), # 这⾥要与客户端url对应,最后有没有【/】要统⼀]urls

from import settingsimport timeimport requestsimport jsonimport hashlibclass PolyvPlayer(object): userId = _CONFIG['userId'] secretkey = _CONFIG['secretkey'] def tomd5(self, value): """取md5值""" return 5(()).hexdigest() return 5(()).hexdigest() # 获取视频数据的token def get_video_token(self, videoId, viewerIp, viewerId=None, viewerName='', extraParams='HTML5'): """ :param videoId: 视频id :param viewerId: 看视频⽤户id :param viewerIp: 看视频⽤户ip :param viewerName: 看视频⽤户昵称 :param extraParams: 扩展参数 :param sign: 加密的sign :return: 返回点播的视频的token """ ts = int(() * 1000) # 时间戳 plain = { "userId": , 'videoId': videoId, 'ts': ts, 'viewerId': viewerId, 'viewerIp': viewerIp, 'viewerName': viewerName, 'extraParams': extraParams } # 按照官⽅⽂档,将参数 按照ASCKII升序 key + value + key + + value 拼接 plain_sorted = {} key_temp = sorted(plain) for key in key_temp: plain_sorted[key] = plain[key] print(plain_sorted) plain_string = '' for k, v in plain_(): plain_string += str(k) + str(v) print(plain_string) sign_data = key + plain_string + key # 取sign_data的md5的⼤写 sign = 5(sign_data).upper() # 新的带有sign的字典 ({'sign': sign}) print('plain', plain) result = ( url='/service/v1/token', headers={"Content-type": "application/x-www-form-urlencoded"}, # ⼀定要带上这个请求头 data=plain ).json() data = {} if isinstance(result, str) else ("data", {}) return {"token": data}polyv_video = PolyvPlayer() from ation import MiddlewareMixinclass MyCorsMiddelware(MiddlewareMixin): def process_response(self, request, response): response["Access-Control-Allow-Origin"] = "*" if == "OPTIONS": response["Access-Control-Allow-Headers"] = "*" return responsemiddlewares

# --------- 保利威视频注册⽤户id和key--------POLYV_CONFIG = { 'userId': '您的id', # polyv 提供的服务器间的通讯验证 'secretkey': '您的secret' # polyv 提供的接⼝调⽤签名访问的key}settings部分

from uts import renderfrom rest_ import APIViewfrom rest_se import Responsefrom import HttpResponsefrom import polyv_videoimport jsonclass Polyv(APIView): def post(self, request): vid = ("vid") remote_addr = ("REMOTE_ADDR") user_id = 1 user_name = "test" verify_data = polyv__video_token(vid, remote_addr, user_id, user_name) return Response(verify_data["token"])views

播放跑马灯

以上步骤其实已经可以满⾜⼤部分⽤户了,但是有朋友发现了,这⾥还是可以⽤IDM直接下载啊: 所以接下来就要设置跑马灯了

1.设置视频授权跑马灯根据我的观察,好像默认就开启了跑马灯的 2.设置⼀个授权地址这个地址可以是本地的

3.创建⼀个html⽂件,名字随意,存⼊如下代码:

这⾥的域名部分,官⽅建议这样设置,其实在后⾯我测试的时候,发现按照下⾯这个设置,兼容性不好,⾕歌可以播放,IE浏览器放不了

部分添加⼀个指向test_bolyv视图函数视图函数:

5.视频接⼝/polyv添加get⽅法这个get⽅法是保利威后台⾃动调⽤的,不是我们这边服务端要⽤的,也不是客户端要⽤的user_name部分就是要显⽰的跑马灯数据

6.在定义的polyv类⾥添加⽅法:get_play_key和get_resp get_play_key是获取sign的,注意这⾥的设置sign和上⾯获取加密视频的sign不太⼀样

get_resp是做跑马灯授权的:

7.引⼊新的js

这⾥他给的例⼦是⽤的不加密的⽅式

我们要播放加密视频,当然还是得使⽤playsafe参数播放,在templates⽬录下新建⼀个,代码如下,我标注出来的就是添加的参数,同样的,注意返回数据的层级

启动项⽬:

通过pycharm虚拟⼀个客户端出来,点击那些浏览器图标打开,我的电脑是windows,所以试了⾕歌,⽕狐和IE ⾕歌:⾕歌默认打开是没有声⾳的,这是⾕歌浏览器的策略问题,不是⼤问题,正常播放,且正常显⽰跑马灯

IE:再次强调,如果在那个xml⽂件⾥,你如果按官⽅的建议设置成这样:然后你打开IE是播放不了的: 所以别按它建议的设置,就⽤默认的

⽕狐:问题来了,就是这个问题,我折腾⽼久了,这个根本原因还是跨域请求问题,因为⽕狐浏览器默认安全性⽐较⾼,所以⾕歌和IE可以,就是⽕狐不⾏,我查阅了很多,⽐如关闭⽕狐的跨域请求的,设置跨域请求的,设置了很多,还是没⽤,最后使⽤了第三⽅库django-cors-headers解决了,相关介绍安装⽂章: 第5个⽅法

根据操作,重启项⽬,⽕狐⽴马播放:

然后现在你看我⽤IDM点下载:

我随便选了⼀个: 提⽰:

最后再来个辅助测试,换个视频id播放看看,换回这个视频

⽕狐,⾕歌,IE:

确实没有问题了,这样的操作是不是很6啊,我反正感觉很6

详细的参数配置步骤就没展开了,具体看官⽅⽂档吧:

相关代码:

Title

前端html

bolyv_

from import settingsimport timeimport requestsimport requestsimport jsonimport hashlibclass PolyvPlayer(object): userId = _CONFIG['userId'] secretkey = _CONFIG['secretkey'] def tomd5(self, value): """取md5值""" return 5(()).hexdigest() # 获取视频数据的token def get_video_token(self, videoId, viewerIp, viewerId=None, viewerName='', extraParams='HTML5'): """ :param videoId: 视频id :param viewerId: 看视频⽤户id :param viewerIp: 看视频⽤户ip :param viewerName: 看视频⽤户昵称 :param extraParams: 扩展参数 :param sign: 加密的sign :return: 返回点播的视频的token """ ts = int(() * 1000) # 时间戳 plain = { "userId": , 'videoId': videoId, 'ts': ts, 'viewerId': viewerId, 'viewerIp': viewerIp, 'viewerName': viewerName, 'extraParams': extraParams } # 按照官⽅⽂档,将参数 按照ASCKII升序 key + value + key + + value 拼接 plain_sorted = {} key_temp = sorted(plain) for key in key_temp: plain_sorted[key] = plain[key] print(plain_sorted) plain_string = '' for k, v in plain_(): plain_string += str(k) + str(v) print(plain_string) sign_data = key + plain_string + key # 取sign_data的md5的⼤写 sign = 5(sign_data).upper() # 新的带有sign的字典 ({'sign': sign}) print('plain', plain) result = ( url='/service/v1/token', headers={"Content-type": "application/x-www-form-urlencoded"}, # ⼀定要带上这个请求头 data=plain ).json() data = {} if isinstance(result, str) else ("data", {}) return {"token": data} def get_play_key(self, vid, username, code, status, ts): def get_play_key(self, vid, username, code, status, ts): """ :param vid: 视频 vid :param username: 响应跑马灯展⽰ :param code: ⾃定义参数 :param status: 是否可播放, 1、可播放 2、禁播 :param ts: 时间戳 :return: 返回跑马灯视频的key """ return 5("vid={}&secretkey={}&username={}&code={}&status={}&t={}".format( vid, key, username, code, status, ts)).lower() @staticmethod def get_resp(status, username, sign, msg="授权暂未通过"): res_str = { "status": status, "username": username, "sign": sign, "msg": msg, "fontSize": "18", "fontColor": "0xFF0000", "speed": "50", "filter": "on", "setting": "2", "alpha": "0.7", "filterAlpha": "1", "filterColor": "0x3914AF", "blurX": "2", "blurY": "2", "tweenTime": "1", "interval": "3", "lifeTime": "3", "strength": "4", "show": "on" } return res_strpolyv_video = PolyvPlayer() - ⾃定义的polyv类 from uts import renderfrom rest_ import APIViewfrom rest_se import Responsefrom import HttpResponsefrom import polyv_videoimport jsonclass Polyv(APIView): def post(self, request): vid = ("vid") remote_addr = ("REMOTE_ADDR") user_id = 1 user_name = "test" verify_data = polyv__video_token(vid, remote_addr, user_id, user_name) return Response(verify_data["token"]) def get(self, request, *args, **kwargs): vid = _("vid", "") code = _("code", "") t = _("t", "") callback = _("callback", "") user_name = "test|1234565" status = 1 # username, code, status, t sign = polyv__play_key(vid, user_name, code, status, t) print(sign) res_str = polyv__resp(int(status), user_name, sign) res_str = (res_str, ensure_ascii=False) if callback != "": ret = callback + "(" + res_str + ")" else: ret = res_str print(ret) return HttpResponse(ret)# 解决跨域def test_bolyv(request): return render(request, "bolyv_")views

from b import adminfrom import path, re_pathfrom import test_bolyvfrom import Polyvurlpatterns = [ path('admin/', ), path('polyv', _view()), # 这⾥要与客户端url对应,最后有没有【/】要统⼀ re_path(r'^', test_bolyv)]urls INSTALLED_APPS = [ '', '', 'ttypes', 'ns', 'es', 'files', 'fig', 'corsheaders',]MIDDLEWARE = [ 'tyMiddleware', 'nMiddleware', 'ddleware', 'Middleware', # 注意顺序 'ewMiddleware', 'ticationMiddleware', 'eMiddleware', 'OptionsMiddleware', # 'Middelware' # 这是我们⾃⼰定义的那个中间件]# --------- 保利威视频注册⽤户id和key--------POLYV_CONFIG = { 'userId': '您的id', # polyv 提供的服务器间的通讯验证 'secretkey': '您的secret' # polyv 提供的接⼝调⽤签名访问的key}# 跨域增加忽略CORS_ALLOW_CREDENTIALS = TrueCORS_ORIGIN_ALLOW_ALL = TrueCORS_ORIGIN_WHITELIST = ( '*')CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW',)CORS_ALLOW_HEADERS = ( 'XMLHttpRequest', 'X_FILENAME', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with',) - 部分配置

总结经过这前后⼏个接⼊第三⽅平台的案例,发现其实都不算难,但是都有⼀些坑,必须要⾃⼰去实践去研究了才能玩得会⽕狐浏览器的安全级别默认很⾼,需要借助第三⽅库来配置跑马灯视频设置get请求的url必须和主逻辑API接⼝是同⼀个遇到问题还是多研究,多理解,多分析

发布者:admin,转转请注明出处:http://www.yc00.com/web/1689328199a230561.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信