Python django框架 web端视频加密的实例详解
作者:於 兔シ 发布时间:2022-08-10 06:05:04
标签:Python,django,视频加密
视频加密流程图:
后端获取保利威的视频播放授权token,提供接口api给前端
参考文档:http://dev.polyv.net/2019/videoproduct/v-api/v-api-play/create-playsafe-token/
在utils下创建polyv.py,编写token生成工具函数,path:utils/polyv.py
utils 是多个模块的公共函数库的文件夹里面存放自己开发的组件
from django.conf import settings
import time
import requests
#pip install requests
import hashlib
class PolyvPlayer(object):
def __init__(self,userId,secretkey,tokenUrl):
"""初始化,提供用户id和秘钥"""
self.userId = userId
self.secretKey = secretkey
self.tokenUrl = tokenUrl
def tomd5(self, value):
"""取md5值"""
return hashlib.md5(value.encode()).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(time.time() * 1000) # 时间戳
plain = {
"userId": self.userId,
'videoId': videoId,
'ts': ts,
'viewerId': viewerId,
'viewerIp': viewerIp,
'viewerName': viewerName,
}
# 按照ASCKII升序 key + value + key + value... + value 拼接
plain_sorted = {}
key_temp = sorted(plain)
for key in key_temp:
plain_sorted[key] = plain[key]
plain_string = ''
for k, v in plain_sorted.items():
plain_string += str(k) + str(v)
# 首尾拼接上秘钥
sign_data = self.secretKey + plain_string + self.secretKey
# 取sign_data的md5的大写
sign = self.tomd5(sign_data).upper()
# 新的带有sign的字典
plain.update({'sign': sign})
# python 提供的发送http请求的模块
result = requests.post(
url=self.tokenUrl,
headers={"Content-type": "application/x-www-form-urlencoded"},
data=plain # 平台所需要携带的数据
).json() # json.loads 把那拿到的数据序列化
token = {} if isinstance(result, str) else result.get("data", {}) # 如果保利威视频平台返回的的字符串 token={} 否则
if token == '':
return result
return token
在 项目开发时的本地配置 配置参数:
配置文件settings/dev.py,代码:
# 保利威视频加密服务
POLYV_CONFIG = {
"userId":"62dc475e3f",
"secretkey":"h6FiaEBRMU",
"tokenUrl":"https://hls.videocc.net/service/v1/token",
}
保利威文档地址:https://my.polyv.net/secure/setting/api
保利威api参考文档:http://dev.polyv.net/2019/videoproduct/v-api/v-api-play/create-playsafe-token/
urls.py,主路由代码:
path(r'polyv/',include('polyv.urls')),
在项目主应用文件夹下创建app
命令:
cd 主应用文件夹下
python3 …/…/manage.py startapp polyv
urls.py,子路由代码:
from django.urls import path,re_path
from . import views
urlpatterns = [
path('video/',views.Video.as_view(),)
]
polyv/views.py,视图代码:
from django.shortcuts import render
# Create your views here.
from rest_framework import status
from lyapi.utils.polyv import PolyvPlayer
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from django.conf import settings
from rest_framework.response import Response
class VideoView(APIView):
# vid = '348e998797383060cb19620b1c600203_3'
# permission_classes = [IsAuthenticated, ] #from rest_framework.permissions import IsAuthenticated 登录认证
def get(self,request):
polyv_obj = PolyvPlayer(settings.POLYV_CONF['userid'],settings.POLYV_CONF['secretKey'],settings.POLYV_CONF['tokenUrl']) # 调用polyv文件下的polyv_obj类
# vid = 'cee1047a76927eb43774263cd93bb69f_c' # 存在保利威平台的视频ID
# vid = '348e998797383060cb19620b1c600203_3' # 存在保利威平台的视频ID
vid = request.query_params.get('vid')# 需要把保利威平台的视频ID存在数据库里或者直接或者在前段直接在的Params加 vid cee1047a76927eb43774263cd93bb69f_c
viewerIp = request.META.get('REMOTE_ADDR') # 获取用户访问的IP地址
viewerId = request.user.id # 获取用户的id
viewerName = request.user.username # 获取用户的账号名
token_dict = polyv_obj.get_video_token(vid,viewerIp,viewerId,viewerName) # 调用polyv文件下的polyv_obj类下的get_video_token方法
print(token_dict)
if 'code' in list(token_dict) and token_dict['code'] != 200: # 返回请求失败的信息
return Response(token_dict, status=status.HTTP_403_FORBIDDEN)
'''
返回结果:
{
"code": 403,
"status": "error",
"message": "invalid userId or videoId.",
"data": ""
}
'''
return Response(token_dict) # 返回请求成功的信息
'''
返回结果:
{
"token": "43883858-92a3-4f25-a6e8-701d10d88cde-f2",
"userId": "cee1047a76",
"appId": null,
"videoId": "cee1047a76927eb43774263cd93bb69f_c",
"viewerIp": "127.0.0.1",
"viewerId": "2",
"viewerName": "root",
"extraParams": null,
"ttl": 600000,
"createdTime": 1605614888570,
"expiredTime": 1605615488570,
"iswxa": 0,
"disposable": false
}
'''
到这里后端的api接口就已经写好啦!
前段 vue界面 简写:
在src下的components下新建一个Player.vue
# Player.vue
<template>
<div class="player">
<div id="player">
</div>
</div>
</template>
<script>
export default {
name:"Player",
data () {
return {
}
},
mounted() { //如果需要对标签进行一些加工处理,然后再放数据时,需要用mounted这个钩子函数,如果单纯的是获取数据,添加到数据属性中
// 那么用created方法
this.get_video_data();
},
methods: {
get_video_data(){
let user_name = localStorage.username || sessionStorage.username; //token认证
let token = localStorage.token || sessionStorage.token;//token认证
console.log(this.$route.params.vid)
let self = this;
var player = polyvPlayer({
wrap: '#player',
width: document.documentElement.clientWidth - 300,
height: document.documentElement.clientHeight,
vid: this.$route.params.vid,
// forceH5: true,
// code: user_name,
playsafe: (vid, next) =>{
console.log(self)
self.$axios.get(`${self.$settings.Host}/polyv/video/?vid=${self.$route.params.vid}`,{
headers:{
'Authorization':'jwt ' + token
}
}).then((res)=>{
// {‘token':'asasfd'}
next(res.data.token);
}).catch((error)=>{
})
}
});
}
},
computed: {
}
}
</script>
<style scoped>
</style>
src下的router的index.js配置url:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import Login from '@/components/Login'
import Register from "@/components/Register";
import Course from "@/components/Course"
import Detail from "@/components/Detail";
import Cart from "@/components/Cart";
import Order from "@/components/Order";
import Player from "@/components/Player";//Player组件的url 需要复制这里,其他的url忽略
import Myorder from "@/components/Myorder";
Vue.use(Router)
export default new Router({
mode:'history',
routes: [
{
path: '/',
//name: 'heme',
component: Home
},
{
path: '/home',
//name: 'heme',
component: Home
},
{
path: '/user/login',
//name: 'heme',
component: Login
},
{
path: '/register',
//name: 'heme',
component: Register
},
{
path: '/courses',
//name: 'heme',
component: Course
},
{
path: '/courses/detail/:id',
//name: 'heme',
component: Detail
},
{
path: '/cart',
//name: 'heme',
component: Cart
},
{
path: '/order',
//name: 'heme',
component: Order
},
{
path: '/myorder',
//name: 'heme',
component: Myorder
},
{//Player组件的url 需要复制这个括号里的,其他的url忽略
path: '/polyv/player/:vid',
//name: 'heme',
component: Player
},
]
})
自己配置的 访问路径http://www.luffycity.cn:8080/polyv/player/cee1047a76927eb43774263cd93bb69f_c```
来源:https://blog.csdn.net/yutu75/article/details/109682510
0
投稿
猜你喜欢
- 1.反变换法设需产生分布函数为F(x)的连续随机数X。若已有[0,1]区间均匀分布随机数R,则产生X的反变换公式为:F(x)=r, 即x=F
- 学习目的 接触验证控件 昨天介绍了SQL SERVER插入数据,但是我们省略了验证输入这一步。以前的做法是用语句逐个判断输入的正确性,如是否
- 1、运算概念的理解运算(Operation)是操作逻辑的抽象运算体现一种操作逻辑,在广义角度来说任何程序都是一种运算Python解释器通过保
- 前言本文将教你如何使用YOLOV3对象检测器、OpenCV和Python实现对图像和视频流的检测。用到的文件有yolov3.weights、
- 1. tensorflow模型文件打包成PB文件import tensorflow as tffrom tensorflow.python.
- NumPy提供了多种存取数组内容的文件操作函数。保存数组数据的文件可以是二进制格式或者文本格式。二进制格式的文件又分为NumPy
- 本文实例为大家分享了python实现网上购物系统的具体代码,供大家参考,具体内容如下1.购物商城的需求分析:1、输出欢迎界面还有登录注册菜单
- 将汉字转为拼音,可以用于批量汉字注音、文字排序、拼音检索文字等常见场景。现在互联网上有许多拼音转换工具,基于Python的开源模块也不少,今
- 开发背景是这样的:整个项目中使用很多台摩托罗拉的RFID读卡器,我要为这些读卡器写一个管理程序,判断是否有RFID标签进入或离开某个区域。用
- 昨天我问过这个问题怎么用ADODB.Stream来读取或写入文件,而不是用fso,不过没人回答到点上,今天搞定了.贴出来给觉得有用的朋友,希
- 本文实例讲述了Python随机数用法。分享给大家供大家参考,具体如下:1. random.seed(int)给随机数对象一个种子值,用于产生
- 所以爱微网现在讲解先php内置函数 有大小写转换相关函数 文本html标签处理函数大小写有关函数 strtolower() strtoupp
- 忙碌了一年,今天终于放假了。原本打算好好休息一下,没成想只过了半天就觉得有点无聊。看家人和朋友们都在忙年,那我就用OpenGL导演一场烟花盛
- 废话不多说1.win+R 启动“运行”输入cmd 点确定2.输入 cd /d xxxxxxx回车jupyter notebook回车在这里我
- 在ie7发布之前,Dean的addEvent/removeEvent可以称的上是完美了。IE7发布后,引入新的内存泄漏(这个我不是很确定,忘
- 前言:又到每日分享Python小技巧的时光了,今天给大家分享的是Python接口常用封装函数。相信对于封装,大家都不陌生吧,今天就用四个小案
- 简单使用最开始,我们用最短的代码体验一下logging的基本功能。import logginglogger = logging.getLog
- 爬虫库使用简单的requests库,这是一个阻塞的库,速度比较慢。解析使用XPATH表达式总体采用类的形式多线程使用concurrent.f
- numpy作为python科学计算的基础模块,支撑起了pandas、matplotlib等使用。其中,ndarray作为numpy的重要
- 02条件语句和while循环三目运算a = 6#原判断语句if a > 5:print(True)else:print(False)#