Python django框架 web端視頻加密的實(shí)例詳解
視頻加密流程圖:

后端獲取保利威的視頻播放授權(quán)token,提供接口api給前端
參考文檔:http://dev.polyv.net/2019/videoproduct/v-api/v-api-play/create-playsafe-token/
在utils下創(chuàng)建polyv.py,編寫token生成工具函數(shù),path:utils/polyv.py
utils 是多個(gè)模塊的公共函數(shù)庫的文件夾里面存放自己開發(fā)的組件
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()
# 獲取視頻數(shù)據(jù)的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: 擴(kuò)展參數(shù)
:param sign: 加密的sign
:return: 返回點(diǎn)播的視頻的token
"""
ts = int(time.time() * 1000) # 時(shí)間戳
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 提供的發(fā)送http請(qǐng)求的模塊
result = requests.post(
url=self.tokenUrl,
headers={"Content-type": "application/x-www-form-urlencoded"},
data=plain # 平臺(tái)所需要攜帶的數(shù)據(jù)
).json() # json.loads 把那拿到的數(shù)據(jù)序列化
token = {} if isinstance(result, str) else result.get("data", {}) # 如果保利威視頻平臺(tái)返回的的字符串 token={} 否則
if token == '':
return result
return token
在 項(xiàng)目開發(fā)時(shí)的本地配置 配置參數(shù):
配置文件settings/dev.py,代碼:
# 保利威視頻加密服務(wù)
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')),
在項(xiàng)目主應(yīng)用文件夾下創(chuàng)建app
命令:
cd 主應(yīng)用文件夾下
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 登錄認(rèn)證
def get(self,request):
polyv_obj = PolyvPlayer(settings.POLYV_CONF['userid'],settings.POLYV_CONF['secretKey'],settings.POLYV_CONF['tokenUrl']) # 調(diào)用polyv文件下的polyv_obj類
# vid = 'cee1047a76927eb43774263cd93bb69f_c' # 存在保利威平臺(tái)的視頻ID
# vid = '348e998797383060cb19620b1c600203_3' # 存在保利威平臺(tái)的視頻ID
vid = request.query_params.get('vid') # 需要把保利威平臺(tái)的視頻ID存在數(shù)據(jù)庫里或者直接或者在前段直接在的Params加 vid cee1047a76927eb43774263cd93bb69f_c
viewerIp = request.META.get('REMOTE_ADDR') # 獲取用戶訪問的IP地址
viewerId = request.user.id # 獲取用戶的id
viewerName = request.user.username # 獲取用戶的賬號(hào)名
token_dict = polyv_obj.get_video_token(vid,viewerIp,viewerId,viewerName) # 調(diào)用polyv文件下的polyv_obj類下的get_video_token方法
print(token_dict)
if 'code' in list(token_dict) and token_dict['code'] != 200: # 返回請(qǐng)求失敗的信息
return Response(token_dict, status=status.HTTP_403_FORBIDDEN)
'''
返回結(jié)果:
{
"code": 403,
"status": "error",
"message": "invalid userId or videoId.",
"data": ""
}
'''
return Response(token_dict) # 返回請(qǐng)求成功的信息
'''
返回結(jié)果:
{
"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接口就已經(jīng)寫好啦!
前段 vue界面 簡(jiǎn)寫:
在src下的components下新建一個(gè)Player.vue
# Player.vue
<template>
<div class="player">
<div id="player">
</div>
</div>
</template>
<script>
export default {
name:"Player",
data () {
return {
}
},
mounted() { //如果需要對(duì)標(biāo)簽進(jìn)行一些加工處理,然后再放數(shù)據(jù)時(shí),需要用mounted這個(gè)鉤子函數(shù),如果單純的是獲取數(shù)據(jù),添加到數(shù)據(jù)屬性中
// 那么用created方法
this.get_video_data();
},
methods: {
get_video_data(){
let user_name = localStorage.username || sessionStorage.username; //token認(rèn)證
let token = localStorage.token || sessionStorage.token; //token認(rèn)證
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 需要復(fù)制這里,其他的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 需要復(fù)制這個(gè)括號(hào)里的,其他的url忽略
path: '/polyv/player/:vid',
//name: 'heme',
component: Player
},
]
})
自己配置的 訪問路徑http://www.luffycity.cn:8080/polyv/player/cee1047a76927eb43774263cd93bb69f_c```
到此這篇關(guān)于Python django框架 web端視頻加密的文章就介紹到這了,更多相關(guān)Python django框架視頻加密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python Django框架介紹之模板標(biāo)簽及模板的繼承
- pycharm中django框架連接mysql數(shù)據(jù)庫的方法
- Python項(xiàng)目實(shí)戰(zhàn)之使用Django框架實(shí)現(xiàn)支付寶付款功能
- Django框架實(shí)現(xiàn)在線考試系統(tǒng)的示例代碼
- Python web框架(django,flask)實(shí)現(xiàn)mysql數(shù)據(jù)庫讀寫分離的示例
- Django框架安裝及項(xiàng)目創(chuàng)建過程解析
- 淺談django框架集成swagger以及自定義參數(shù)問題
- 解決django框架model中外鍵不落實(shí)到數(shù)據(jù)庫問題
- Django框架獲取form表單數(shù)據(jù)方式總結(jié)
- Django添加bootstrap框架時(shí)無法加載靜態(tài)文件的解決方式
- 教你用Python3+mysql8.0搭建Django框架
相關(guān)文章
Python跑循環(huán)時(shí)內(nèi)存泄露的解決方法
這篇文章主要介紹了Python跑循環(huán)時(shí)內(nèi)存泄露的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
Python?網(wǎng)頁請(qǐng)求之requests庫的使用詳解
requests?是?Python?中比較常用的網(wǎng)頁請(qǐng)求庫,主要用來發(fā)送?HTTP?請(qǐng)求,在使用爬蟲或測(cè)試服務(wù)器響應(yīng)數(shù)據(jù)時(shí)經(jīng)常會(huì)用到,使用起來十分簡(jiǎn)潔,這篇文章主要介紹了Python?網(wǎng)頁請(qǐng)求之requests庫的使用詳解,需要的朋友可以參考下2022-09-09
Pytest參數(shù)化parametrize使用代碼實(shí)例
這篇文章主要介紹了Pytest參數(shù)化parametrize使用代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
Python中Pickling和Unpickling的區(qū)別詳解
在本文中,我們將探討 Python 中 pickling 和 unpickling 之間的主要區(qū)別,我們將詳細(xì)討論 Python pickling 和 unpickling 的概念,包括它們的目的、語法、用法以及安全可靠的 pickling 和 unpickling 操作的注意事項(xiàng),需要的朋友可以參考下2023-09-09

