一、准备工作
安装好MongoDB
MongoDB Community Download | MongoDB
教程所用环境
- SpringBoot~2.1.13
- MongoDB~5.0.9
- JDK11
二、上传视频到MongoDB
上传代码我这里就不写了 ,其他文章有很多参考
1、创建数据库后在数据库中新建存储桶
2、上传视频
三、配置SpringBoot
一、配置MongDB环境
1、导入相关maven包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.5.16</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2、yml配置
spring:
data:
mongodb:
host: 127.0.0.1
port: 27017
#数据库
database: frontop_saas_file
#验证库
authentication-database: admin
#用户(如果MongoDB没有配置授权验证的可以不用写验证信息)
username: admin
#密码
password: admin
3、配置自定义GridFsTemplate和GridFSBucket的Bean
作用:如果不配置自定义的话GridFSBucket和GridFsTemplate的话,默认回去fs存储桶中寻找文件,而不是从我们自定义mp4的存储桶中寻找
新建GirdFsConfig.java
package com.frontop.system.config;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
/**
* @author YangBoss
* @title: GridFsConfig
* @projectName frontop-ao
* @description: TODO
* @date 2022/6/22 17:08
*/
@Configuration
public class GridFsConfig {
//获取配置文件中数据库信息
@Value("${spring.data.mongodb.database}")
String db;
@Bean(name = "gridFsMp4Template")
public GridFsTemplate gridFsTestTemplate(MongoDbFactory dbFactory, MongoConverter converter) {
return new GridFsTemplate(dbFactory, converter, "mp4");
}
//GridFSBucket用于打开下载流
@Bean(name="gridMp4BucketTemplate")
public GridFSBucket getGridFSBucket(MongoClient mongoClient){
MongoDatabase mongoDatabase = mongoClient.getDatabase(db);
GridFSBucket bucket = GridFSBuckets.create(mongoDatabase,"mp4");
return bucket;
}
}
四、开始读取视频
1、创建接口,直接贴代码,视频做了分段,按每1024字节返回流
package com.frontop.system.modules.app.controller;
import com.frontop.common.annotation.AnonymousAccess;
import com.frontop.system.modules.app.model.FileDocument;
import com.frontop.system.modules.app.service.MongoFileService;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* @author YangBoss
* @title: RedioController
* @projectName frontop-ao
* @description: TODO
* @date 2022/6/22 17:21
*/
@RestController
@RequestMapping("/video")
public class RedioController {
@Resource(name = "gridFsMp4Template")
private GridFsTemplate gridFsTestTemplate;
@Resource(name = "gridMp4BucketTemplate")
private GridFSBucket gridFSBucket;
/**
* 在线分段读取视频文件
*/
@GetMapping("/viewTo/{id}")
public void viewTo(HttpServletResponse response,HttpServletRequest request,@PathVariable("id") String id) throws Exception {
long skip = -1;
long length = -1;
Query gridQuery = new Query().addCriteria(Criteria.where("_id").is(new ObjectId(id)));
//根据id查询文件
GridFSFile gridFSDBFile = gridFsTestTemplate.findOne(gridQuery);
response.setHeader("Content-Type", "video/mp4");
long fileLength = gridFSDBFile.getLength();
long end = fileLength - 1;
String range = request.getHeader("Range");
if (range != null && range.length() > 0) {
int idx = range.indexOf("-");
skip = Long.parseLong(range.substring(6, idx));
if ((idx + 1) < range.length()) {
end = Long.parseLong(range.substring(idx + 1));
}
length = end - skip + 1;
}
if (range == null || range.length() <= 0) {//bytes=32523-32523
response.setHeader("Content-Length", "" + fileLength);
response.setStatus(200);
} else {
response.setHeader("Content-Length", "" + length);
response.setHeader("Content-Range", "bytes " + skip + "-" + end + "/" + fileLength);
response.setStatus(206);
}
System.out.println("bytes " + skip + "-" + end + "/" + fileLength);
download(response.getOutputStream(), gridFSDBFile, skip, length);
}
/**
* 文件下载基础类
* 断点续读
* @param outputStream 文件输出流
* @param fsFile mongo文件
* @param skip 跳过多少字节 <=0忽略
* @param length 输出字节长度 <=忽略
* @throws Exception
*/
public void download(OutputStream outputStream, GridFSFile fsFile, long skip, long length) throws Exception {
InputStream inputStream = null;
try {
//打开流下载对象
GridFSDownloadStream in = gridFSBucket.openDownloadStream(fsFile.getObjectId());
//获取流对象
GridFsResource resource = new GridFsResource(fsFile, in);
inputStream = resource.getInputStream();
if (skip > 0) {
inputStream.skip(skip);
}
byte[] bs = new byte[1024];
int len;
while ((len = inputStream.read(bs)) != -1) {
if (length > 0) {
if (length > len) {
outputStream.write(bs, 0, len);
outputStream.flush();
length -= len;
} else {
outputStream.write(bs, 0, (int) length);
outputStream.flush();
break;
}
} else {
outputStream.write(bs, 0, len);
outputStream.flush();
}
}
} catch (Exception e) {
throw e;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
五、测试播放
一、打开MongoDB中mp4.files文档
拿到对应视频的id
二、将视频ID输入到对应的接口地址中打开视频
完成播放!!!
注意点:如果不采用断点分段返回流的话,视频进度将无法进行拖拽!
如有问题可在评论留言,会回复
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/67226.html