day89:luffy:使用Celery完成我的訂單超時取消&Polyv視訊加密播放

Poke發表於2020-11-13

目錄

1.我的訂單超時取消

2.PoliV視訊播放

1.我的訂單超時取消

使用Celery完成超時取消功能

mycelery/order/tasks.py

from mycelery.main import app
from order.models import Order
import datetime
from lyapi.settings import contains

@app.task(name='cancle_order')
def cancle_order():
    
    # 1.獲取過期時間間隔(設定的是60s)
    expire_time = contains.ORDER_EXPIRE_TIME
    
    # 2.獲取當前時間
    current_time = datetime.datetime.now()
    
    # 3.查詢所有超時過期的訂單
    '''訂單超時的條件:下單時間 < 當前時間 - 過期間隔'''
    expire_order_list = Order.objects.filter(order_status=0,pay_time__lt=current_time - datetime.timedelta(seconds=expire_time))

    # 將超時訂單的所有課程的狀態改為3:超時取消
    for order in expire_order_list:
        order.order_status = 3
        order.save()

constant.py

# 訂單超時時間間隔
ORDER_EXPIRE_TIME = 60

mycelery/config.py

from celery.schedules import crontab
from .main import app

# 定時任務的排程列表,用於註冊定時任務
app.conf.beat_schedule = {
    
    # 每分鐘檢視訂單狀態
    'check_order_outtime': {
        
        # 本次排程的任務
        'task': 'cancle_order', # 這裡的任務名稱必須先到main.py中註冊
        
        # 定時任務的排程週期
        # 'schedule': crontab(minute=0, hour=0),   # 每週凌晨00:00
        
        'schedule': crontab(),   # 每分鐘
          # 'args': (16, 16),  # 注意:任務就是一個函式,所以如果有引數則需要傳遞
    },
}

mycelery/main.py

# 註冊任務[自動搜尋並載入任務]
app.autodiscover_tasks(['mycelery.sms','mycelery.order'])

執行指令

1.先在終端下,執行celery的定時任務程式,以下命令:

celery -A mycelery.main beat

2.然後再新建一個終端,執行以下命令,上面的命令必須先指定:

celery -A mycelery.main worker --loglevel=info

2.PoliV視訊播放

 

 

1.後端介面

專案中有兩種視訊:收費視訊[需要加密]和免費視訊

比如我們在課程詳情頁裡面放的那個視訊播放,是免費的,視訊基本上就是一些課程介紹之類的。

為了保護我們的視訊不容易被人剽竊,所以我們需要對視訊進行加密傳輸,只有購買之後才能看到。保利威、又拍雲、騰訊、網易都有視訊的雲存貯和雲加密服務。

官方網址: http://www.polyv.net/vod/

注意:

開發時通過免費試用註冊體驗版賬號【測試賬號的測試有效期是一週】

公司使用酷播尊享版 

1.後端獲取保利威的視訊播放授權token,提供介面api給前端

參考文件:http://dev.polyv.net/2019/videoproduct/v-api/v-api-play/create-playsafe-token/

根據官方文件的案例,已經有其他人開源了,針對polvy的token生成的python版本了,我們可以直接拿來使用.

lyapi/libs/polyv.py

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]
        print(plain_sorted)

        plain_string = ''
        for k, v in plain_sorted.items():
            plain_string += str(k) + str(v)
        print(plain_string)

        # 首尾拼接上祕鑰
        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", {})

        return token

dev.py

POLYV_CONF = {
    'userid':'e42241e79c',
    'secretKey':'38MWu0xs0d',
    'tokenUrl':'https://hls.videocc.net/service/v1/token'

}

2.獲取polyv token的後端介面

course/urls.py

from django.urls import path,re_path
from . import views

urlpatterns = [
    re_path(r'polyv/token/', views.PolyvView.as_view(),),
]

course/views.py

class PolyvView(APIView):
    # vid = '348e998797383060cb19620b1c600203_3'
    permission_classes = [IsAuthenticated, ]
    def get(self,request):
        polyv_obj = PolyvPlayer(settings.POLYV_CONF['userid'],settings.POLYV_CONF['secretKey'],settings.POLYV_CONF['tokenUrl'])
        vid = request.query_params.get('vid')
        viewerIp = request.META.get('REMOTE_ADDR')
        viewerId = request.user.id
        viewerName = request.user.username

        token_dict = polyv_obj.get_video_token(vid,viewerIp,viewerId,viewerName)

        return Response(token_dict)

3.drf測試:course/polyv/token/?vid=e42241e79c63063c68fbd3de2cb01afc_e  可拿到token

2.前端獲取token

Player.vue

get_video_data(){
          let user_name = localStorage.username || sessionStorage.username;
        let token = localStorage.token || sessionStorage.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}/course/polyv/token/?vid=${self.$route.params.vid}`,{
              headers:{
              'Authorization':'jwt ' + token
              }
            }).then((res)=>{
              // {‘token’:'asasfd'}
              next(res.data.token);

            }).catch((error)=>{

            })

index.html 引入js檔案

index.html

<script src="//player.polyv.net/script/player.js"></script>

課程詳情頁面選擇章節課時開始學習跳轉到視訊頁面

 

Detail.vue

<button class="try" v-if="lesson.free_trail"><router-link :to="'/polyv/player/'+lesson.section_link">立即學習</router-link></button>

相關文章