python 录制web视频_Python django框架 web端视频加密的实例详解
视频加密流程图:
后端获取保利威的视频播放授权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
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: {
}
}
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```
到此这篇关于Python django框架 web端视频加密的文章就介绍到这了,更多相关Python django框架视频加密内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
本文标题: Python django框架 web端视频加密的实例详解
本文地址: http://www.cppcns.com/jiaoben/python/365540.html
python 录制web视频_Python django框架 web端视频加密的实例详解相关推荐
- python进程socket通信_Python Socket TCP双端聊天功能实现过程详解
SOCKET编程 socket(套接字):是一个网络通信的端点,能实现不同主机的进程通信, -通过IP+端口定位对方并发送消息的通信机制 分为UDP和TCP 客户端Client: 发起访问的一-方 服 ...
- python如何定义类_Python中类的定义、继承及使用对象实例详解
本文实例讲述了Python中类的定义.继承及使用对象的方法.分享给大家供大家参考.具体分析如下: Python编程中类的概念可以比作是某种类型集合的描述,如"人类"可以被看作一个类 ...
- python脚本例子_python dict 字典 以及 赋值 引用的一些实例(详解)
最近在做一个很大的数据库方面的东东,要用到根据数值来查找,于是想到了python中的字典,平时没用过dict这个东东 用的最多的还是 list 和 tuple (网上查 用法一大堆) 看了一下创建字典 ...
- python 经典脚本文件_Python3.5文件读与写操作经典实例详解
本文实例讲述了Python3.5文件读与写操作.分享给大家供大家参考,具体如下: 1.文件操作的基本流程: (1)打开文件,得到文件句柄并赋值给一个变量 (2)通过句柄对文件进行操作 (3)关闭文件 ...
- python从date目录导入数据集_PyTorch加载自己的数据集实例详解
数据预处理在解决深度学习问题的过程中,往往需要花费大量的时间和精力. 数据处理的质量对训练神经网络来说十分重要,良好的数据处理不仅会加速模型训练, 更会提高模型性能.为解决这一问题,PyTorch提供 ...
- Django框架设置cookies与获取cookies操作详解
本文实例讲述了Django框架设置cookies与获取cookies操作.分享给大家供大家参考,具体如下: 在Django里面,使用Cookie和Session看起来好像是一样的,使用的方式都是req ...
- python抽奖滚动界面_Python使用Tkinter实现转盘抽奖器的步骤详解
我使用 Python 中的 Tkinter 模块实现了一个简单的滚动抽奖器,接下来继续写一个简单的转盘抽奖器. 滚动抽奖器与点名的场景相似,是从一群人中抽出中奖的人,奖品是提前确定了的,抽奖只是确定中 ...
- python类的命名空间_Python之关于类变量的两种赋值区别详解
我就废话不多说了,还是直接看代码吧! # -*- coding:utf-8 -*- #面试题,写一个方法,将一行字符串中所有的单词数量统计出来 class Person(object): TAG = ...
- python模拟手写笔迹_Python实现基于KNN算法的笔迹识别功能详解
本文实例讲述了Python实现基于KNN算法的笔迹识别功能.分享给大家供大家参考,具体如下: 需要用到: Numpy库 Pandas库 手写识别数据 点击此处本站下载. 数据说明: 数据共有785列, ...
最新文章
- POJ 1185 炮兵阵地 状压dp
- C++ STL next_permutation() prev_permutation(a,a+n)用法。
- 面向对象设计之CRC卡片
- Django 缓存系统
- 服务器与服务器之前文件传输,客户端与服务器的文件传输
- php mysql知识总结_Mysql数据库知识总结(看资料总结出来的)
- 关于APS生产排产软件选择,有哪几个要素?
- ov5640帧率配置_OV5640摄像头的数据处理配置流程(一)
- 软考高级系统架构设计师系列论文:详细介绍一篇论文的万能模版,快速了解如何写好一篇架构设计师论文
- CYCLONEⅡ系列FPGA 总结
- 修改ipa文件版本号
- php投影,投影+直播双模式方案搭建
- 淘宝“蓝鲸计划”细节内容曝光 收编谷歌中国资源
- linux 搭建Discuz论坛教程-个人实践笔记
- 2018-2019年世界将会出现一场经济危机,危机过后中国将会崛起!
- Alamps学习设计模式之备忘录模式(笑话:劫个色OR抢个鸡蛋版)
- OpenCV 人脸识别方法:特征脸法(应用PCA算法)、费舍尔脸法FisherFace(应用LDA算法)、LBPH方法(应用LBP算法)
- Quality Tools for Android
- soul 源码分析 —— 插件解析之monitor插件
- 码农从1万小时到刻意练习
热门文章
- elementui el-drawer去除自带黑色边框、允许滚动(亲测有效)
- vue事件修饰符:通过@click.self的self属性来阻止内层向外层冒泡
- 【網址收藏】解决VSCODE“因为在此系统上禁止运行脚本“报错
- 【网址收藏】spark on k8s operator github地址
- flink scala shell命令行使用示例
- JVM调优:图解对象内存分配过程
- Python Django 一对多正向查询示例
- Linux centos 6.7防火墙打开MySQL 3306端口
- springboot支持三种嵌入式servlet容器:tomcat(默认),jetty,undertow
- Redisson分布式锁实战(适用于Redis高并发场景)