今日重点

  1. 内容管理前后的联调
  2. 前端node.js安装 下载cnpm淘宝工具 下载node.js的前端依赖(cnpm install) npm run serve (后端微服务必须处于运行状态)
  3. 下载失败 将前端工程下mode_modules文件夹删除
  4. 新增课程计划:
  5. 保存后报错size index (原因:保存后立马会发送另外一个请求 ,teachplan其中需要判断是否能拿到0索引位置的数据 如果没有new新的)
  6. 删除成功后前端仍然显示 该课程(原因:后端删除为逻辑删除,而查所有的语句中并没有加入判断删除字段的条件! 添加判断删除状态)
  7. 媒资业务说明(核心:上传 审核 绑定)
  8. 1.媒资指内容生产过程中大量的音视频 图片 文档 等多媒体业务数据
  9. 2.媒资管理指用计算机技术 来解决多媒体媒资数据的管理!
  10. 3.本项目作用一个大型在线平台 媒资管理主要对点播 直播视频课程以及课程相关的多媒体资料进行管理!
  11. 业务流程:
  12. 上传媒资信息管理:包括上传 ,结构内媒资信息crud
  13. 运营审核媒资: 包括媒资检索 媒资预览 还有审核
  14. 课程计划绑定媒资 : 包括已审核媒资的检索 课程计划绑定媒资文件
  15. 阿里云视频点播服务
  16. 1.快速实现产品 快速交付产品 不必重头开始研发
  17. 2.减少技术投入 包括时间 人力
  18. 3.直接使用成熟的技术方案,避免技术风险
  19. 阿里云视频点播服务功能完善 SDK便于使用,API丰富 并与阿里云生态完美集成,因此我们项目选择使用它!
  20. 阿里云视频媒资提供99.999999999(11个9)% 的数据可靠性!
  21. 阿里云SDK视频上传:
  22. 流程: 获取上传凭证和地址 SDK获取上传凭证和地址 返回凭证和地址给前端 前端使用凭证和地址直接上传视频文件
  23. 播放流程: 获取视频URL SDK获取视频地址 返回地址给前端 前端拿着地址直接播放
  24. 视频凭证有效时间:3000秒
  25. 视频播放地址有效时间:3600秒
  26. 上传视频和获得视频播放地址的简略流程
  27. 确保文件上传安全性:
  28. 凭证+有效时间
  29. 断点续传上传文:
  30. 将大文件进行分片 编号 通过http协议进行分片上传 分块文件合并上传完!
  31. 断点续传: 文件上传时间短 文件上传提速(上传失败后,只需要继续上传未成功的部分即可,不需要重头再继续一遍)
  32. 核心原理是利用HTTP请求中的俩个字段: 客户端请求头中的Range,和服务端响应头的Content-Range 最后根据length 判断是否上传完整!
  33. tey catch: 代码中使用网络连接 使用第三方接口 可能有不稳定因素导致报错!
  34. 如果当前代码调用远端第三方代码 要使用cry cacth
  35. 错误信息不能打印精确到栈方法调用的错误信息!
  36. 抛出异常时要使用return !
  37. catch中
  38. e.prinStackTrace();
  39. 错误记录到日志中,日志文件再本地存储,操作时会涉及到IO操作,如果操作失败了会导致大批量错误日志打印容易引起服务宕机!
  40. 生产环境下 切勿不能使用这样的错误信息记录! 推荐使用log.error(“错误信息!”)
  41. 如果catch中使用了自己定义的异常处理器 需要 return null,因为统系编译器不知道你处理器做了什么!

学习目标


1了解课程资料的种类
2理解学成在线对课程资料存储方式
3理解媒资管理业务流程
4能够配置阿里视频点播服务
5能够使用阿里视频点播服务对服务进行管理
6能够根据文档定媒资文件上传接口
7能够完成媒资文件上传功能实现
8能够根据文档定义媒资信息保存接口
9能够完成保存媒资信息功能实现
10能够根据文档定义媒资信息查询接口
11能够完成查询媒资信息功能实现

1.媒资管理需求概述


对于在线教育平台,一定会有大量的媒资信息(视频、讲义、代码等)。对于这些有一般有教学机构上传媒资信息,再由学成在线进行通过管理。

1.1 媒资管理概述


1.媒资是什么 ?
媒资是指内容生产过程中产生的大量的音视频、图片、文档等多媒体业务数据。
2. 媒资管理是什么 ?
媒资管理是结合计算机存储、网络、数据库、多媒体等多项技术,主要解决多媒体数据资料的存储、检索管理、资料查询发布等问题。
3. 本项目的媒资管理系统定位是什么?
本项目作为一个大型的在线教育平台,其媒资管理主要对点播、直播视频课程以及课程相关的多媒体资料进行管理。

1.2 业务介绍


教育机构通过媒资管理可以对媒资文件进行上传、检索、删除等操作;平台运营通过媒资管理对媒资文件进行预览审核;最终,教育机构把审核通过的媒资文件绑定至课程计划,形成视频课程、课程资料等业务主体。

Day06-第三章-媒资管理-媒资信息管理 - 图1

需求列表如下:
1、上传和媒资信息管理:包括上传、机构内媒资信息 CRUD。
2、运营审核媒资:包括媒资检索、媒资预览、审核。
3、课程计划绑定媒资:包括已审核媒资的检索、课程计划绑定媒资文件。

1.3 业务流程

1.3.1 上传和媒资信息管理
1.教育机构用户在门户管理界面中的媒资管理链接进入媒资管理界面。
进入媒资管理

Day06-第三章-媒资管理-媒资信息管理 - 图2

媒资管理列表

Day06-第三章-媒资管理-媒资信息管理 - 图3

2.教育机构用户在”媒资管理”页面中点击”上传媒资文件”按钮,打开上传媒资文件页面。
上传媒资按钮

Day06-第三章-媒资管理-媒资信息管理 - 图4

上传媒资对话框

Day06-第三章-媒资管理-媒资信息管理 - 图5

3.选择要上传的文件,自动执行文件上传。
开始上传媒资文件

Day06-第三章-媒资管理-媒资信息管理 - 图6

4.选择要上传的文件,自动执行文件上传。
5.用户进入”媒资管理”页面中,默认执行无参数分页查询,展示机构内媒资信息列表,可通过输入查询参数进行条件检索。
媒资信息检索

Day06-第三章-媒资管理-媒资信息管理 - 图7

7.用户可点击媒资列表中的预览视频,可以对视频媒资信息进行在线预览功能

Day06-第三章-媒资管理-媒资信息管理 - 图8

Day06-第三章-媒资管理-媒资信息管理 - 图9

7.用户可点击媒资分页列表某一行数据后的”删除“按钮,执行删除媒资信息。
删除媒资信息

Day06-第三章-媒资管理-媒资信息管理 - 图10

Day06-第三章-媒资管理-媒资信息管理 - 图11

1.3.2 运营审核媒资


1.运营用户登入运营平台并进入媒资管理页面,查找待审核媒资
运营商媒资管理列表

Day06-第三章-媒资管理-媒资信息管理 - 图12

2.点击列表中媒资名称链接,可预览该媒资,若是视频,则播放视频。
运营商预览资源

Day06-第三章-媒资管理-媒资信息管理 - 图13

Day06-第三章-媒资管理-媒资信息管理 - 图14

3.点击列表中某媒资后的”审核” 按钮,既完成媒资的审批过程。
审核操作

Day06-第三章-媒资管理-媒资信息管理 - 图15

审批结果操作

Day06-第三章-媒资管理-媒资信息管理 - 图16

1.3.3 课程计划绑定媒资


1.教育机构用户进入课程管理页面并编辑某一个课程,在”课程大纲”标签页的某一小节后可点击”添加视频“。
课程计划绑定媒资信息

Day06-第三章-媒资管理-媒资信息管理 - 图17

2.弹出添加视频对话框,可通过视频关键字搜索已审核通过的视频媒资。
填写需要关联审核通过的视频

Day06-第三章-媒资管理-媒资信息管理 - 图18

3.选择视频媒资,点击提交按钮,完成课程计划绑定媒资流程。
关联视频

Day06-第三章-媒资管理-媒资信息管理 - 图19

上图解释:
注释①:填写审核通过的视频关键字
注释②:选择关联出的视频名称
注释③:选择好后,点击提交完成视频关联
关联后的课程计划

Day06-第三章-媒资管理-媒资信息管理 - 图20

4.学习中心对课程计划查询
通过内容管理对课程发布后,学员就可以通过学习中心对发布后的课程进行学习,课程学习主要是以课程章节来学习课程。而课程章节就为课程下的课程计划信息。在课程学习页面中,会将课程计划以课程章节的形式进行展示。
学习中心的课程计划

Day06-第三章-媒资管理-媒资信息管理 - 图21

1.4 媒资管理数据模型


学成在线整个数据结构体系是不同的微服务操作不同的数据库中的内容,而媒资管理管理在 MySQL 数据库里单独操作 xc_media 数据库,如下图:

Day06-第三章-媒资管理-媒资信息管理 - 图22

针对内容管理的业务需求,xc_media 数据库中的表主要包含下面内容:
媒资管理数据模型(表结构)

Day06-第三章-媒资管理-媒资信息管理 - 图23

PS:后面功能实现时,设计到哪个表,我们在对表哪个表再详讲。

2. 阿里云视频点播服务


视频点播功能对于在线教育类型项目必不可少,视频的上传、存储、播放、管理等都是需要解决的问题。因此在这里我们需要学习一个应用技术,阿里云视频点播服务
流媒体服务:
1.对于流媒体的技术不了解
2.搭建流媒体服务成本非常高
中小型公司不会自己去搭建流媒体服务。
企业通常直接使用云服务,而不自行开发,原因在于:(背)
●快速实现产品,快速交付产品,不必重头开始研发
●减少技术投入,包括时间、人力
●直接使用成熟的技术方案,避免技术风险
为什么使用阿里云视频点播服务?(背)
经考量,阿里云视频点播服务功能完善、SDK便于使用、API丰富,并与阿里云生态完美集成,因此我们项目选择使用它。

2.1 产品功能概述


阿里云视频点播(ApsaraVideo for VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速、视频播放于一体的一站式音视频点播解决方案。
VoD 为 Video on demand(视频点播) 简写形式。
视频服务

Day06-第三章-媒资管理-媒资信息管理 - 图24

其中开通视频点播基础配置属于必要环节,我们着重关注媒资上传、存储与访问以及计费方式,其他仅做了解。
官网地址:https://www.aliyun.com/product/vod

2.1.1 媒资上传


阿里云视频点播支持多端上传、并发上传、断点续传,满足不同场景下的上传需求,同时支持短视频SDK直接上传及直播录制转点播的一体化方案。
●上传方式 提供上传SDK,支持Web端(JavaScript)、移动端(Android,iOS)、服务端(JAVA),以及上传OpenAPI,也可以通过控制台和PC客户端工具上传,并支持直播录制转点播
●支持类型

| 类型

| 格式

| | —- | —- | | 视频

| 3gp, asf, avi, dat, dv, flv, f4v, gif, m2t, m3u8, m4v, mj2, mjpeg, mkv, mov, mp4, mpe, mpg, mpeg, mts, ogg, qt, rm, rmvb, swf, ts, vob, wmv, webm

| | 音频

| aac, ac3, acm, amr, ape, caf, flac, m4a, mp3, ra, wav, wma

| | 图片

| png,jpg,jpeg

|

2.1.2 媒资存储管理


阿里云视频点播提供集上传、存储、媒资管理于一体的媒体管理方案,可以方便、灵活的管理海量视音频素材。
●媒资存储 数据多重冗余备份,提供异地容灾和资源隔离,提供 99.999999999(11个9)% 的数据可靠性,您可以在任何应用、任何时间、任何地点存储和访问您的数据。
●媒资管理支持通过控制台或 API 对媒资进行管理。
○列表式视频管理,在线预览视频
○媒资信息编辑:标题、描述、封面设置等,支持自定义媒资元数据管理
○媒资多级分类、标签
○媒体名称模糊搜索及媒资ID精准搜索
○文件管理,支持查看视频地址
○视频信息CSV导出,包括视频的ID、名称、视频地址等

2.1.3 计费方式


1.按量收费
阿里云视频点播VOD服务费用的各项组成部分,包括:媒资管理费用、媒体处理费用、加速服务费用和增值服务费用。
费用组成

Day06-第三章-媒资管理-媒资信息管理 - 图25

  1. 视频点播VOD服务默认的计费方式分为 **按量计费** 。当您开通VOD服务后,即默认为按量付费;另外针对常用付费服务功能支持 **预付费资源包** 的计费方式。<br />**2.资源包购买**<br />可使用资源包的方式进行购买:<br />●视频点播流量包(针对视频加速)

| 加速流量

| 价格

| | —- | —- | | 加速流量-100GB

| 20

| | 加速流量-500GB

| 95

| | 加速流量-1TB

| 180

|

●视频点播存储包(针对媒资管理)

| 资源包规格

| 价格

| | —- | —- | | 100GB

| 99

| | 500GB

| 486

| | 1TB

| 999

|

●视频点播转码时长包(针对媒体处理)

| 资源包规格

| 价格

| | —- | —- | | 5千分钟

| 87

| | 2万分钟

| 304

| | 10万分钟

| 1302

|

资费详情:https://www.aliyun.com/price/product?spm=5176.8413026.702518.btn4.532911cfWqwLhX#/vod/detail
PS:对于我们现阶段的开发来说,各个计费标准都很少。

2.2 阿里云视频入门

Plain Text复制代码

1

在使用阿里云的视频点播服务前,我们需要在阿里云进行注册登录,并开通阿里云服务。开通过后需要在阿里云平台的管理界面中进行相应的配置便可使用阿里云点播服务。

2.2.1 开通步骤


1.访问阿里云官网,在右上角单击登录或注册。
进入阿里云首页后,如果没有阿里云的账户需要先进行注册,才可以进行登录。由于注册较为简单,课程和讲义不在进行体现(注册可以使用多种方式,如淘宝账号、支付宝账号、微博账号等…)。
阿里云官网

Day06-第三章-媒资管理-媒资信息管理 - 图26

阿里云官网注册页面

Day06-第三章-媒资管理-媒资信息管理 - 图27

阿里云官网登录页面

Day06-第三章-媒资管理-媒资信息管理 - 图28

2.在阿里云官网进入VOD产品详情页,单击立即开通。
视频点播首页

Day06-第三章-媒资管理-媒资信息管理 - 图29

开通视频点播服务

Day06-第三章-媒资管理-媒资信息管理 - 图30

上图解释:
注释①:视频点播的计费方式,默认是按照流量计费。
注释②:同意视频点播协议。
注释③:点击开通按钮
开通服务

Day06-第三章-媒资管理-媒资信息管理 - 图31

3.开通完成后,即可进入VOD控制台概览页面,开始使用点播服务
视频点播管理控制台界面

Day06-第三章-媒资管理-媒资信息管理 - 图32

2.2.2 基础配置


在使用服务前,需要完成一些基础的配置,以下步骤将指导您进行处理。
1.媒资管理管理配置-存储管理
VOD提供存储服务,会默认帮您分配一个存储空间(bucket),默认区域为华东2(上海),无需任何配置即可进行上传和媒体资源管理,如您对存储区域有要求可再进行添加,目前VOD服务支持华北2(北京)和华东2(上海)两个服务中心,操作请参考 存储管理文档
阿里云视频点播服务是基于对象存储(OSS)构建的,上传的视频其实是上传到阿里云OSS
管理界面中的存储管理界面

Day06-第三章-媒资管理-媒资信息管理 - 图33

选择视频存储的服务器地址

Day06-第三章-媒资管理-媒资信息管理 - 图34

添加后的存储地址,并选择为默认

Day06-第三章-媒资管理-媒资信息管理 - 图35

2.2.3 通过控制台上传文件


完成上述配置之后,即可在控制台进行视频文件的上传
1.选择媒资库 > 音视频,单击上传音视频。
上传媒资库信息

Day06-第三章-媒资管理-媒资信息管理 - 图36

2.在上传音视频页面,您可以根据需要连续添加多个音视频或选择移除某个音视频,单击开始上传。
页面管理平台上传视频

Day06-第三章-媒资管理-媒资信息管理 - 图37

上图解释:
注释①:选择视频存储地点为:华北1(cn-beijing)
注释②:点击添加视频按钮上传视频文件。
3.已添加的本地视频文件进入上传阶段,当上传进度为100%时,完成上传操作。
上传视频后的视频列表

Day06-第三章-媒资管理-媒资信息管理 - 图38

注意:阿里视频点播服务端默认视频预览的格式为 .mp4 格式,其他格式暂未支持。

2.3 阿里云视频 SDK 代码测试


上面我们通过阿里云的管理平台上传视频,并通过页面平台获得视频播放地址。实际开发中一般是通过代码来上传视频和获得视频播放地址。对此阿里云也为 Java 提供了相应的 SDK 来完成。下面是上传视频获得视频播放地址的简略流程。
文件上传流程

Day06-第三章-媒资管理-媒资信息管理 - 图39

视频播放流程

Day06-第三章-媒资管理-媒资信息管理 - 图40

2.3.1 工程导入


将“资料/项目”下的媒资管理服务业务工程:xc-media-service ,放到 xc-parent 下并解压。后期的媒资相关代码我们会在此工程中进行编写。
媒资项目工程

Day06-第三章-媒资管理-媒资信息管理 - 图41

并将媒资管理工程以模块的方式在父工程的 pom 文件进行配置
添加模块

Day06-第三章-媒资管理-媒资信息管理 - 图42

2.3.2 服务端文件上传


为安全考虑,七牛对上传文件定义了安全机制,需要在上传文件时,除了上传的图片,还需要上传的凭证。凭证类似于火车票或船票。上传凭证需要使用方通过 AccessKey + 存储区域标识 + 文件源信息 来生成。
获得上传凭证示意图

Day06-第三章-媒资管理-媒资信息管理 - 图43

2.3.2.1 AccessKey获取
AccessKey用于程序方式调用云服务API,AccessKey包括AccessKeyId和AccessKeySecret。
●AccessKeyId 用于标识用户。
●AccessKeySecret 是用来验证用户的密钥。AccessKeySecret必须保密。
LTAI4G3wMNtzQPfFPDMHoCJF
uxzY3N4czSqZqhcXcuOq0ZcRlB6zjB
1、进入管理控制台
云管理控制台个人管理连接

Day06-第三章-媒资管理-媒资信息管理 - 图44

2、点击右上角头像
accesskeys 连接地址

Day06-第三章-媒资管理-媒资信息管理 - 图45

3、移动到弹出窗口下的Accesskey按钮进行点击,点击继续使用Accesskey
使用accesskey提示框

Day06-第三章-媒资管理-媒资信息管理 - 图46

4、进入页面后点击右上方的创建Accesskey
创建ack

Day06-第三章-媒资管理-媒资信息管理 - 图47

5、弹出手机验证,根据提示创建Accesskey

Day06-第三章-媒资管理-媒资信息管理 - 图48

6、获得 Accesskey ID和 Accesskey Secret 信息
获得Accesskey ID 和 Accesskey Secret

Day06-第三章-媒资管理-媒资信息管理 - 图49

Day06-第三章-媒资管理-媒资信息管理 - 图50

2.3.2.2 存储区域标识获取


官方文档 中,对存储区域标识有明确的说明如下:
视频点播区域标识

Day06-第三章-媒资管理-媒资信息管理 - 图51

由于之前创建的是 “华北2” ,根据上图它的区域标识为:cn-beijing

2.3.2.3 服务端文件上传测试


1.阿里云 SDK 的 Maven 依赖
项目需要先将官方提供的 SDK 引入到 Maven 工程中的 pom 文件里,坐标如下:

  1. <!--阿里云视频点播-->
  2. <dependency>
  3. <groupId>com.aliyun</groupId>
  4. <artifactId>aliyun-java-sdk-core</artifactId>
  5. <version>4.3.3</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.aliyun</groupId>
  9. <artifactId>aliyun-java-sdk-vod</artifactId>
  10. <version>2.15.2</version>
  11. </dependency>

PS:xc-media-service 工程已经引入,无需再次引入。
2.编写获得上传视频的代码
根据阿里云视频点播文档,可以根据官方的提供的 Java 版的 SDK 进行开发。
在 xc-media-service 工程中编写测试程序。

  1. /**
  2. * <p></p>
  3. *
  4. * @Description:
  5. */
  6. public class AliyunVodTest {
  7. String accessKeyId = "自己的accessKeyId";
  8. String accessKeySecret = "自己的accessKeySecret";
  9. /**
  10. * 初始化代码
  11. * @param accessKeyId
  12. * @param accessKeySecret
  13. * @return
  14. * @throws ClientException
  15. */
  16. public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) {
  17. String regionId = "cn-beijing"; // 点播服务接入区域
  18. DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
  19. DefaultAcsClient client = new DefaultAcsClient(profile);
  20. return client;
  21. }
  22. @Test
  23. public void testUpload() throws ClientException {
  24. //1.创建请求对象
  25. CreateUploadVideoRequest request = new CreateUploadVideoRequest();
  26. request.setTitle("test001 file");
  27. request.setFileName("filename.mp4");
  28. //2.获得客户端对象
  29. DefaultAcsClient client = initVodClient(accessKeyId, accessKeySecret);
  30. // 3.获得响应对象
  31. CreateUploadVideoResponse response = client.getAcsResponse(request);
  32. // 4.解析响应对象
  33. try {
  34. System.out.print("VideoId = " + response.getVideoId() + "\n");
  35. System.out.print("UploadAddress = " + response.getUploadAddress() + "\n");
  36. System.out.print("UploadAuth = " + response.getUploadAuth() + "\n");
  37. } catch (Exception e) {
  38. System.out.print("ErrorMessage = " + e.getLocalizedMessage());
  39. }
  40. System.out.print("RequestId = " + response.getRequestId() + "\n");
  41. }
  42. }

2.3.3 视频播放地址获取


1.编写获得上传视频的代码
根据阿里云视频点播文档,可以根据官方的提供的 Java 版的 SDK 进行开发。
在 xc-media-service 工程中编写测试程序。

  1. /**
  2. * <p></p>
  3. *
  4. * @Description:
  5. */
  6. public class AliyunVodTest {
  7. String accessKeyId = "自己的accessKeyId";
  8. String accessKeySecret = "自己的accessKeySecret";
  9. /**
  10. * 初始化代码
  11. * @param accessKeyId
  12. * @param accessKeySecret
  13. * @return
  14. * @throws ClientException
  15. */
  16. public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) {
  17. String regionId = "cn-beijing"; // 点播服务接入区域
  18. DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
  19. DefaultAcsClient client = new DefaultAcsClient(profile);
  20. return client;
  21. }
  22. @Test
  23. public void testGetURL() throws ClientException {
  24. // 1.获得请求对象
  25. GetPlayInfoRequest request = new GetPlayInfoRequest();
  26. request.setVideoId("上传到点播服务视频的id值");
  27. //2.获得客户端对象
  28. DefaultAcsClient client = initVodClient(accessKeyId, accessKeySecret);
  29. GetPlayInfoResponse response = client.getAcsResponse(request);
  30. try {
  31. List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
  32. //播放地址
  33. for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
  34. System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n");
  35. }
  36. //Base信息
  37. System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n");
  38. } catch (Exception e) {
  39. System.out.print("ErrorMessage = " + e.getLocalizedMessage());
  40. }
  41. System.out.print("RequestId = " + response.getRequestId() + "\n");
  42. }
  43. }

3.上传和媒资信息管理


在媒资管理中,主要是对学成在线的媒资信息管理,并实现与云服务端完成视频上传凭证和地址获取业务对接。下面我们看下具体的媒资管理中的需求。
此模块主要针对教育机构用户对媒资信息的管理,主要功能包括
●媒资文件上传
●保存媒资信息
●分页查询机构内媒资信息
●删除媒资信息
对于功能,下面我们需要分别来进行实现。

3.1 项目环境搭建


学成在线的媒资管理会在 xc-media-service 微服务工程中,进行开发。在开发前,我们需要将其运行环境先构建出来。
1.数据库环境
2.配置中心数据
3.项目的基础代码(entity、dto、controller、service、mapper)

3.1.1 数据库环境


在今天下发资料里的数据脚本导入到本地 MySQL 数据中,资料位置在 ‘资料/数据库脚本/xc_media.sql’ 。
导入后的数据库内容

Day06-第三章-媒资管理-媒资信息管理 - 图52

后面业务中设计到表时,我们在详细讲解表结构。

3.1.2 配置中心数据


1.配置阿里云基础配置
media-service-dev.properties,添加配置项如下:

  1. aliyun.region = 如果是华北2:cn-beijing ,如果是华东2:cn-shanghai
  2. aliyun.accessKeyId = 自己的账号的 accessKeyId
  3. aliyun.accessKeySecret = 自己的账号的accessKeySecret

2.媒资管理应用配置
媒资管理微服务需要在Nacos中创建对应的配置信息,并引入配置内容 media-service-dev-properties

  1. # 修改druid公共配置信息里的连接地址
  2. spring.datasource.url=jdbc:mysql://192.168.94.129:3306/xc_media?userUnicode=true&useSSL=false&characterEncoding=utf8
  3. #springboot启动配置修改
  4. server.servlet.context-path = /media
  5. server.port=63050

3.2 媒资文件上传功能实现


对于教育机构将媒资文件上传操作中,将媒资文件上传到云端,下面是具体的时序图:
媒资文件上传时序图

Day06-第三章-媒资管理-媒资信息管理 - 图53

在上面的接口中,获得上传的凭证默认的有效时间是 :3000秒(50分钟) ,详见: 上传地址和凭证说明
,如果上传时间过长,前端需要重新刷新凭证内容。所有后端需要开发刷新凭证的接口地址。

3.2.1 断点续传上传文件


场景:大文件的上传,大文件的下载,需要考虑断点续传
通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了,电断了没有上传完成,需要客户重新上传,这是致命的,所以对于大文件上传的要求最基本的是断点续传。
断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载,断点续传可以提高节省操作时间,提高用户体验性。
分片上传示意图

Day06-第三章-媒资管理-媒资信息管理 - 图54

  1. 对于媒资管理的分片上传,是通过阿里云提供客户端技术(javaScript/ios/android)来实现,但是需要结合后端的**获得凭证**和**刷新凭证**接口来完成文件分片上传。<br />PS:由于是前端实现分片上传,具体代码课上不在进行介绍,我们的重点是放在分片文件上传的后端微服务接口开发上。<br />断电续传:<br /> 1.文件上传的时间缩短<br /> 2.文件上传提速<br />断点续传原理:[https://baijiahao.baidu.com/s?id=1590263619161019562&wfr=spider&for=pc](https://baijiahao.baidu.com/s?id=1590263619161019562&wfr=spider&for=pc)<br />Java实现断点续传:[https://blog.csdn.net/u012319157/article/details/79111491](https://blog.csdn.net/u012319157/article/details/79111491)<br />js实现断点续传:[https://www.cnblogs.com/luozhixiang/p/9306240.html](https://itheima-sh.yuque.com/docs/share/_www.cnblogs.com_luozhixiang_p_9306240)

3.2.2 媒资上传文件需求


1.教育机构用户在门户管理界面中的媒资管理链接进入媒资管理界面。
进入媒资管理

Day06-第三章-媒资管理-媒资信息管理 - 图55

2.教育机构用户在”媒资管理”页面中点击”上传媒资文件”按钮,打开上传媒资文件页面。
上传媒资按钮

Day06-第三章-媒资管理-媒资信息管理 - 图56

上传媒资对话框

Day06-第三章-媒资管理-媒资信息管理 - 图57

3.选择要上传的文件,自动执行文件上传。
开始上传媒资文件

Day06-第三章-媒资管理-媒资信息管理 - 图58

4.选择要上传的文件,自动执行文件上传。

3.2.3 媒资上传文件接口定义
1.接口参数列表
根据前后端传入参数列表来定义接口
Http接口地址

Day06-第三章-媒资管理-媒资信息管理 - 图59

接口传入传出列表—获得视频上传凭证

Day06-第三章-媒资管理-媒资信息管理 - 图60

接口传入传出列表—刷新视频上传凭证

Day06-第三章-媒资管理-媒资信息管理 - 图61

2. 传入传出的参数封装类
根据前后端传入参数列表来定义参数封装类
●传入参数—获得视频上传参数
在 xc-api 工程的 com.xuecheng.api.media.model.aliyun 包下创建接口类接口定义如下:

  1. package com.xuecheng.api.media.aliyun;
  2. import io.swagger.annotations.ApiModel;
  3. import io.swagger.annotations.ApiModelProperty;
  4. import lombok.Data;
  5. import java.util.Map;
  6. /**
  7. * <P>
  8. * 媒体上传请求信息
  9. * </p>
  10. *
  11. */
  12. @Data
  13. @ApiModel("媒体上传请求信息封装类")
  14. public class VodUploadRequest {
  15. /**
  16. * 视频标题
  17. */
  18. @ApiModelProperty("视频标题")
  19. private String title;
  20. /**
  21. * 视频源文件名(必须带扩展名,且扩展名不区分大小写)
  22. */
  23. @ApiModelProperty("视频源文件名")
  24. private String fileName;
  25. /**
  26. * 回调URL
  27. */
  28. @ApiModelProperty("回调URL")
  29. private String callbackURL;
  30. /**
  31. * 用户自定义的扩展字段,用于回调时透传返回,最大长度512字节
  32. */
  33. @ApiModelProperty("用户自定义的扩展字段,用于回调时透传返回,最大长度512字节")
  34. private Map<String, String> extend;
  35. }

●传出参数—获得/刷新视频上传参数
在 xc-api 工程的 com.xuecheng.api.media.model.aliyun 包下创建接口类接口定义如下:

  1. package com.xuecheng.api.media.model.aliyun;
  2. import io.swagger.annotations.ApiModel;
  3. import io.swagger.annotations.ApiModelProperty;
  4. import lombok.Data;
  5. /**
  6. * <P>
  7. * 视频上传凭证,前端使用此凭证上传
  8. * </p>
  9. */
  10. @Data
  11. @ApiModel("视频上传凭证封装类")
  12. public class VodUploadToken {
  13. /**
  14. * 请求id
  15. */
  16. @ApiModelProperty("请求id")
  17. private String requestId;
  18. /**
  19. * 上传视频的唯一标识
  20. */
  21. @ApiModelProperty("上传视频的唯一标识")
  22. private String videoId;
  23. /**
  24. * 上传URL
  25. */
  26. @ApiModelProperty("上传URL")
  27. private String uploadAddress;
  28. /**
  29. * 上传凭证
  30. */
  31. @ApiModelProperty("上传凭证")
  32. private String uploadAuth;
  33. }

3. 接口编写
在 xc-api 工程的 com.xuecheng.api.media 包下创建接口类接口定义如下:
●媒资文件上传

  1. package com.xuecheng.api.media.model;
  2. import com.xuecheng.api.media.model.aliyun.VodUploadRequest;
  3. import com.xuecheng.api.media.model.aliyun.VodUploadToken;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiImplicitParam;
  6. import io.swagger.annotations.ApiOperation;
  7. /**
  8. * <p></p>
  9. *
  10. * @Description:
  11. */
  12. @Api("媒资管服务Api")
  13. public interface AliyunVodApi {
  14. @ApiOperation("获得媒资文件上传凭证")
  15. VodUploadToken generateUploadToken(VodUploadRequest request);
  16. @ApiOperation("刷新媒资文件上传凭证")
  17. @ApiImplicitParam(name = "videoId",value = "媒资文件的id值",required = true,paramType = "path",dataType = "String")
  18. VodUploadToken refreshUploadToken(String videoId);
  19. }

3.2.4 媒资上传文件接口开发


由于本次微服务只和阿里云服务进行数据交换,没有业务的操作,只需要编写controller ,controller 层与前端进行数据交互。
1.controller 编写

  1. package com.xuecheng.media.controller;
  2. import com.aliyuncs.DefaultAcsClient;
  3. import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
  4. import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;
  5. import com.xuecheng.api.media.model.AliyunVodApi;
  6. import com.xuecheng.api.media.model.aliyun.VodUploadRequest;
  7. import com.xuecheng.api.media.model.aliyun.VodUploadToken;
  8. import com.xuecheng.media.common.utils.AliyunVODUtil;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Value;
  11. import org.springframework.web.bind.annotation.*;
  12. /**
  13. * <p></p>
  14. *
  15. * @Description:
  16. */
  17. @Slf4j
  18. @RestController
  19. public class AliyunVodController implements AliyunVodApi {
  20. /*
  21. * aliyun.region = cn-shanghai
  22. aliyun.accessKeyId = LTAI4G3wMNtzQPfFPDMHoCJF
  23. aliyun.accessKeySecret = uxzY3N4czSqZqhcXcuOq0ZcRlB6zjB
  24. *
  25. * */
  26. @Value("${aliyun.region}")
  27. private String region;
  28. @Value("${aliyun.accessKeyId}")
  29. private String accessKeyId;
  30. @Value("${aliyun.accessKeySecret}")
  31. private String accessKeySecret;
  32. @PostMapping("media/vod-token")
  33. public VodUploadToken generateUploadToken(@RequestBody VodUploadRequest uploadRequest) {
  34. // PS: 只要和本项目中微服务之外的内容要产生交互,必须要进行try-catch处理
  35. // 交互方:aliyun(第三方服务)
  36. // 原因:网络(不稳定因素)
  37. try {
  38. // 1.初始化客户端
  39. DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);
  40. // 2.创建请求对象并获得响应对象
  41. CreateUploadVideoResponse response = AliyunVODUtil.createUploadVideo(client, uploadRequest.getTitle(), uploadRequest.getFileName());
  42. // 3.解析响应数据
  43. VodUploadToken token = new VodUploadToken();
  44. token.setVideoId(response.getVideoId());
  45. token.setUploadAddress(response.getUploadAddress());
  46. token.setUploadAuth(response.getUploadAuth());
  47. token.setRequestId(response.getRequestId());
  48. return token;
  49. } catch (Exception e) {
  50. // printStackTrace:将程序中的所有调用关系的栈信息进行打印-日志(日志文件-IO)
  51. // 用户大量请求
  52. // e.printStackTrace(); //丢工作
  53. // 异常信息的说明
  54. // 1.只将错误信息记录
  55. // 2.将错误信息隐藏并返回友好提示
  56. String message = e.getMessage();
  57. log.error(MediaErrorCode.E_140011.getDesc()+" : {}",message);
  58. // throw new BusinessException();
  59. // 编译器的问题:只看代码,不管代码中方法调用的结果内容
  60. ExceptionCast.cast(CommonErrorCode.UNKOWN);
  61. return null;
  62. }
  63. }
  64. @GetMapping("media/refresh-vod-token/{videoId}")
  65. public VodUploadToken refreshUploadToken(@PathVariable String videoId) {
  66. // PS: 只要和本项目中微服务之外的内容要产生交互,必须要进行try-catch处理
  67. // 交互方:aliyun(第三方服务)
  68. // 原因:网络(不稳定因素)
  69. try {
  70. // 1.初始化客户端
  71. DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);
  72. // 2.创建请求对象并获得响应对象
  73. RefreshUploadVideoResponse response = AliyunVODUtil.refreshUploadVideo(client, videoId);
  74. // 3.解析响应数据
  75. VodUploadToken token = new VodUploadToken();
  76. token.setVideoId(response.getVideoId());
  77. token.setUploadAddress(response.getUploadAddress());
  78. token.setUploadAuth(response.getUploadAuth());
  79. token.setRequestId(response.getRequestId());
  80. return token;
  81. } catch (Exception e) {
  82. // printStackTrace:将程序中的所有调用关系的栈信息进行打印-日志(日志文件-IO)
  83. // 用户大量请求
  84. // e.printStackTrace(); //丢工作
  85. // 异常信息的说明
  86. // 1.只将错误信息记录
  87. // 2.将错误信息隐藏并返回友好提示
  88. String message = e.getMessage();
  89. log.error(MediaErrorCode.E_140015.getDesc()+" : {}",message);
  90. // throw new BusinessException();
  91. // 编译器的问题:只看代码,不管代码中方法调用的结果内容
  92. ExceptionCast.cast(CommonErrorCode.UNKOWN);
  93. return null;
  94. }
  95. }
  96. }

3.2.5 媒资上传文件接口测试


由于阿里云已经提供了 JavaScript 的 SDK 来实现文件分片上传,那么可以将 官方相应的测试页面 引入进行测试。
在 xc-media-service 媒资管理微服务中,已经将测试页面导入到工程中,我们直接可以进行测试。
项目中的测试页面

Day06-第三章-媒资管理-媒资信息管理 - 图62

  1. 通过工程中的 aliyun 客户端页面来完成获得文件上传凭证和文件上传操作。前端调用后端业务微服务接口代码如下:<br />前端代码示意图

Day06-第三章-媒资管理-媒资信息管理 - 图63

上图解释:
注释①:获得视频上传凭证业务微服务地址
注释②:刷新视频上传凭证业务微服务地址
1.启动工程,访问 http://127.0.0.1:8085/media/vod/upload.html,展示以下界面:
测试页面示意图

Day06-第三章-媒资管理-媒资信息管理 - 图64

2.选择要上传的视频文件,点击开始上传,在上传文件的执行过程中,关掉浏览器(测试断点续传)
上传文件示意图

Day06-第三章-媒资管理-媒资信息管理 - 图65

3.再次打开上传页面,依然选择上次的视频文件,再次点击 开始上传,观察浏览器的Console。
再次上传文件示意图

Day06-第三章-媒资管理-媒资信息管理 - 图66

上传文件直接从 12% 开始上传,并非 1% 开始。

3.3 保存媒资信息功能实现


对于教育机构将媒资文件上传操作中,除了将媒资文件上传到云端,而且要将视频的基本信息保存到媒资数据库中,下面是具体的时序图:

Day06-第三章-媒资管理-媒资信息管理 - 图67

前端在将视频文件上传到云端后,要将视频文件的信息保存到媒资管理微服务中的数据库中。

3.3.1 数据模型(表结构)


媒资管理服务的数据库 xc_media 中定义了媒资数据结构表。
1.媒资表说明
媒资表结构

Day06-第三章-媒资管理-媒资信息管理 - 图68

在上图中的表结构中,主要字段为:
1.自身信息描述:id,filename,type,timelength等
2.教学机构描述:company_id,company_name
3.审核信息描述:audit_status, audit_mind
4.阿里云信息描述:bucket,url,file_id

3.3.2 保存媒资信息接口定义


1.接口参数列表
根据前后端传入参数列表来定义接口
Http接口地址

Day06-第三章-媒资管理-媒资信息管理 - 图69

接口传入传出列表

Day06-第三章-媒资管理-媒资信息管理 - 图70

2. 传入传出的参数封装类
根据前后端传入保存参数使用 VO 数据来封装
●媒资 VO 封装类

  1. package com.xuecheng.api.media.model.vo;
  2. import io.swagger.annotations.ApiModel;
  3. import io.swagger.annotations.ApiModelProperty;
  4. import lombok.Data;
  5. /**
  6. * 媒资保存信息
  7. */
  8. @Data
  9. @ApiModel(value="MediaVO", description="媒资保存信息")
  10. public class MediaVO {
  11. @ApiModelProperty(value = "文件名称", required = true)
  12. private String filename;
  13. @ApiModelProperty(value = "文件类型(文档,音频,视频)", required = true)
  14. private String type;
  15. @ApiModelProperty(value = "文件标识, 七牛的key,视频的videoId", required = true)
  16. private String fileId;
  17. @ApiModelProperty(value = "标签")
  18. private String tags;
  19. @ApiModelProperty(value = "存储空间")
  20. private String bucket;
  21. }

根据前后端传出参数使用 DTO 数据来封装
●媒资 DTO 封装类(代码生成器生成)

  1. package com.xuecheng.api.media.model;
  2. import io.swagger.annotations.ApiModel;
  3. import io.swagger.annotations.ApiModelProperty;
  4. import lombok.Data;
  5. import java.io.Serializable;
  6. import java.time.LocalDateTime;
  7. /**
  8. * 媒资信息
  9. */
  10. @Data
  11. @ApiModel(value="MediaDTO", description="媒资信息")
  12. public class MediaDTO implements Serializable {
  13. @ApiModelProperty(value = "主键")
  14. private Long id;
  15. @ApiModelProperty(value = "机构ID")
  16. private Long companyId;
  17. @ApiModelProperty(value = "机构名称")
  18. private String companyName;
  19. @ApiModelProperty(value = "文件名称", required = true)
  20. private String filename;
  21. @ApiModelProperty(value = "文件类型(文档,音频,视频)", required = true)
  22. private String type;
  23. @ApiModelProperty(value = "标签")
  24. private String tags;
  25. @ApiModelProperty(value = "存储空间", required = true)
  26. private String bucket;
  27. @ApiModelProperty(value = "文件标识, 七牛的key,视频的videoId", required = true)
  28. private String fileId;
  29. @ApiModelProperty(value = "媒资文件访问地址")
  30. private String url;
  31. private String timelength;
  32. @ApiModelProperty(value = "上传人")
  33. private String username;
  34. @ApiModelProperty(value = "上传时间")
  35. private LocalDateTime createDate;
  36. @ApiModelProperty(value = "修改时间")
  37. private LocalDateTime changeDate;
  38. @ApiModelProperty(value = "状态")
  39. private Integer status;
  40. @ApiModelProperty(value = "备注")
  41. private String remark;
  42. @ApiModelProperty(value = "审核状态")
  43. private String auditStatus;
  44. @ApiModelProperty(value = "审核意见")
  45. private String auditMind;
  46. }

3. 接口编写
在 xc-api 工程的 com.xuecheng.api.media 包下创建接口类接口定义如下:
●媒资文件保存

  1. package com.xuecheng.api.media;
  2. import com.xuecheng.api.media.aliyun.VodUploadRequest;
  3. import com.xuecheng.api.media.aliyun.VodUploadToken;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiImplicitParam;
  6. import io.swagger.annotations.ApiOperation;
  7. /**
  8. * <p></p>
  9. *
  10. * @Description:
  11. */
  12. @Api(value = "媒资管理", tags = "媒资管理API",description = "对媒资信息进行管理")
  13. public interface MediaApi {
  14. //其他代码省略
  15. @ApiOperation("保存媒资信息")
  16. @ApiImplicitParam(name = "vo", value = "媒资保存信息", required = true, dataType = "MediaVO", paramType = "body")
  17. MediaDTO createMedia(MediaVO vo);
  18. }

3.3.3 保存媒资信息接口开发


1.DAO编写
Mybatis Plus 已经简化了单表操作,它提供的 Api 就可以完成添加数据操作,所有不需要进行编写。
2. service编写
对于service层,除了进行业务层逻辑判断和操作外,还需要将 PO 数据转为 DTO 数据,所以需要编写课程计划的对象属性映射。
●对象属性转换类

  1. package com.xuecheng.media.convert;
  2. import com.xuecheng.api.media.model.MediaDTO;
  3. import com.xuecheng.api.media.model.vo.MediaVO;
  4. import com.xuecheng.media.entity.Media;
  5. import org.mapstruct.Mapper;
  6. import org.mapstruct.factory.Mappers;
  7. import java.util.List;
  8. /**
  9. * 媒资信息转换类
  10. */
  11. @Mapper
  12. public interface MediaConvert {
  13. MediaConvert INSTANCE = Mappers.getMapper(MediaConvert.class);
  14. MediaDTO entity2dto(Media media);
  15. Media dto2entity(MediaDTO media);
  16. }

●接口

  1. public interface MediaService extends IService<Media> {
  2. //其他代码省略
  3. /**
  4. * 保存媒资信息
  5. * @param dto
  6. * @return
  7. */
  8. MediaDTO createMedia(MediaDTO dto);
  9. }

●实现类

  1. package com.xuecheng.media.service.impl;
  2. import com.aliyuncs.DefaultAcsClient;
  3. import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.xuecheng.api.media.model.dto.MediaDTO;
  7. import com.xuecheng.common.domain.code.CommonErrorCode;
  8. import com.xuecheng.common.enums.common.ResourceTypeEnum;
  9. import com.xuecheng.common.exception.ExceptionCast;
  10. import com.xuecheng.common.util.StringUtil;
  11. import com.xuecheng.media.common.constant.MediaErrorCode;
  12. import com.xuecheng.media.common.utils.AliyunVODUtil;
  13. import com.xuecheng.media.convert.MediaConvert;
  14. import com.xuecheng.media.entity.Media;
  15. import com.xuecheng.media.mapper.MediaMapper;
  16. import com.xuecheng.media.service.MediaService;
  17. import lombok.extern.slf4j.Slf4j;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.stereotype.Service;
  20. import org.springframework.transaction.annotation.Transactional;
  21. import org.springframework.util.CollectionUtils;
  22. import org.springframework.util.ObjectUtils;
  23. import java.util.List;
  24. /**
  25. * <p>
  26. * 媒资信息 服务实现类
  27. * </p>
  28. *
  29. * @author itcast
  30. */
  31. @Slf4j
  32. @Service
  33. public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {
  34. /*
  35. * 业务分析:
  36. * 1.判断关键
  37. * companyid filename fileid(videoId)
  38. * 2.给信息数据赋值默认值
  39. * auditStatus:未审核
  40. *
  41. * 3.保存信息
  42. * 4.将数据库最新数据返回
  43. *
  44. * */
  45. @Transactional
  46. public MediaDTO createMedia(MediaDTO dto) {
  47. //1.判断关键
  48. // companyid filename fileid(videoId)
  49. if (ObjectUtils.isEmpty(dto.getCompanyId())||
  50. StringUtil.isBlank(dto.getFilename())||
  51. StringUtil.isBlank(dto.getFileId())
  52. ) {
  53. ExceptionCast.cast(CommonErrorCode.E_100101);
  54. }
  55. // 2.给信息数据赋值默认值
  56. // auditStatus:未审核
  57. dto.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
  58. // 3.保存信息
  59. Media media = MediaConvert.INSTANCE.dto2entity(dto);
  60. boolean result = this.save(media);
  61. if (!result) {
  62. ExceptionCast.cast(MediaErrorCode.E_140001);
  63. }
  64. // 4.将数据库最新数据返回
  65. Media po = this.getById(media.getId());
  66. MediaDTO resultDTO = MediaConvert.INSTANCE.entity2dto(po);
  67. return resultDTO;
  68. }
  69. }

3. controller编写

  1. @RestController
  2. public class MediaController implements MediaApi {
  3. @Autowired
  4. private MediaService mediaService;
  5. //其他代码省略
  6. @PostMapping("media")
  7. public MediaDTO createMedia(@RequestBody MediaVO vo) {
  8. //1.获得机构的id值
  9. Long companyId = SecurityUtil.getCompanyId();
  10. //2.将vo数据转换为dto数据
  11. MediaDTO dto = MediaConvert.INSTANCE.vo2dto(vo);
  12. dto.setCompanyId(companyId);
  13. //3.调用service获得结果数据
  14. MediaDTO result = mediaService.createMedia(dto);
  15. return result;
  16. }
  17. }


3.3.3 信息接口测试


测试环境需要启动的微服务有:
1.注册中心 xc-discover-service (端口:63000)
2.服务网关 xc-gateway-service (端口:63010)
3.媒资管理 xc-media-service (端口:63050)
1. 使用 postman 在请求信息中添加请求参数
POST http://127.0.0.1:63010/media/media
请求消息内容如下:

  1. {
  2. "filename":"文件1",
  3. "type":"001002",
  4. "fileId":"自己阿里云上的视频id值"
  5. }

●请求头(访问令牌)

  1. 请求头的 key 值: authorization
  2. 请求头的 value 值:
  3. Bearer ewogICAgImF1ZCI6IFsKICAgICAgICAieHVlY2hlbmctcmVzb3VyY2UiCiAgICBdLAogICAgInBheWxvYWQiOiB7CiAgICAgICAgIjExNzcxNDQyMDk0NjMxMjgxMjUiOiB7CiAgICAgICAgICAgICJyZXNvdXJjZXMiOiBbCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJ1c2VyX2F1dGhvcml0aWVzIjogewogICAgICAgICAgICAgICAgInJfMDAxIjogWwogICAgICAgICAgICAgICAgICAgICJ4Y19jb21wYW55X21vZGlmeSIsCgkJCQkJInhjX2NvbXBhbnlfdmlldyIsCgkJCQkJInhjX2NvdXJzZV9iYXNlX2RlbCIsCgkJCQkJInhjX2NvdXJzZV9iYXNlX2VkaXQiLAoJCQkJCSJ4Y19jb3Vyc2VfYmFzZV9saXN0IiwKCQkJCQkieGNfY291cnNlX2Jhc2Vfc2F2ZSIsCgkJCQkJInhjX2NvdXJzZV9iYXNlX3ZpZXciLAoJCQkJCSJ4Y19jb3Vyc2VfcHVibGlzaCIsCgkJCQkJInhjX21hcmtldF9zYXZlX21vZGlmeSIsCgkJCQkJInhjX21hcmtldF92aWV3IiwKCQkJCQkieGNfbWVkaWFfZGVsIiwKCQkJCQkieGNfbWVkaWFfbGlzdCIsCgkJCQkJInhjX21lZGlhX3ByZXZpZXciLAoJCQkJCSJ4Y19tZWRpYV9zYXZlIiwKCQkJCQkieGNfdGVhY2hlcl9saXN0IiwKCQkJCQkieGNfdGVhY2hlcl9tb2RpZnkiLAoJCQkJCSJ4Y190ZWFjaGVyX3NhdmUiLAoJCQkJCSJ4Y193b3JrcmVjb3JkX2NvcnJlY3Rpb24iLAoJCQkJCSJ4Y193b3JrcmVjb3JkX2xpc3QiLAoJCQkJCSJ4Y190ZWFjaHBsYW53b3JrX2RlbCIsCgkJCQkJInhjX3RlYWNocGxhbndvcmtfbGlzdCIsCgkJCQkJInhjX3RlYWNocGxhbndvcmtfc2F2ZV9tb2RpZnkiLAoJCQkJCSJ4Y190ZWFjaHBsYW5fZGVsIiwKCQkJCQkieGNfdGVhY2hwbGFuX3NhdmVfbW9kaWZ5IiwKCQkJCQkieGNfdGVhY2hwbGFuX3ZpZXciCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgInJfMDAyIjogWwogICAgICAgICAgICAgICAgICAgICJ4Y19jb3Vyc2VfYWRtaW5fbGlzdCIsCgkJCQkJInhjX2NvdXJzZV9iYXNlX2NvbW1pdCIsCgkJCQkJInhjX3N5c3RlbV9jYXRlZ29yeSIsCgkJCQkJInhjX21fbWVkaWFfbGlzdCIsCgkJCQkJInhjX21lZGlhX2F1ZGl0IgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKICAgICJ1c2VyX25hbWUiOiAieGMtdXNlci1maXJzdCIsCiAgICAic2NvcGUiOiBbCiAgICAgICAgInJlYWQiCiAgICBdLAogICAgIm1vYmlsZSI6ICIxNTAxMjM0NTY3OCIsCiAgICAiZXhwIjogMTYwNjUyNTEyMiwKICAgICJjbGllbnRfYXV0aG9yaXRpZXMiOiBbCiAgICAgICAgIlJPTEVfVVNFUiIKICAgIF0sCiAgICAianRpIjogIjFlYjdlOTg3LWQ3YzItNDBmNS1iMGQ2LWNkNjEzOWNiMThlMCIsCiAgICAiY2xpZW50X2lkIjogInhjLWNvbS1wbGF0Zm9ybSIsCiAgICAiY29tcGFueUlkIjogMTIzMjE0MTQyNQp9

响应内容如下:

Day06-第三章-媒资管理-媒资信息管理 - 图71

3.4 查询媒资信息功能实现(学员实现)


机构将视频信息保存到媒资服务器中,对此需要开发查询当前机构下的媒资信息。

3.4.1 查询媒资信息需求分析


用户进入”媒资管理”页面中,默认执行无参数分页查询,展示机构内媒资信息列表,可通过输入查询参数进行条件检索。
媒资信息检索

Day06-第三章-媒资管理-媒资信息管理 - 图72

Day06-第三章-媒资管理-媒资信息管理 - 图73

查询条件为:
1.根据媒资名称模糊进行查询
2.根据媒资的类型进行查询

3.4.2 查询媒资信息接口定义


1.接口参数列表
根据前后端传入参数列表来定义接口
Http接口地址

Day06-第三章-媒资管理-媒资信息管理 - 图74

接口传入传出列表

Day06-第三章-媒资管理-媒资信息管理 - 图75

3.5 预览媒资信息功能实现(学员实现)


业务分析:
1.判断关键数据
mediaId、companyId
2.判断业务数据
媒资信息
判断是否存在(mediaId、companyId)
判断媒资类型,如果是视频的话,要获得阿里云视频点播的播放地址
3.获得媒资资源的路径地址Url
获得最新的播放地址,从阿里云上获得
PS:优化—要从缓存中获得url(ps:缓存中必须存在url—1.创建media获得,2.服务端启动时来获得—定时任务)
缓存中的url—-设置缓存中的ttl
4.返回结果内容

3.6.1 预览媒资信息功能需求分析


用户可点击媒资分页列表某一行数据后的”预览视频“按钮,执行媒资信息在线预览。
预览媒资信息

Day06-第三章-媒资管理-媒资信息管理 - 图76

Day06-第三章-媒资管理-媒资信息管理 - 图77

3.6.2 预览媒资信息功能接口定义


1.接口参数列表
根据前后端传入参数列表来定义接口
Http接口地址

Day06-第三章-媒资管理-媒资信息管理 - 图78

接口传入传出列表

Day06-第三章-媒资管理-媒资信息管理 - 图79

2. 接口编写
在 xc-api 工程的 com.xuecheng.api.media 包下创建接口类接口定义如下:
●媒资删除

  1. package com.xuecheng.api.media;
  2. import com.xuecheng.api.media.aliyun.VodUploadRequest;
  3. import com.xuecheng.api.media.aliyun.VodUploadToken;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiImplicitParam;
  6. import io.swagger.annotations.ApiOperation;
  7. /**
  8. * <p></p>
  9. *
  10. * @Description:
  11. */
  12. @Api("媒资管服务Api")
  13. public interface AliyunVodApi {
  14. @ApiOperation("获得媒资播放地址")
  15. String getPlayUrlByMediaId(Long mediaId);
  16. }

3.6.3 预览媒资信息功能接口开发


1.DAO编写
Mybatis Plus 已经简化了单表操作,它提供的 Api 就可以完成添加数据操作,所有不需要进行编写。
2. service编写
●接口

  1. public interface MediaService extends IService<Media> {
  2. //其他代码省略
  3. /**
  4. * 获得媒资信息的资源路径地址
  5. * @param mediaId
  6. * @param companyId
  7. * @return
  8. */
  9. String getPlayUrlByMediaId(Long mediaId,Long companyId);
  10. }

●实现类

  1. /**
  2. * 媒资信息 服务实现类
  3. */
  4. @Service
  5. public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {
  6. //其他代码省略
  7. public String getPlayUrlByMediaId(Long mediaId,Long companyId) {
  8. // 1.判断关键数据
  9. if (ObjectUtils.isEmpty(mediaId)||
  10. ObjectUtils.isEmpty(companyId)
  11. ) {
  12. ExceptionCast.cast(CommonErrorCode.E_100101);
  13. }
  14. // 2.判断业务数据
  15. // 媒资信息是否存在
  16. LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
  17. queryWrapper.eq(Media::getId, mediaId);
  18. if (!(ObjectUtils.nullSafeEquals(companyId, MediaAuditController.OPERATION_FLAG))) {
  19. queryWrapper.eq(Media::getCompanyId, companyId);
  20. }
  21. Media media = this.getOne(queryWrapper);
  22. if (ObjectUtils.isEmpty(media)) {
  23. ExceptionCast.cast(MediaErrorCode.E_140005);
  24. }
  25. // 3.获得媒资文件的资源路径地址
  26. // 判断媒资类型是否是视频类型,如果是需要获得aliyun视频的地址
  27. String type = media.getType();
  28. String resourceUrl = null;
  29. if (ResourceTypeEnum.VIDEO. getCode().equals(type)) {
  30. resourceUrl = getAliyunVodPlayUrl(media.getFileId());
  31. } else if (ResourceTypeEnum.DOCUMENT.getCode().equals(type)){
  32. //获得的媒资文档的资源访问地址路径
  33. } else if (ResourceTypeEnum.WORK.getCode().equals(type)){
  34. //获得的媒资文档的资源访问地址路径
  35. }
  36. return resourceUrl;
  37. }
  38. @Value("${aliyun.region}")
  39. private String region;
  40. @Value("${aliyun.accessKeyId}")
  41. private String accessKeyId;
  42. @Value("${aliyun.accessKeySecret}")
  43. private String accessKeySecret;
  44. /**
  45. * 获得阿里云视频播放地址
  46. * @param fileId
  47. * @return
  48. */
  49. private String getAliyunVodPlayUrl(String fileId) {
  50. String playURL = null;
  51. try {
  52. DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);
  53. GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, fileId);
  54. List<GetPlayInfoResponse.PlayInfo> playInfoList = playInfo.getPlayInfoList();
  55. if (CollectionUtils.isEmpty(playInfoList)) {
  56. ExceptionCast.cast(MediaErrorCode.E_140018);
  57. }
  58. // 默认获得第一个播放地址
  59. playURL = playInfoList.get(0).getPlayURL();
  60. } catch (Exception e) {
  61. log.error(MediaErrorCode.E_140012.getDesc()+" : {}",e.getMessage());
  62. ExceptionCast.cast(MediaErrorCode.E_140012);
  63. }
  64. return playURL;
  65. }
  66. }

3. controller编写

  1. package com.xuecheng.media.controller;
  2. import com.aliyuncs.DefaultAcsClient;
  3. import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
  4. import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;
  5. import com.xuecheng.api.media.AliyunVodApi;
  6. import com.xuecheng.api.media.model.aliyun.VodUploadRequest;
  7. import com.xuecheng.api.media.model.aliyun.VodUploadToken;
  8. import com.xuecheng.common.domain.code.CommonErrorCode;
  9. import com.xuecheng.common.exception.ExceptionCast;
  10. import com.xuecheng.common.util.SecurityUtil;
  11. import com.xuecheng.media.common.constant.MediaErrorCode;
  12. import com.xuecheng.media.common.utils.AliyunVODUtil;
  13. import com.xuecheng.media.service.MediaService;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.beans.factory.annotation.Value;
  17. import org.springframework.web.bind.annotation.*;
  18. /**
  19. * <p></p>
  20. *
  21. * @Description:
  22. */
  23. @Slf4j
  24. @RestController
  25. public class AliyunVodController implements AliyunVodApi {
  26. @Autowired
  27. private MediaService mediaService;
  28. @GetMapping("media/preview/{mediaId}")
  29. public String getPlayUrlByMediaId(@PathVariable Long mediaId) {
  30. Long companyId = SecurityUtil.getCompanyId();
  31. String playUrl = mediaService.getPlayUrlByMediaId(mediaId, companyId);
  32. return playUrl;
  33. }
  34. }

3.6.4 信息接口测试


测试环境需要启动的微服务有:
1.注册中心 xc-discover-service (端口:63000)
2.服务网关 xc-gateway-service (端口:63010)
3.媒资管理 xc-media-service (端口:63050)
4.系统管理 xc-system-service (端口:63110)
测试环境需要启动的前端工程有:
1.project-xczx2-portal-vue-ts(端口:8601)
1. 使用 前端在页面请求信息中添加请求参数
前端工程的测试页面:http://localhost:8601/#/organization/media-list

Day06-第三章-媒资管理-媒资信息管理 - 图80



3.6 删除媒资信息功能实现(学员实现)


业务分析:
1.判断关键数据
mediaId、companyId
2.判断业务数据
媒资信息
判断是否存在
判断审核状态:只有审核通过不能删除
判断媒资信息是否有绑定课程计划数据
绑定媒资和课程计划数据:content(发送feign)
teachplan_media
3.删除媒资信息
媒资服务中的数据:Media
阿里云对应的视频


3.6.1 删除媒资信息需求分析


用户可点击媒资分页列表某一行数据后的”删除“按钮,执行删除媒资信息。
删除媒资信息

此数据为机构数据,会设计删除数据恢复,数据删除要采用逻辑删除。


3.6.2 删除媒资信息接口定义


1.接口参数列表
根据前后端传入参数列表来定义接口
Http接口地址

接口传入传出列表

Day06-第三章-媒资管理-媒资信息管理 - 图81

Day06-第三章-媒资管理-媒资信息管理 - 图82

Day06-第三章-媒资管理-媒资信息管理 - 图83
Day06-第三章-媒资管理-媒资信息管理 - 图84