Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-api-boot
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-api-boot
Commits
da209647
提交
da209647
authored
2月 15, 2023
作者:
方治民
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 优化文件上传的临时文件处理方式
上级
47dbe6cd
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
29 行增加
和
28 行删除
+29
-28
UploadProcessServiceImpl.java
...m/yiring/app/service/upload/UploadProcessServiceImpl.java
+25
-14
UploadProcessService.java
.../java/com/yiring/common/service/UploadProcessService.java
+3
-3
FileManageServiceImpl.java
...com/yiring/common/service/impl/FileManageServiceImpl.java
+1
-11
没有找到文件。
app/src/main/java/com/yiring/app/service/upload/UploadProcessServiceImpl.java
浏览文件 @
da209647
...
@@ -5,11 +5,11 @@ import cn.hutool.core.io.FileUtil;
...
@@ -5,11 +5,11 @@ import cn.hutool.core.io.FileUtil;
import
com.yiring.common.config.EnvConfig
;
import
com.yiring.common.config.EnvConfig
;
import
com.yiring.common.core.Minio
;
import
com.yiring.common.core.Minio
;
import
com.yiring.common.service.UploadProcessService
;
import
com.yiring.common.service.UploadProcessService
;
import
com.yiring.common.util.Commons
;
import
io.minio.ObjectWriteResponse
;
import
io.minio.ObjectWriteResponse
;
import
java.awt.image.BufferedImage
;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.FileInputStream
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Files
;
import
java.nio.file.Files
;
...
@@ -33,6 +33,7 @@ import org.apache.pdfbox.rendering.PDFRenderer;
...
@@ -33,6 +33,7 @@ import org.apache.pdfbox.rendering.PDFRenderer;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.MediaType
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.multipart.MultipartFile
;
/**
/**
* @author Jim
* @author Jim
...
@@ -53,24 +54,26 @@ public class UploadProcessServiceImpl implements UploadProcessService {
...
@@ -53,24 +54,26 @@ public class UploadProcessServiceImpl implements UploadProcessService {
@SneakyThrows
@SneakyThrows
@Override
@Override
public
String
handle
(
String
object
,
Path
path
)
{
public
String
handle
(
String
object
,
MultipartFile
file
)
{
@Cleanup
FileInputStream
is
=
new
FileInputStream
(
path
.
toFile
());
String
suffix
=
FileUtil
.
getSuffix
(
object
);
String
suffix
=
FileUtil
.
getSuffix
(
object
);
// Image: 在文件名上追加图片物理像素
// Image: 在文件名上追加图片物理像素
if
(
isSupportiveImage
(
suffix
))
{
if
(
isSupportiveImage
(
suffix
))
{
@Cleanup
InputStream
is
=
file
.
getInputStream
();
object
=
handleImage
(
object
,
is
);
object
=
handleImage
(
object
,
is
);
}
}
// PDF: 在文件名上追加页数,同时在同目录生成 PDF 每一页的图片
// PDF: 在文件名上追加页数,同时在同目录生成 PDF 每一页的图片
if
(
isPdf
(
suffix
))
{
if
(
isPdf
(
suffix
))
{
@Cleanup
InputStream
is
=
file
.
getInputStream
();
object
=
handlePdf
(
object
,
is
);
object
=
handlePdf
(
object
,
is
);
}
}
// Video/Audio: 在文件名上追加时长,视频生成封面图
// Video/Audio: 在文件名上追加时长,视频生成封面图
if
(
isSupportiveMedia
(
suffix
))
{
if
(
isSupportiveMedia
(
suffix
))
{
object
=
handleMedia
(
object
,
suffix
,
path
);
object
=
handleMedia
(
object
,
suffix
,
file
);
}
}
return
object
;
return
object
;
...
@@ -84,6 +87,7 @@ public class UploadProcessServiceImpl implements UploadProcessService {
...
@@ -84,6 +87,7 @@ public class UploadProcessServiceImpl implements UploadProcessService {
@SneakyThrows
@SneakyThrows
public
String
handlePdf
(
String
object
,
InputStream
is
)
{
public
String
handlePdf
(
String
object
,
InputStream
is
)
{
@Cleanup
PDDocument
doc
=
PDDocument
.
load
(
is
);
PDDocument
doc
=
PDDocument
.
load
(
is
);
int
pages
=
doc
.
getNumberOfPages
();
int
pages
=
doc
.
getNumberOfPages
();
...
@@ -107,7 +111,7 @@ public class UploadProcessServiceImpl implements UploadProcessService {
...
@@ -107,7 +111,7 @@ public class UploadProcessServiceImpl implements UploadProcessService {
}
}
@SneakyThrows
@SneakyThrows
public
String
handleMedia
(
String
object
,
String
suffix
,
Path
path
)
{
public
String
handleMedia
(
String
object
,
String
suffix
,
MultipartFile
file
)
{
// 判断是否配置 ffmpeg 环境
// 判断是否配置 ffmpeg 环境
FFmpeg
ffmpeg
=
new
FFmpeg
();
FFmpeg
ffmpeg
=
new
FFmpeg
();
FFprobe
ffprobe
=
new
FFprobe
();
FFprobe
ffprobe
=
new
FFprobe
();
...
@@ -115,8 +119,13 @@ public class UploadProcessServiceImpl implements UploadProcessService {
...
@@ -115,8 +119,13 @@ public class UploadProcessServiceImpl implements UploadProcessService {
return
object
;
return
object
;
}
}
// 将上传的文件转存一份到本地临时目录
Path
tempFile
=
Paths
.
get
(
FileUtil
.
getTmpDirPath
(),
"T_"
+
Commons
.
uuid
(),
file
.
getOriginalFilename
());
FileUtil
.
mkParentDirs
(
tempFile
);
file
.
transferTo
(
tempFile
);
// 解析媒体文件
// 解析媒体文件
FFmpegProbeResult
probeResult
=
ffprobe
.
probe
(
path
.
toString
());
FFmpegProbeResult
probeResult
=
ffprobe
.
probe
(
tempFile
.
toString
());
FFmpegFormat
format
=
probeResult
.
getFormat
();
FFmpegFormat
format
=
probeResult
.
getFormat
();
// 构建具有时长(秒)标记的存储地址
// 构建具有时长(秒)标记的存储地址
...
@@ -126,33 +135,35 @@ public class UploadProcessServiceImpl implements UploadProcessService {
...
@@ -126,33 +135,35 @@ public class UploadProcessServiceImpl implements UploadProcessService {
// 视频截取首帧可见画面作为封面
// 视频截取首帧可见画面作为封面
if
(
isSupportiveVideo
(
suffix
))
{
if
(
isSupportiveVideo
(
suffix
))
{
// 使用 ffmpeg 截取视频首帧图片
// 使用 ffmpeg 截取视频首帧图片
Path
tempFile
=
Paths
.
get
(
path
.
getParent
().
toString
(),
FileUtil
.
getName
(
filepath
)
+
".jpg"
);
Path
path
=
Paths
.
get
(
tempFile
.
getParent
().
toString
(),
FileUtil
.
getName
(
filepath
)
+
".jpg"
);
FFmpegBuilder
builder
=
new
FFmpegBuilder
()
FFmpegBuilder
builder
=
new
FFmpegBuilder
()
.
setInput
(
path
.
toString
())
.
setInput
(
tempFile
.
toString
())
.
overrideOutputFiles
(
true
)
.
overrideOutputFiles
(
true
)
.
addOutput
(
tempFile
.
toString
())
.
addOutput
(
path
.
toString
())
.
setFrames
(
1
)
.
setFrames
(
1
)
.
done
();
.
done
();
FFmpegExecutor
executor
=
new
FFmpegExecutor
(
ffmpeg
,
ffprobe
);
FFmpegExecutor
executor
=
new
FFmpegExecutor
(
ffmpeg
,
ffprobe
);
executor
.
createJob
(
builder
).
run
();
executor
.
createJob
(
builder
).
run
();
// 判断封面图是否生成
// 判断封面图是否生成
if
(
Files
.
exists
(
tempFile
))
{
if
(
Files
.
exists
(
path
))
{
// 上传封面图
// 上传封面图
minio
.
putObject
(
tempFile
.
toFile
(),
getObjectFolder
(
filepath
));
minio
.
putObject
(
path
.
toFile
(),
getObjectFolder
(
filepath
));
}
}
// 大视频文件切片上传(> 5s)
// 大视频文件切片上传(> 5s)
if
(
sec
>
5
)
{
if
(
sec
>
5
)
{
filepath
=
handle
ToHls
(
filepath
,
path
,
ffmpeg
,
ffprobe
);
filepath
=
handle
VideoToHls
(
filepath
,
tempFile
,
ffmpeg
,
ffprobe
);
}
}
}
}
// 删除为本次上传进行本地处理所创建的整个临时文件夹目录
FileUtil
.
del
(
tempFile
.
getParent
());
return
filepath
;
return
filepath
;
}
}
@SneakyThrows
@SneakyThrows
public
String
handleToHls
(
String
object
,
Path
path
,
FFmpeg
ffmpeg
,
FFprobe
ffprobe
)
{
public
String
handle
Video
ToHls
(
String
object
,
Path
path
,
FFmpeg
ffmpeg
,
FFprobe
ffprobe
)
{
String
originName
=
FileUtil
.
getName
(
object
);
String
originName
=
FileUtil
.
getName
(
object
);
String
objectFolder
=
object
.
replace
(
"/"
+
originName
,
""
);
String
objectFolder
=
object
.
replace
(
"/"
+
originName
,
""
);
String
targetName
=
originName
.
replaceAll
(
"^(.*)\\."
+
FileUtil
.
getSuffix
(
originName
)
+
"$"
,
"$1.m3u8"
);
String
targetName
=
originName
.
replaceAll
(
"^(.*)\\."
+
FileUtil
.
getSuffix
(
originName
)
+
"$"
,
"$1.m3u8"
);
...
...
basic-common/minio/src/main/java/com/yiring/common/service/UploadProcessService.java
浏览文件 @
da209647
/* (C) 2022 YiRing, Inc. */
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
service
;
package
com
.
yiring
.
common
.
service
;
import
java.nio.file.Path
;
import
org.springframework.web.multipart.MultipartFile
;
/**
/**
* 文件上传媒体文件预处理服务
* 文件上传媒体文件预处理服务
...
@@ -19,10 +19,10 @@ public interface UploadProcessService {
...
@@ -19,10 +19,10 @@ public interface UploadProcessService {
* 视频封面:haha.mp4 -> haha.mp4.jpg 截取视频封面
* 视频封面:haha.mp4 -> haha.mp4.jpg 截取视频封面
*
*
* @param object 上传文件存储地址
* @param object 上传文件存储地址
* @param
path 文件地址
* @param
file 上传的文件
* @return 预处理后的文件地址(可能对文件名追加了时长、页数、分辨率等标识)
* @return 预处理后的文件地址(可能对文件名追加了时长、页数、分辨率等标识)
*/
*/
default
String
handle
(
String
object
,
Path
path
)
{
default
String
handle
(
String
object
,
MultipartFile
file
)
{
return
object
;
return
object
;
}
}
}
}
basic-common/minio/src/main/java/com/yiring/common/service/impl/FileManageServiceImpl.java
浏览文件 @
da209647
/* (C) 2023 YiRing, Inc. */
/* (C) 2023 YiRing, Inc. */
package
com
.
yiring
.
common
.
service
.
impl
;
package
com
.
yiring
.
common
.
service
.
impl
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.yiring.common.core.Minio
;
import
com.yiring.common.core.Minio
;
import
com.yiring.common.service.FileManageService
;
import
com.yiring.common.service.FileManageService
;
import
com.yiring.common.service.UploadProcessService
;
import
com.yiring.common.service.UploadProcessService
;
import
com.yiring.common.util.Commons
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -43,14 +39,8 @@ public class FileManageServiceImpl implements FileManageService {
...
@@ -43,14 +39,8 @@ public class FileManageServiceImpl implements FileManageService {
String
uuid
=
IdUtil
.
fastSimpleUUID
();
String
uuid
=
IdUtil
.
fastSimpleUUID
();
String
object
=
minio
.
buildUploadPath
(
filename
,
""
,
uuid
);
String
object
=
minio
.
buildUploadPath
(
filename
,
""
,
uuid
);
// 将上传的文件转存一份到本地临时目录
Path
tempFile
=
Paths
.
get
(
FileUtil
.
getTmpDirPath
(),
Commons
.
uuid
(),
filename
);
FileUtil
.
mkParentDirs
(
tempFile
);
file
.
transferTo
(
tempFile
);
// 预处理(默认不做任何处理,具体逻辑需自行在外部实现)
// 预处理(默认不做任何处理,具体逻辑需自行在外部实现)
object
=
service
.
handle
(
object
,
tempFile
);
object
=
service
.
handle
(
object
,
file
);
// 删除为本次上传进行本地处理所创建的整个临时文件夹目录
FileUtil
.
del
(
tempFile
.
getParent
());
// 上传原文件(如果是转换成了 m3u8 hls 文件则不保存原文件)
// 上传原文件(如果是转换成了 m3u8 hls 文件则不保存原文件)
String
suffix
=
".m3u8"
;
String
suffix
=
".m3u8"
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论