热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

学成在线第13天讲义在线学习HLS五

6媒资管理前边章节完成在线视频播放,如何实现点击课程计划播放视频呢,课程视频如何管理呢?本节开始将对课程视频进行管理。6.1需求分析媒资管

媒资管理 
前边章节完成在线视频播放,如何实现点击课程计划播放视频呢,课程视频如何管理呢? 
本节开始将对课程视频进行管理。 
6.1需求分析 
媒资管理系统是每个在线教育平台所必须具备的,百度百科对它的定义如下:
 
每个教学机构都可以在媒资系统管理自己的教学资源,包括:视频、教案等文件。 
目前媒资管理的主要管理对象是课程录播视频,包括:媒资文件的查询、视频上传、视频删除、视频处理等。 
媒资查询:教学机构查询自己所拥有的媒体文件。 
视频上传:将用户线下录制的教学视频上传到媒资系统。 
视频处理:视频上传成功,系统自动对视频进行编码处理。 
视频删除 :如果该视频已不再使用,可以从媒资系统删除。

下边是媒资系统与其它系统的交互情况:
 

1、上传媒资文件 
前端/客户端请求媒资系统上传文件。 
文件上传成功将文件存储到媒资服务器,将文件信息存储到数据库。 
2、使用媒资 
课程管理请求媒资系统查询媒资信息,将课程计划与媒资信息对应、存储。 
3、视频播放 
用户进入学习中心请求学习服务学习在线播放视频。 
学习服务校验用户资格通过后请求媒资系统获取视频地址。 
6.2 开发环境 
6.2.1 创建媒资数据库 
1、媒资文件信息

@Data
@ToString
@Document(collection = "media_file")
public class MediaFile {
/*
文件id、名称、大小、文件类型、文件状态(未上传、上传完成、上传失败)、上传时间、视频处理方式、视频处
理状态、hls_m3u8,hls_ts_list、课程视频信息(课程id、章节id)
*/
@Id
//文件id
private String fileId;
//文件名称
private String fileName;
//文件原始名称
private String fileOriginalName;
//文件路径
private String filePath;
//文件url
private String fileUrl;
//文件类型
private String fileType;
//mimetype
private String mimeType;
//文件大小
private Long fileSize;
//文件状态
private String fileStatus;
//上传时间
private Date uploadTime;
}

2、创建xc_media数据库 
媒资系统使用mongodb数据库存储媒资信息。
 

6.2.2 创建媒资服务工程 
媒资管理的相关功能单独在媒资服务中开发,下边创建媒资服务工程(xc-service-manage-media)。 
媒资服务的配置与cms类似,导入 资料”--xc-service-manage-media工程,工程结构如下:
 

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

 
上传流程如下: 
1、上传前先把文件分成块 
2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传 
3、各分块上传完成最后合并文件 
文件下载则同理。 
6.3.2 文件分块与合并 
为了更好的理解文件分块上传的原理,下边用java代码测试文件的分块与合并。 
6.3.2.1文件分块 
文件分块的流程如下: 
1、获取源文件长度 
2、根据设定的分块文件的大小计算出块数 
3、从源文件读数据依次向每一个块文件写数据。
//测试文件分块方法

@Test
public void testChunk() throws IOException {
File sourceFile = new File("F:/develop/ffmpeg/lucene.mp4");
// File sourceFile = new File("d:/logo.png");
String chunkPath = "F:/develop/ffmpeg/chunk/";
File chunkFolder = new File(chunkPath);
if(!chunkFolder.exists()){
chunkFolder.mkdirs();
}
//分块大小
long chunkSize = 1024*1024*1;
//分块数量
long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize );
if(chunkNum<&#61;0){
chunkNum &#61; 1;
}
//缓冲区大小
byte[] b &#61; new byte[1024];
//使用RandomAccessFile访问文件
RandomAccessFile raf_read &#61; new RandomAccessFile(sourceFile, "r");
//分块
for(int i&#61;0;i//创建分块文件
File file &#61; new File(chunkPath&#43;i);
boolean newFile &#61; file.createNewFile();
if(newFile){
//向分块文件中写数据
RandomAccessFile raf_write &#61; new RandomAccessFile(file, "rw");
int len &#61; ‐1;
while((len &#61; raf_read.read(b))!&#61;‐1){
raf_write.write(b,0,len);
if(file.length()>chunkSize){
break;
}
}
raf_write.close();
}
}
raf_read.close();
}

6.3.2.2文件合并 
文件合并流程&#xff1a; 
1、找到要合并的文件并按文件合并的先后进行排序。 
2、创建合并文件 
3、依次从合并的文件中读取数据向合并文件写入数
//测试文件合并方法

&#64;Test
public void testMerge() throws IOException {
//块文件目录
File chunkFolder &#61; new File("F:/develop/ffmpeg/chunk/");
//合并文件
File mergeFile &#61; new File("F:/develop/ffmpeg/lucene1.mp4");
if(mergeFile.exists()){
mergeFile.delete();
}
//创建新的合并文件
mergeFile.createNewFile();
//用于写文件
RandomAccessFile raf_write &#61; new RandomAccessFile(mergeFile, "rw");
//指针指向文件顶端
raf_write.seek(0);
//缓冲区
byte[] b &#61; new byte[1024];
//分块列表
File[] fileArray &#61; chunkFolder.listFiles();
// 转成集合&#xff0c;便于排序
List fileList &#61; new ArrayList(Arrays.asList(fileArray));
// 从小到大排序
Collections.sort(fileList, new Comparator() {
&#64;Override
public int compare(File o1, File o2) {
if (Integer.parseInt(o1.getName()) return ‐1;
}
return 1;
}
});
//合并文件
for(File chunkFile:fileList){
RandomAccessFile raf_read &#61; new RandomAccessFile(chunkFile,"rw");
int len &#61; ‐1;
while((len&#61;raf_read.read(b))!&#61;‐1){
raf_write.write(b,0,len);
}
raf_read.close();
}
raf_write.close();
}

6.3.3 前端页面 
上传文件的页面内容参考&#xff1a;资料”--upload.vue文件 
6.3.3.1 WebUploader介绍 
如何在web页面实现断点续传&#xff1f; 
常见的方案有&#xff1a; 
1、通过Flash上传&#xff0c;比如SWFuploadUploadify
2、安装浏览器插件&#xff0c;变相的pc客户端&#xff0c;用的比较少。
3Html5 
随着html5的流行&#xff0c;本项目采用Html5完成文件分块上传。 
本项目使用WebUploader完成大文件上传功能的开发&#xff0c;WebUploader官网地址&#xff1a; 
http://fexteam.gz01.bdysite.com/webuploader/
 

使用WebUploader上传流程如下&#xff1a;

 
6.3.3.1 钩子方法 
webuploader中提供很多钩子方法&#xff0c;下边列出一些重要的&#xff1a;
 

本项目使用如下钩子方法&#xff1a; 
1&#xff09;before-send-fifile 
在开始对文件分块儿之前调用&#xff0c;可以做一些上传文件前的准备工作&#xff0c;比如检查文件目录是否创建完成等。

2&#xff09;before-send 
在上传文件分块之前调用此方法&#xff0c;可以请求服务端检查分块是否存在&#xff0c;如果已存在则此分块儿不再上传。 
3&#xff09;after-send-fifile 
在所有分块上传完成后触发&#xff0c;可以请求服务端合并分块文件。 
注册钩子方法源代码&#xff1a;

WebUploader.Uploader.register({
"before‐send‐file":"beforeSendFile",
"before‐send":"beforeSend",
"after‐send‐file":"afterSendFile"
}

6.3.3.2 构建WebUploader 
使用webUploader前需要创建webUploader对象。 
指定上传分块的地址&#xff1a;/api/media/upload/uploadchunk

// 创建uploader对象&#xff0c;配置参数
this.uploader &#61; WebUploader.create(
{
swf:"/static/plugins/webuploader/dist/Uploader.swf",//上传文件的flash文件&#xff0c;浏览器不支持h5时启动
flash
server:"/api/media/upload/uploadchunk",//上传分块的服务端地址&#xff0c;注意跨域问题
fileVal:"file",//文件上传域的name
pick:"#picker",//指定选择文件的按钮容器
auto:false,//手动触发上传
disableGlobalDnd:true,//禁掉整个页面的拖拽功能
chunked:true,// 是否分块上传
chunkSize:1*1024*1024, // 分块大小&#xff08;默认5M&#xff09;
threads:3, // 开启多个线程&#xff08;默认3个&#xff09;
prepareNextFile:true// 允许在文件传输时提前把下一个文件准备好
}
)

6.3.3.3 before-send-fifile 
文件开始上传前前端请求服务端准备上传工作。 
参考源代码如下&#xff1a;

type:"POST",
url:"/api/media/upload/register",
data:{
// 文件唯一表示
fileMd5:this.fileMd5,
fileName: file.name,
fileSize:file.size,
mimetype:file.type,
fileExt:file.ext
}

6.3.3.4 before-send 
上传分块前前端请求服务端校验分块是否存在。 
参考源代码如下&#xff1a;

type:"POST",
url:"/api/media/upload/checkchunk",
data:{
// 文件唯一表示
fileMd5:this.fileMd5,
// 当前分块下标
chunk:block.chunk,
// 当前分块大小
chunkSize:block.end‐block.start
}

6.3.3.5 after-send-fifile 
在所有分块上传完成后触发&#xff0c;可以请求服务端合并分块文件 
参考代码如下&#xff1a;

type:"POST",
url:"/api/media/upload/mergechunks",
data:{
fileMd5:this.fileMd5,
fileName: file.name,
fileSize:file.size,
mimetype:file.type,
fileExt:file.ext
}

6.3.3.6 页面效果


推荐阅读
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
author-avatar
雨过后放晴
若言琴上有琴声,放在匣中何不鸣?
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有