django项目--在线播放

在线课堂

一、功能需求分析

1. 分析

在线直播,或点播设计到视频的存储,转码,加密,播放很多细节,个人单独开发不现实。本项目的在线课堂选择在线播放视频的形式。实际项目中一般选择云点播或者内嵌视频网站的方式进行。本项目选择是用百度云VOD点播来实现。

2. 功能

  • 视频展示页面

  • 视频播放详情

二、模型设计

1. 表字段分析

  • 老师表

    • 姓名

    • 职称

    • 简介

    • 头像

  • 课程分类表

    • 名称
  • 课程表

    • 课程名称

    • 封面

    • 视频地址

    • 时长

    • 简介

    • 大纲

    • 老师

    • 分类

2.模型定义

在course/models.py中定义如下模型

from django.db import models
​
from utils.models import BaseModel
​
​
class Teacher(BaseModel):
 name = models.CharField('讲师姓名', max_length=150, help_text='讲师姓名')
 title = models.CharField('职称', max_length=150, help_text='职称')
 profile = models.TextField('简介', help_text='简介')
 photo = models.URLField('头像url', default='', help_text='头像url')
​
 class Meta:
 db_table = 'tb_teachers'
 verbose_name = '讲师'
 verbose_name_plural = verbose_name
​
 def __str__(self):
 return self.name
​
​
class CourseCategory(BaseModel):
 name = models.CharField('课程分类名', max_length=100, help_text='课程分类名')
​
 class Meta:
 db_table = 'tb_course_category'
 verbose_name = '课程分类'
 verbose_name_plural = verbose_name
​
 def __str__(self):
 return self.name
​
​
class Course(BaseModel):
 title = models.CharField('课程名', max_length=150, help_text='课程名')
 cover_url = models.URLField('封面url', help_text='封面url')
 video_url = models.URLField('课程视频url', help_text='课程视频url')
 duration = models.DurationField('课程时长', help_text='课程时长')
 profile = models.TextField('课程简介', null=True, blank=True, help_text='课程简介')
 outline = models.TextField('课程大纲', null=True, blank=True, help_text='课程大纲')
 teacher = models.ForeignKey('Teacher', on_delete=models.SET_NULL, null=True, blank=True)
 category = models.ForeignKey('CourseCategory', on_delete=models.SET_NULL, null=True, blank=True)
​
 class Meta:
 db_table = 'tb_course'
 verbose_name = '课程'
 verbose_name_plural = verbose_name
​
 def __str__(self):
 return self.title

三、百度云VOD音视频点播

1. 开通百度VOD音频点播功能

  1. 注册后登陆首页,找到vod服务


开通即送55元包


2.添加媒资

官方使用说明

1563342650830.png
1563343001477.png
1563343108603.png

3.导入测试数据

# 在mysql数据库中添加自己的测试数据
INSERT INTO `tb_teachers`
(create_time, update_time, is_delete, name, title,`profile`,photo)
 VALUES
 ( '2019-07-17 14:26:05.000000', '2019-07-17 14:26:09.000000', '0', '心蓝', 'python高级讲师', 'python学院最帅的老师', '/media/xinlan.jpg');
​
# 导入课程分类数据
INSERT INTO `tb_course_category` VALUES ('1', '2019-07-17 14:34:33.000000', '2019-07-17 14:34:36.000000', '0', 'python基础');
INSERT INTO `tb_course_category` VALUES ('2', '2019-07-17 14:34:52.000000', '2019-07-17 14:34:55.000000', '0', 'python高级');
INSERT INTO `tb_course_category` VALUES ('3', '2019-07-17 14:35:20.000000', '2019-07-17 14:35:16.000000', '0', 'python框架');
​
# 导入课程数据
insert into tb_course (title, cover_url, video_url, duration, `profile`, outline, teacher_id, category_id, create_time, update_time, is_delete) values
('你的测试视频1名称', '你的测试视频缩略图URL', '你的测试视频URL', 212000000, '你的测试视频简介', '你的视频大纲', 1, 2, now(), now(), 0),
​
('你的测试视频2名称', '你的测试视频缩略图URL', '你的测试视频URL', '你的测试视频时长整数表示微秒', '你的测试视频简介', '你的视频大纲', 1, 2, now(), now(), 0);

四、视频展示列表

1.接口设计

  1. 接口说明:
类目 说明
请求方法 GET
url定义 /course/
参数格式 无参数
  1. 返回结果:

    文档下载页面

2.后端代码

  1. 视图
# 在course/views.py文件下创建如下视图
    from django.shortcuts import render, Http404
    from django.views import View
    ​
    from . import models
    ​
    ​
    def course_list(request):
     """
     在线课程列表
     url:/course/
     :param request:
     :return:
     """
     courses = models.Course.objects.only('title', 'cover_url', 'teacher__title', 'teacher__name').filter(
     is_delete=False).select_related(
     'teacher')
     return render(request, 'course/course.html', context={'courses': courses})
  1. 路由
# 在course/urs.py中定义如下路由
    from django.urls import path
    ​
    from . import views
    ​
    app_name = 'course'
    ​
    urlpatterns = [
     path('', views.course_list, name='index'),
    ]

3.前端代码

  1. html

    {% extends 'base/base.html' %}
    {% load static %}
    {% block title %}在线课堂{% endblock %}
    {% block link %}
     
    {% endblock %}
    {% block main_start %}
     
{% endblock %}
2.  css
        /* ==== 修改course.css如下 ====*/
        /* ========== top-wrap start =========  */
        #top-wrap {
         background: #fff;
         line-height: 60px;
         box-shadow: 0 4px 4px rgba(0,0,0,.1);
        }
        #top-wrap .top-title {
         float: left;
         font-size: 22px;
         margin-right: 140px;
        ​
        }
        #top-wrap .top-nav {
         display: flex;
         justify-content: space-between;
         width: 400px;
         color: #878787;
         font-size: 18px;
        }
        #top-wrap .top-nav li.active {
         color: #212121;
        }
        #top-wrap .top-nav  li:hover {
         text-shadow: 1px 1px 2px #212121;
        }
        /* ========== top-wrap end =========  */
        /* ========== course-container  start =========  */
        #course-container {
         flex: 1;
        }
        #course-container .course-list {
         display: flex;
         flex-flow: row wrap;
         margin-bottom: 20px;
        }
        #course-container .course-list .course-item {
         margin: 20px;
         width: 260px;
         height: 260px;
         background: #fff;
         position: relative;
         /* float: left; */
        }
        .course-list .course-item .course-img {
         width: 100%;
         height: 61.8%;
        }
        .course-list .course-item .course-content {
         padding: 0 20px;
         height: 150px;
         box-sizing: border-box;
        }
        .course-list .course-item:hover {
         box-shadow: 0 4px 8px rgba(0,0,0,.1);
        }
        .course-item .course-content .course-info {
         font-size: 16px;
         line-height: 1.5;
         max-height: 50px;
         overflow: hidden;
        }
        .course-item .course-content .course-author{
         color: #848383;
         font-size: 14px;
         line-height: 36px;
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
        }
        .course-item .course-content .course-price {
         position: absolute;
         bottom: 10px;
         right: 21px;
         font-size: 16px;
         line-height: 30px;
         color: #6fa026;
        ​
        }
        .course-item .course-content .course-price span{
         font-size: 14px;
        }
        .course-item .course-content .course-price.free {
         color: green;
         float: right;
        }
        /* ========== course-container  end =========  */
        ​

五、视频播放详情页面

1.接口设计

  1. 接口说明:
类目 说明
请求方法 GET
url定义 /course//
参数格式 路径参数
  1. 参数说明:
参数名 类型 是否必须 描述
course_id 整数 视频id
  1. 返回结果:

    视频播放详情页面

2. 后端代码

  1. 视图
    # 在course/views.py文件下创建如下视图
    class CourseDetailView(View):
     """
     课程详情视图
     url:/course//
     """
    ​
     def get(self, request, course_id):
     course = models.Course.objects.only('title', 'cover_url', 'video_url', 'profile', 'outline', 'teacher__name',
     'teacher__photo', 'teacher__title', 'teacher__profile').select_related(
     'teacher').filter(is_delete=False, id=course_id).first()
    ​
     if course:
    ​
     return render(request, 'course/course_detail.html', context={'course': course})
     else:
     return Http404('此课程不存在')
    
  1. 路由
    # 在course/urs.py中添加如下路由
    path('/', views.CourseDetailView.as_view(), name='course_detail')

3.前端代码

  1. html
    
{% extends 'base/base.html' %}
{% load static %}
{% block title %}视频详情-{{ course.title }}{% endblock %}
{% block link %}
    
{% endblock %}
{% block main_start %}
    

{{ course.title }}

免费
{{ course.teacher.name }}
{{ course.teacher.name }}

{{ course.teacher.name }}

{{ course.teacher.title }}

{{ course.teacher.profile }}
课程简介
{{ course.profile }}
课程大纲

{{ course.outline }}

帮助中心

1. 购买后的课程在线可反复观看学习,视频有效期以具体课程信息为准。

2. 课程暂不支持下载观看,均为在线观看视频。

3. 课程一经购买,不可转让、不可退款;仅限购买账号观看。

4. 如有问题请咨询客服: 400-1567-315

关于潭州课堂
湖南潭州教育网络科技有限公司拥有千余人的优秀师资团队,是一家师资丰富、教育产品类别众多的在线培训公司。公司总部座落于美丽的星城长沙,2015年9月正式入驻芯城科技园目前拥有近两万平米办公面积。 在潭州学习的学员已突破1000万人次在线学员覆盖全球,包括中国、加拿大、日本、美国、韩国等诸多国家。

推荐课程

{% endblock %} {% block script %} {% endblock %} ​
  1. js
    // 创建js文件 static/js/course/course.js
    $(function () {
      let $course_data = $(".course-data");
      let sVideoUrl = $course_data.data('video-url');
      let sCoverUrl = $course_data.data('cover-url');

      let player = cyberplayer("course-video").setup({
        width: '100%',
        height: 650,
        file: sVideoUrl,
        image: sCoverUrl,
        autostart: false,
        stretching: "uniform",
        repeat: false,
        volume: 100,
        controls: true,
        ak: '你自己的ak'
      });

    });
    
3.  css
        /*== 修改course_detail.css 代码如下===*/
        #main {
            flex: 1;
        }

        .course-contain {
            width: 100%;
        }

        .course-contain .course-top-contain, #course-video{
            width: 100%;
            background: #fff;
            /*padding:0 20px;*/
        }
        .course-top-contain .course-title {
            font-size: 30px;
            line-height: 2.5;
            margin: 0 20px;
        }

        .course-top-contain .course-other {
            line-height: 3.5;
            margin: 0 20px;
        }
        .course-other  .share {
            float: left;
        }
        .share span {
             margin-right: 8px;
        }
        .share i {
                display: inline-block;
            vertical-align: middle;
            width: 14px;
            height: 14px;
            margin-right: 5px;
            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABM0lEQVQokY2Sr0tEQRSFv/dYsIiwYVFkg/deERZBbEaDiJpEBP8Ck6jYxCBuMlgNikGTIIjBIIhbBDGISUSwzIwW4wbtrmHnwWNxf5w099z7MXeYk1SrVbpJ1IrANjAKnAXvbgpdqaYegPF4Xha1hbSH2yQHZVrpCIpaCdj9p/WVxoFhUdsQtcVY94vaHhCAErAD/EboGTgoiNpYLAYiVAMmgU9gLnj3GP0ToAy8Bu8aBWArg6JmgbXg3VF+t+BdHahndQo0WvZvAFed3p6Bh8B3zvsB7kRtKj8oamOiNiFqCUAavHsHKsAmMAMMAtfAvahdiFpZ1NaBN+AFeBK1YtIuOaI2AhwD00AC9OXa+23/MXj3EbybB1ZbIIChrskJ3p0DtRb7stesLtEMQQU4Dd7d/gHKLE8gSrHhJgAAAABJRU5ErkJggg==);
        }
        .share .share-list{
            display: none;
            /*width: 130px;*/
            position: relative;
            background: #fff;
            text-align: center;
            line-height: 45px;
            left: 8px;
            /*box-shadow: 0 1px 2px #ccc;*/
            /*border: 1px solid #ddd;*/
            border-radius: 5px;
            z-index: 1;
        }
        .share:hover .share-list{
            display: inline-block;
        }
        .share-list:after{
            content: "";
            border: 12px solid transparent;
            border-right-color: #eee;
            position: absolute;
            top: 0px;
            left: -25px;
        }
        .share-list a{
            cursor: pointer;
        }
        .share-list a img{
            vertical-align: middle;
        }
        .course-other .buy-list {
            float: right;
        }

        .price {
            color: #f76363;
            float: right;
            margin-right: 20px;
            line-height: 40px;
            font-size: 20px;
        }

        .buy-btn {
            background-color: #ff8d3f;
            border: none;
            width: 120px;
            text-align: center;
            line-height: 40px;
            color: #fff;
            border-radius: 5px;
            font-size: 16px;
            float: right;
        }

        .course-video {
            border-top: 1px solid #ddd;
            height: 400px;
        }

        .course-bottom-contain {
            width: 100%;
            margin-top: 30px;
        }

        .curse-bottom-contain {
            margin-top: 30px;
            width: 100%;
        }

        .course-detail-list {
            width: 800px;
            float: left;
        }

        .course-detail-list .course-item {
            margin-bottom: 20px;
            background-color: #fff;
            padding: 20px;
        }

        .course-item .course-title{
            border-left: 6px solid #5b86db;
            padding: 0 10px;
            color: #202020;
            font-size: 18px;
        }

        .course-item .teacher-box {
            margin-top: 20px;
        }

        .teacher-box  .teacher-avatar {
            width: 62px;
            height: 62px;
            border-radius: 50%;
            float: left;
        }

        .teacher-box .teacher-info {
            float: left;
            margin-left: 10px;
            position: relative;
            font-size: 16px;
            color: #696969;
            height: 62px;
            width: 90%;
        }

        .teacher-name {
            position: absolute;
            left: 0;
            top: 8px;
        }
        .teacher-identify {
            position: absolute;
            bottom: 8px;
            left: 0;
        }

        .item-content {
            font-size: 14px;
            color: #888;
            line-height: 2em;
            margin-top: 20px;
        }

        .item-course-title {
            font-size: 18px;
            color: #202020;
            float: left;
            line-height: 40px;
        }

        .item-buy-list {
            float: right;
            margin-top: 0;
        }

        .course-side {
            float: right;
            width: 360px;
            background-color: #fff;
            padding: 20px;
            padding-bottom: 0;
            box-sizing: border-box;
        }
        .course-side  .side-title {
            font-size: 18px;
            line-height: 2.4;
        }

       

你可能感兴趣的:(django项目--在线播放)