在线视频

I. 功能需求分析

1>分析

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

2>功能

  • 视频展示页面
  • 视频播放详情

II. 模型设计

1>表字段分析

  • 老师表

    • 姓名
    • 职称
    • 简介
    • 头像
  • 课程分类表
    • 名称
  • 课程表
    • 课程名称
    • 封面
    • 视频地址
    • 时长
    • 简介
    • 大纲
    • 老师
    • 分类

2>模型定义

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

from django.db import modelsfrom utils.models import BaseModelclass 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_namedef __str__(self):return self.nameclass CourseCategory(BaseModel):name = models.CharField('课程分类名', max_length=100, help_text='课程分类名')class Meta:db_table = 'tb_course_category'verbose_name = '课程分类'verbose_name_plural = verbose_namedef __str__(self):return self.nameclass 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_namedef __str__(self):return self.title

DurationField表示时间间隔

只要创建模板就要生成迁移

III. 百度云VOD音视频点播

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

  1. 打开网址, 注册登陆, 点击立即购买

    如果是首次使用需要填写信息, 然后提交

    提交后点击此处

    切换到vod界面

    如果是没有认证则先认证再开通, 首次会送55元包, 这足以供我们使用

2>添加媒资

官方使用说明

3>导入测试数据

# 在mysql数据库中添加自己的测试数据
INSERT INTO `tb_teachers`
(create_time, update_time, is_delete, name, title,`profile`,photo)VALUES( '2019-08-28 14:26:05.000000', '2019-08-28 14:26:09.000000', '0', 'jax', '管理员', '本网站的主开发工程师', '/media/jax.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);

IIII. 视频展示列表

1>接口设计

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

    文档下载页面

2>后端代码

2.1>视图
# 在course/views.py文件下创建如下视图
from django.shortcuts import render, Http404
from django.views import Viewfrom . import modelsdef course_list(request):"""在线课程列表url:/course/"""# 1. 拿到所有视频数据courses = Course.objects.select_related('teacher').only('title', 'cover_url', 'teacher__title', 'teacher__name').filter(is_delete=False)# 用only的原因取到指定的字段, 而不是获取所有字段, 提升性能# 2. 前端渲染return render(request, 'course/course.html', context={'courses': courses})

2.2>路由

# 在course/urs.py中定义如下路由
from django.urls import pathfrom . import viewsapp_name = 'course'urlpatterns = [path('', views.course_list, name='index'),
]

3>前端代码

3.1>html
<!-- 创建模板templates/course/course.html -->
{% extends 'base/base.html' %}
{% load static %}
{% block title %}在线课程{% endblock %}
{% block link %}<link rel="stylesheet" href="{% static 'css/course/course.css' %}"><script>iMenuIndex = 1</script>
{% endblock %}
{% block main %}<!-- main start --><main id="course-container"><div class="w1200"><ul class="course-list">{% for course in courses %}<!-- course-item start --><li class="course-item"><a href="{% url 'course:course_detail' course.id %}"><img class="course-img" src="{{ course.cover_url }}"alt="{{ course.title }}"><div class="course-content"><p class="course-info">{{ course.title }}</p><p class="course-author">{{ course.teacher.name }} ({{ course.teacher.title }})</p><p class="course-price free">免费</p><p class="course-author">{{ course.profile }}</p></div></a></li><!-- course-item end -->{% endfor %}</ul></div></main><!-- main end -->
{% endblock %}

打开网站看一看页面的渲染,

样式不怎么好看, 来改一下css

3.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 =========  */

浏览器会自动缓存样式, 将下面的Disable cache禁用即可

修改样式之后的页面

V. 视频播放详情页面

视频播放详情页的设计思路与文章详情如出一辙

1>接口设计

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

    视频播放详情页面

2>后端代码

2.1>视图
# 在course/views.py文件下创建如下视图
class CourseDetailView(View):"""课程详情视图url:/course/<int:course_id>/"""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('此课程不存在')
2.2>路由
# 在course/urs.py中添加如下路由
path('<int:course_id>/', views.CourseDetailView.as_view(), name='course_detail')

3.前端代码

3.1>html
<!-- 创建模板templates/course/course_detail.html -->
{% extends 'base/base.html' %}
{% load static %}
{% block title %}课程详情{% endblock %}
{% block link %}<link rel="stylesheet" href="{% static 'css/course/course-detail.css' %}">
{% endblock %}
{% block main %}<!-- main start --><main id="main"><div class="w1200"><div class="course-contain"><div class="course-top-contain"><h4 class="course-title">{{ course.title }}</h4><div class="course-other clearfix"><!-- 分享方式 start --><div class="share"><i></i><span>分享</span><div class="share-list"><div class="bshare-custom icon-medium"><div class="bsPromo bsPromo2"></div><a title="分享到QQ空间" class="bshare-qzone"></a><a title="分享到新浪微博"class="bshare-sinaminiblog"></a><atitle="分享到QQ好友" class="bshare-qqim" href="javascript:void(0);"></a><atitle="分享到微信" class="bshare-weixin" href="javascript:void(0);"></a><atitle="更多平台" class="bshare-more bshare-more-icon more-style-addthis"></a><spanclass="BSHARE_COUNT bshare-share-count" style="float: none;">62.9K</span></div><script type="text/javascript" charset="utf-8"src="http://static.bshare.cn/b/buttonLite.js#style=-1&amp;uuid=&amp;pophcol=2&amp;lang=zh"></script><script type="text/javascript" charset="utf-8"src="http://static.bshare.cn/b/bshareC0.js"></script></div></div><!-- 分享方式 end --></div></div><!-- 视频窗口 start --><div class="course-video" id="course-video"><span class="course-data" style="display: none"data-video-url="{{ course.video_url }}"data-cover-url="{{ course.cover_url }}"></span></div><!-- 视频窗口 end --><div class="course-bottom-contain"><!-- 视频详情 start --><div class="course-detail-list"><div class="course-item clearfix"><h5 class="course-title">课程讲师</h5><div class="teacher-box clearfix"><img src="{{ course.teacher.photo }}" alt="{{ course.teacher.name }}"title="Which" class="teacher-avatar"><div class="teacher-info"><p class="teacher-name">{{ course.teacher.name }}</p><p class="teacher-identify">{{ course.teacher.title }}</p></div></div><div class="item-content">{{ course.teacher.profile }}</div></div><div class="course-item clearfix"><h5 class="course-title">课程简介</h5><div class="item-content">{{ course.profile }}</div></div><div class="course-item clearfix"><h5 class="course-title">课程大纲</h5><div class="item-content"><p>{{ course.outline }}</p></div></div></div><!-- 视频详情 end --><!-- 推荐课程 start --><div class="course-side"><h4 class="side-title">推荐课程</h4></div><!-- 推荐课程 end --></div></div></div></main><!-- main end -->
{% endblock %}
{% block script %}<!-- 这里引用的是百度云点播所依赖的js --><script type="text/javascript" src="https://cdn.bdstatic.com/jwplayer/latest/cyberplayer.js"></script><script src="{% static 'js/course/course_detail.js' %}"></script>
{% endblock %}
3.2>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.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;
}

项目源码:https://gitee.com/hao4875/newssite

[django项目] 如何在网站上实现在线视频功能?相关推荐

  1. 如何在KWSP网站上申请在线EPF帐户(i帐户)–第1部分

    很久以前,您必须访问KWSP柜台以检查您的雇员公积金(EPF)余额或打印您的年度EPF报表. 如今,马来西亚政府在在线发布KWSP服务(在线EPF帐户)方面做得很好. 借助在线EPF服务,您可以检查您 ...

  2. 如何在微网站上设置在线客服QQ

    很多营销型网站需要设置在线QQ客服,方便与来访网站的客户进行沟通,这样大大提高了网站客户的转化率,可以实时在线解决访客问题,那么如何在网站上设置在线的客服QQ呢,下面让我们来了解一下:方法/步骤1.  ...

  3. 动易swCMS6.5网站的模板在线编辑功能模块

    动易swCMS6.5网站的模板在线编辑功能模块 动易cms6.5网站的模板文件以文字内容方式保存在数据库中 其好处就是可以通过在线编辑方式修改模板文件, 而无需使用如DW网页制作工具来修改 模板内容读 ...

  4. 我使用Python和Django在自己的网站上建立了一个会员专区。 这是我学到的东西。

    I decided it was time to upgrade my personal website in order to allow visitors to buy and access my ...

  5. Django项目在Linux服务器上部署和躺过的坑

    引言 在各方的推荐下,领导让我在测试环境部署之前开发的测试数据预报平台.那么问题来了,既然要在服务器上部署, 就需要准备: 1.linux服务器配置 2.linux安装python环境搭建与配置 3. ...

  6. 怎么接受微信支付通知_如何在您的网站上接受在线支付

    怎么接受微信支付通知 Being able to accept internet payments from customers is essential for any online busines ...

  7. linux Centos系统下django项目在Nginx服务器上的部署

    Centos下Python2和3并存环境部署 第一部分: python环境部署 我们今天学习的内容是如何将Django项目部署到linux服务器上,我们部署的linux系统是centos7首先,我们先 ...

  8. 如何在自己的网站加入qq在线交谈功能

    如何在自己的网站加上 qq在线交谈,离线留言功能.即点击qq个性图标,可以打开客户机端的qq客户端.实现和业主的qq聊天对话框. 如: QQ在线状态官网: http://wp.qq.com/index ...

  9. 突破限制,这类网站的仅在线视频也能轻松能下载了!

    原来有写过一篇<IDM完全入门教程>,讲到了可以用IDM轻松下载很多XXX视频网站的在线视频 ▲点击右上角的IDM悬浮窗即可下载 但最近几个月,其实有不少视频网站都做了改版,不再能直接用 ...

最新文章

  1. poj1486(二分图必须边)
  2. 数据准备技巧及其对机器学习的重要性
  3. Nancy之结合TinyFox调试备忘
  4. anaconda在ubuntu中安装后没有_你的大数据平台中病毒了!!!记一次HDP安装后中dr.who病毒并修复的过程...
  5. android反编译的方法
  6. 在IDEA上使用maven构建WEB工程,出现Unable to compile class for JSP错误,页面500. ————解决方案
  7. 计算机组成原理实验箱使能开关,计算机组成原理微程序计数器实验报告
  8. C++morse code 摩尔斯电码算法(附完整源码)
  9. PowerDesigner pdm生成Access的方法
  10. 正则表达式快速入门,转载
  11. 赋能开发者,英特尔发布oneAPI 2022工具包
  12. 客户端通过网口启动可过去的ip_西安交通大学16年3月课程考试《网络组网技术综合训练》作业考核试题...
  13. angular.js入门基础(一)
  14. 谷歌黑科技:gVisor轻量级容器运行时沙箱
  15. [Flex]Flex编程注意之自动获取焦点、监听全局键盘事件
  16. VML编程之------background背景《VML极道教程》原著:沐缘华
  17. [ 成为架构师系列 ] 2. 深入理解 Cookie 与 Session ,Facade 设计模式, 分布式 Session...
  18. 16S扩增子数据提交GSA实操手册—发表文章前必备技能
  19. elementui Messagebox确认消息弹框中没有取消按钮
  20. 集合竞价和连续竞价03

热门文章

  1. 弘辽科技:淘口令下单会降权吗?能不能提升流量?
  2. 利用Selenium爬取煎蛋网妹纸图原来是这么简单!!!
  3. java源代码打包为jar且对于游戏可执行
  4. ingress controller学习记录
  5. 系统之家ghost Win10 64位专业版ISO镜像下载 2020.05
  6. GNU Radio 社区
  7. leetcode-561-Array Partition I
  8. Android 面试准备进行曲 (Handler源码/面试题)v1.3
  9. Oracle查询24小时制的时间格式
  10. 大白话版 UnityShader学习(1)-基础纹理研究(一)