在线视频采用,视频上传到百度云VOD进行存储,然后在html中调用接口进行播放,具体见帮助文档
在线视频播放处理和在线文档下载处理差不多,就多一个调用百度云VOD的处理接口。
一、分析
1. 数据库设计

-
Teacher表
字段名 |
字段类型 |
关联表 |
关联类型 |
关联操作 |
id |
int |
|
|
|
name |
char |
|
|
|
position |
char |
|
|
|
brief |
text |
|
|
|
saying |
char |
|
|
|
avatar |
url |
|
|
|
create_time |
datatime |
|
|
|
update_time |
datatime |
|
|
|
is_delete |
boolean |
|
|
|
-
CourseCategory表
字段名 |
字段类型 |
关联表 |
关联类型 |
关联操作 |
id |
int |
|
|
|
name |
char |
|
|
|
create_time |
datatime |
|
|
|
update_time |
datatime |
|
|
|
is_delete |
boolean |
|
|
|
-
Course表
字段名 |
字段类型 |
关联表 |
关联类型 |
关联操作 |
id |
int |
|
|
|
name |
char |
|
|
|
time |
char |
|
|
|
brief |
text |
|
|
|
outline |
char |
|
|
|
clicks |
integer |
|
|
|
cover_url |
url |
|
|
|
video_url |
url |
|
|
|
teacher |
ForeignKey |
Teacher |
ManyToOne |
SET_NULL |
category |
ForeignKey |
CourseCategory |
ManyToOne |
SET_NULL |
create_time |
datatime |
|
|
|
update_time |
datatime |
|
|
|
is_delete |
boolean |
|
|
|
2. 视频列表显示
- 业务流程
- 从数据库中获取视频信息返回给前端
- 填充html
- 待写:根据类型分类(功能和文章分类实现一样)
- 请求方式:GET
- 请求地址:/course/index/
- 请求参数:无
3. 视频播放
-
业务流程
- 接收前端传来的视频id
- 在数据库中获取数据
- 跳转到视频播放页面
- 调用百度云VOD播放接口
-
请求方式:GET
-
请求地址:/course/<int:course_id>/
-
请求参数:
参数 |
类型 |
前端是否必须传 |
描述 |
course_id |
int |
是 |
路径参数 |
二、视频播放功能
1. 数据库
course/models.py
from django.db import models
from utils.models.models import BaseModel
class Teacher(BaseModel):
"""
create teacher model
field:
姓名 name CharField
职衔 position CharField
简介 brief TextField
名言 saying CharField
头像 avatar URLField
"""
name = models.CharField(max_length=20, verbose_name="姓名", help_text="姓名")
position = models.CharField(max_length=30, verbose_name="职位", help_text="职位")
brief = models.TextField(verbose_name="简介", help_text="简介")
saying = models.CharField(max_length=150, verbose_name="个性签名", help_text="个性签名")
avatar = models.URLField(default="", verbose_name="姓名", help_text="姓名")
class Meta:
db_table = "tb_teacher"
verbose_name = "讲师"
verbose_name_plural = verbose_name
def __str__(self):
return "姓名:{}".format(self.name)
class CourseCategory(BaseModel):
"""
create course category model
field:
课程名 name CharField
"""
name = models.CharField(max_length=30, verbose_name="课程分类名", help_text="课程分类名")
class Meta:
db_table = "tb_coursecategory"
verbose_name = "课程分类"
verbose_name_plural = verbose_name
def __str__(self):
return "课程分类:{}".format(self.name)
class Course(BaseModel):
"""
create course model
field:
名字 name CharField
封面url cover_url URLField
链接url video_url URLField
时长 time FloatField
简介 brief TextField
课程大纲 outline TextField
点击量 clicks IntegerField
讲师 teacher ManyToOne
类型 category ManyToOne
"""
name = models.CharField(max_length=150, verbose_name="课程名", help_text="课程名")
time = models.FloatField(default=0.0, verbose_name="时长", help_text="时长")
brief = models.TextField(verbose_name="简介", help_text="简介")
outline = models.TextField(verbose_name="大纲", help_text="大纲")
clicks = models.IntegerField(default=0, verbose_name="观看量", help_text="观看量")
cover_url = models.URLField(null=True, blank=True, verbose_name="封面url", help_text="封面url")
video_url = models.URLField(null=True, blank=True, verbose_name="视频url", help_text="视频url")
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 "课程:{}".format(self.name)
2. 视频列表显示
1. urls.py配置
course/urls.py
from django.urls import path
from course import views
app_name = "course"
urlpatterns = [
path("index/", views.CourseIndexView.as_view(), name="index"),
]
2. views.py逻辑处理
course/views.py
from django.views import View
from django.shortcuts import render
from course import models
class CourseIndexView(View):
"""
course index view
"""
def get(self, request):
# 获取课程列表中需要的数据:课程标题,讲师姓名,讲师职位
course_list = models.Course.objects.select_related("teacher").only("name", "teacher__name",
"teacher__position").filter(is_delete=False)
return render(request, 'course/course.html', locals())
3. html填充
course/course.html
<main id="course-container">
<div class="w1200">
<ul class="course-list">
{% for course in course_list %}
<li class="course-item">
<a href="{% url 'course:course_detail' course.id %}">
<img class="course-img" src="{{ course.cover_url }}"
alt="{{ course.category.name }}">
<div class="course-content">
<p class="course-info">{{ course.name }}</p>
<p class="course-author">{{ course.teacher.name }}({{ course.teacher.position }})</p>
<p class="course-price free">免费</p> {# 后面写成动态的 #}
</div>
</a>
</li>
{% endfor %}
</ul>
</div>
</main>
3. 视频播放
1. urls.py配置
course/urls.py
from django.urls import path
from course import views
app_name = "course"
urlpatterns = [
path("<int:course_id>/", views.CourseDetailView.as_view(), name="course_detail"),
]
2. views.py逻辑处理
course/views.py
from django.views import View
from django.http import Http404
from django.shortcuts import render
from course import models
class CourseDetailView(View):
"""
course detail view
"""
# 1. 从数据库中获取到需要的课程播放信息:课程名字,教师名字,教师头像,教师简介,教师名言,课程简介,课程大纲,视频url,视频封面url
def get(self, request, course_id):
course_detail = models.Course.objects.select_related("teacher").only("name", "brief", "outline", "video_url",
"cover_url","teacher__name","teacher__brief",
"teacher__avatar","teacher__saying").filter(
is_delete=False, id=course_id).first()
if course_detail:
return render(request,'course/course_detail.html', locals())
else:
raise Http404("课程不存在")
3. html填充
course/course_detail.html
<div class="course-video" id="course-video"> {# 百度VOD视频接口 #}
<span class="course-data" style="display: none;" data-video-url="{{ course_detail.video_url }}"
data-cover-url="{{ course_detail.cover_url }}">
</span>
</div>
<script src="https://cdn./jwplayer/latest/cyberplayer.js"></script> {# 百度VOD视频功能 #}
<script src="{% static 'js/course/BDVideoPlayer.js' %}"></script> {# 接口调用 #}
4. js逻辑处理
js/course/BDVideoPlayer.js
$(function () {
let $courseData = $(".course-data"); //百度云VOD API接口标签
let $videoUrl = $courseData.data('video-url'); //视频url
let $coverUrl = $courseData.data('cover-url'); //封面url
let player = cyberplayer('course-video').setup({
width: '100%',// 宽度百分比(父元素宽度要有),可以是固定宽度
height: 650, // 高度
file: $videoUrl, // 视频url
image: $coverUrl, // 封面url
autostart: false, //是否自动播放
stretching: "uniform", //拉伸设置
repeat: false, // 是否重复播放
volume: 100, //音量大小(0-100)
controls: true, //控制是否显示
ak: '自己的百度云VOD安全认真的AK',
})
});
|