视频的上传及购买播放

一、上传视频

 

1:使用百度云:

  1. 登录百度云:https://cloud.baidu.com/ 进入管理控制台;
  2. 开通 “视频点播VOD” 服务;
  3. 在后台管理系统 --> 右上角“安全认证” --> 获取 “AccessKey”;
  4. 在 “视频点播VOD” 界面 --> 全局设置 --> 发布设置 --> 安全设置 --> 获取 “UserKey”;

 

2:自定义转码设置:

 

1、视频需经过加密在进行发布,先创建一个编码模板(配置如下):

  1. 容器:选择 HLS(Http Live Streaming);
  2. 编码规格:high高;
  3. 分辨率 (视频码率):1920_1080 (2500) ,2180_720 (1024) ,800*600 (512)等;
  4. 加密策略:Token;

 

 

 

2、进入 媒资管理 进行视频上传,选择 自定义转码模板组

 

 二:视频的播放

 

1、后端代码

 

  1. 获取 ‘tokon’ 的值(参照官方文档:https://cloud.baidu.com/doc/VOD/BestPractise.html#token.E8.AE.A1.E7.AE.97.E8.A7.84.E5.88.99
     1 # 获取tokon;
     2 def course_token(request):
     3     # video:是视频文件的完整链接
     4     file = request.GET.get('video')
     5     # 过期时间;
     6     expiration_time = int(time.time()) + 2 * 60 * 60
     7 
     8     USER_ID = settings.BAIDU_CLOUD_USER_ID
     9     USER_KEY = settings.BAIDU_CLOUD_USER_KEY
    10 
    11     # file=http://hemvpc6ui1kef2g0dd2.exp.bcevod.com/mda-igjsr8g7z7zqwnav/mda-igjsr8g7z7zqwnav.m3u8
    12     # 先获取扩展名;再通过‘/’分割取最后一个值,并将扩展名替换为空字符串;得到‘ID’;
    13     extension = os.path.splitext(file)[1]
    14     media_id = file.split('/')[-1].replace(extension, '')
    15 
    16     # 将‘USER_KEY’进行编码;后面的‘hmac.new()’只能接受bytes类型;
    17     # unicode->bytes=unicode.encode('utf-8')bytes
    18     key = USER_KEY.encode('utf-8')
    19     message = '/{0}/{1}'.format(media_id, expiration_time).encode('utf-8')
    20 
    21     # signature:生成签名;
    22     # disgestmod:指定加密方式;
    23     signature = hmac.new(key, message, digestmod=hashlib.sha256).hexdigest()
    24     token = '{0}_{1}_{2}'.format(signature, USER_ID, expiration_time)
    25     return restful.result(data={'token': token})

    (url 映射地址:cms/course_token)

 

 

2、前端代码

 

  1. 下载 videojs 文件:http://sdk.bce.baidu.com/media-sdk/Baidu-T5Player-SDK-Web-v3.4.0.zip
  2. 将 videojs 文件的 js 文件添加到项目文件目录中,以便 HTML模板 引用;
     1 <!-- HTML中需引用的文件 -->
     2     <script src="{% static 'videojs/video.min.js' %}"></script>
     3     <script src="{% static 'videojs/videojs-contrib-hls.min.js' %}"></script>
     4     <script src="{% static 'videojs/videojs-contrib-quality-levels.min.js' %}"></script>
     5 
     6     <!-- 加载播放器 -->
     7     <script type="text/javascript" src="https://cdn.bdstatic.com/jwplayer/latest/cyberplayer.js"></script>
     8 
     9     <!-- 初始化播放器的 js 文件 -->
    10     <script src="{% static 'js/cms/course_detail.min.js' %}"></script>

     

  3. 并创建一个用来加载视频的容器;
    1 <div class="video-group">
    2     <span id="video-info" hidden data-video-url="{{ course.video_url }}"
    3           data-cover-url="{{ course.cover_url }}"></span>
    4     <!-- 用来存储播放器 -->
    5     <div id="playercontainer"></div>
    6 </div>

     

  4. 通过 js 初始化播放器,并传递视频地址;
     1 function CourseDetail() {
     2 
     3 }
     4 
     5 // 视频播放;
     6 CourseDetail.prototype.initPlayer = function () {
     7     var videoInfoSpan = $('#video-info');
     8     var video_url = videoInfoSpan.attr('data-video-url');
     9     var cover_url = videoInfoSpan.attr('data-cover-url');
    10     var player = cyberplayer("playercontainer").setup({
    11         width: '100%',
    12         height: '100%',
    13         file: video_url,            // 视频链接;
    14         image: cover_url,           // 封面图链接;
    15         autostart: false,           // 是否自动播放;
    16         stretching: 'uniform',      // 扩大;
    17         repeat: false,              // 是否重复;
    18         volume: 100,                // 音量;
    19         controls: true,             // 底部控制栏;
    20         primary: "flash",           // 使用flash;
    21         tokenEncrypt: true,         // 采用token加密;
    22         ak: '86dc62e1dbd4455080ab1cfc5e587b17', // AccessKey;
    23     });
    24     
    25     // 视频播放前的事件;
    26     player.on('beforePlay', function (e) {
    27         if (!/m3u8/.test(e.file)) {
    28             return;
    29         }
    30         xfzajax.get({
    31             'url': '/course/course_token/',
    32             'data': {
    33                 'video': video_url
    34             },
    35             'success': function (result) {
    36                 if (result['code'] === 200) {
    37                     var token = result['data']['token'];
    38                     // 将‘tokon’设置入‘player’中,使播放器获取视频密码;
    39                     player.setToken(e.file, token);
    40                 } else {
    41                     alert('token错误!')
    42                 }
    43             },
    44             'fail': function (error) {
    45                 console.log(error)
    46             }
    47         })
    48     })
    49 };
    50 
    51 CourseDetail.prototype.run = function () {
    52     this.initPlayer();
    53 };
    54 
    55 $(function () {
    56     var course = new CourseDetail();
    57     course.run()
    58 });
    View Code

     

 

三、购买视频及播放;

 

1、使用 PaysApi 

  1. 文档的使用及说明:https://www.paysapi.com/docindex
  2. 发起付款接口的说明文档:https://www.paysapi.com/docpay

 

2、代

  1. Models及HTML模板
     1 # 支付页面模板;
     2 class CourseOrder(models.Model):
     3     uid = ShortUUIDField(primary_key=True)
     4     course = models.ForeignKey("Course",on_delete=models.DO_NOTHING)
     5     buyer = models.ForeignKey("xfzauth.User",on_delete=models.DO_NOTHING)
     6     amount = models.FloatField(default=0)
     7     pub_time = models.DateTimeField(auto_now_add=True)
     8     # 支付渠道:1:代表支付宝支付;2:代表微信支付;
     9     istype = models.SmallIntegerField(default=1)
    10     # 支付状态:1:代表未支付;2:代表支付成功;
    11     status = models.SmallIntegerField(default=1)
    View Code
     1 <!-- 部分相关HTML模板 -->
     2 <form action="https://pay.bbbapi.com/" method="post" id="pay-form">
     3     <input type="hidden" name="uid" value="49dc532695baa99e16e01bc0">
     4     <input type="hidden" name="price" value="{{ course.price }}">
     5     <input type="hidden" name="notify_url" value="{{ notify_url }}">
     6     <input type="hidden" name="return_url" value="{{ return_url }}">
     7     <input type="hidden" name="orderid" value="{{ order.pk }}">
     8     <input type="hidden" name="orderuid" value="{{ request.user.pk }}">
     9     <input type="hidden" name="goodsname" value="{{ course.title }}">
    10     <input type="hidden" name="key" value="">
    11     <!-- 微信与支付宝支付 -->
    12     <div class="pay-way">
    13         <label for="istype-wx" class="label">
    14             <input id="istype-wx" type="radio" name="istype" value="2">
    15             <span class="wx-btn fk-btn">
    16             <img src="http://nos.netease.com/test-edu-image/1BD9F69D6760CE1508D2269864AA54F8.png" alt="">
    17         </span>
    18         </label>
    19         <label for="istype-zfb" class="label">
    20             <input id="istype-zfb" type="radio" name="istype" value="1" checked>
    21             <span class="zfb-btn fk-btn"></span>
    22         </label>
    23         <div style="clear: both;"></div>
    24     </div>
    25     <div class="submit-group">
    26         <input type="submit" value="去支付" id="submit-btn" class="submit-btn">
    27     </div>
    28 </form>
    View Code

     

  2. 获取“key”值
     1 from utils import restful
     2 from apps.xfzauth.decorators import xfz_login_required
     3 from hashlib import md5
     4 
     5 # 获取“key”;用户登录的情况下;
     6 @xfz_login_required
     7 def course_order_key(request):
     8     goodsname = request.POST.get("goodsname")       # 商品名称;
     9     istype = request.POST.get("istype")             # 支付渠道;
    10     notify_url = request.POST.get("notify_url")     # 通知回调网址;
    11     orderid = request.POST.get("orderid")           # 商户自定义订单号;
    12     orderuid = str(request.user.pk)                 # 商户自定义客户号;
    13     price = request.POST.get("price")               # 价格;
    14     return_url = request.POST.get("return_url")     # 跳转网址;
    15 
    16     # 在官网个人账户设置中的“API接口信息”中获取“token”与“uid”的值:
    17     token = 'e6110f92abcb11040ba153967847b7a6'
    18     uid = '49dc532695baa99e16e01bc0'
    19 
    20     # 秘钥“key”的拼接顺序:goodsname + istype + notify_url + orderid + orderuid + price + return_url + token + uid
    21     key = md5((goodsname + istype + notify_url + orderid + orderuid + price + return_url + token + uid).encode(
    22         "utf-8")).hexdigest()
    23     return restful.result(data={"key": key})
    View Code

     

  3. 购买课程
     1 # 购买课程;
     2 @xfz_login_required
     3 def course_order(request, course_id):
     4     course = Course.objects.get(pk=course_id)
     5     order = CourseOrder.objects.create(course=course, buyer=request.user, status=1, amount=course.price)
     6     context = {
     7         'course': course,
     8         'order': order,
     9         # 跳转链接:/course/notify_url/;
    10         'notify_url': request.build_absolute_uri(reverse('course:notify_view')),
    11         'return_url': request.build_absolute_uri(reverse('course:course_detail', kwargs={"course_id": course.pk}))
    12     }
    13     return render(request, 'course/course_order.html', context=context)
    14 
    15 # 使用订单ID更新支付状态;(关闭CSRF保护)
    16 @csrf_exempt
    17 def notify_view(request):
    18     orderid = request.POST.get('orderid')
    19     CourseOrder.objects.filter(pk=orderid).update(status=2)
    20     return restful.ok()
    View Code

     

  4. 前端“js”文件
     1 function CourseOrder() {
     2 
     3 }
     4 
     5 CourseOrder.prototype.run = function () {
     6     this.OrderEvent();
     7 };
     8 
     9 // 订购事件;(发起付款接口时需处理的数据)
    10 CourseOrder.prototype.OrderEvent = (function () {
    11     var submitBtn = $("#submit-btn");
    12     submitBtn.click(function (event) {
    13         event.preventDefault();
    14         var goodsname = $("input[name='goodsname']").val();
    15         var istype = $("input[name='istype']:checked").val();
    16         var notify_url = $("input[name='notify_url']").val();
    17         var orderid = $("input[name='orderid']").val();
    18         var price = $("input[name='price']").val();
    19         var return_url = $("input[name='return_url']").val();
    20         xfzajax.post({
    21             'url': '/course/course_order_key/',
    22             'data': {
    23                 'goodsname': goodsname,
    24                 'istype': istype,
    25                 'notify_url': notify_url,
    26                 'orderid': orderid,
    27                 'price': price,
    28                 'return_url': return_url
    29             },
    30             'success': function (result) {
    31                 if(result['code'] === 200){
    32                     var key = result['data']['key'];
    33                     var keyInput = $("input[name='key']");
    34                     keyInput.val(key);
    35                     $("#pay-form").submit();
    36                 }
    37             }
    38         });
    39     });
    40 });
    41 
    42 $(function () {
    43     var order = new CourseOrder();
    44     order.run();
    45 });
    View Code

     

posted @ 2019-06-22 18:34  F·灬小人物  阅读(758)  评论(0编辑  收藏  举报