feat(core): 优化媒体文件扫描和处理功能
- 添加跳过ffprobe相关文件的逻辑,避免处理临时释放文件 - 修复图片处理中的变量引用错误 - 实现大文件指纹复用机制,避免重复全量读取计算MD5 - 新增文件头尾采样指纹算法,提升大文件处理性能 - 重构ffprobe内嵌资源管理,支持多平台自动选择对应版本 - 添加媒体信息数据库的指纹索引和去向跟踪功能 - 优化程序启动流程,失败时跳过媒体整理但保留图片处理 - 更新文档说明多平台ffprobe支持和构建要求
This commit is contained in:
@@ -87,6 +87,9 @@ func visit(currentPath string, info os.FileInfo, err error) error {
|
||||
if filepath.Base(currentPath) == store.DBFileName {
|
||||
return nil // 跳过媒体信息数据库文件
|
||||
}
|
||||
if filepath.Base(currentPath) == util.FFprobeExeName || filepath.Base(currentPath) == "ffprobe_mac" {
|
||||
return nil // 跳过ffprobe相关文件(中断残留的释放文件 / vars/bin内嵌源文件)
|
||||
}
|
||||
vars.GlobalFilePathList = append(vars.GlobalFilePathList, currentPath)
|
||||
// filename, include ext
|
||||
vars.GlobalFilePath2FileNameMap[currentPath] = filepath.Base(currentPath)
|
||||
|
||||
@@ -117,7 +117,7 @@ func DoHandleImage(pickerDir string) {
|
||||
|
||||
// 条件图片并分组存放
|
||||
func doPickImageFile(pickerDir string, imagePath2WidthHeightMap map[string]string) {
|
||||
if len(vars.ImagePath2WidthHeightMap) == 0 {
|
||||
if len(imagePath2WidthHeightMap) == 0 {
|
||||
fmt.Printf("=== 当前目录下没有扫描到图片文件, %s \n", pickerDir)
|
||||
return
|
||||
}
|
||||
|
||||
+25
-6
@@ -8,18 +8,38 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// saveMediaRecord 计算MD5并将媒体信息写入数据库
|
||||
// saveMediaRecord 将媒体信息写入数据库;大文件优先用指纹(头尾采样)复用已入库的MD5,避免全量读取
|
||||
func saveMediaRecord(filePath string, mediaType string, width int, height int, duration float64, codec string, format string, rawInfo string) {
|
||||
md5Str, err := util.CalcFileMd5(filePath)
|
||||
st, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
fmt.Printf("=== 计算MD5失败: %s, 错误: %v\n", filePath, err)
|
||||
fmt.Printf("=== 读取文件信息失败: %s, 错误: %v\n", filePath, err)
|
||||
return
|
||||
}
|
||||
size := st.Size()
|
||||
|
||||
md5Str := ""
|
||||
headMd5, tailMd5 := "", ""
|
||||
if size > util.FingerprintThreshold {
|
||||
if head, tail, ferr := util.CalcFileFingerprint(filePath, size); ferr == nil {
|
||||
headMd5, tailMd5 = head, tail
|
||||
if existing, ok := store.FindMediaByFingerprint(size, head, tail); ok && existing.FileMd5 != "" {
|
||||
md5Str = existing.FileMd5 // 指纹命中,复用MD5,跳过全量读取
|
||||
}
|
||||
}
|
||||
}
|
||||
if md5Str == "" {
|
||||
if md5Str, err = util.CalcFileMd5(filePath); err != nil {
|
||||
fmt.Printf("=== 计算MD5失败: %s, 错误: %v\n", filePath, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
info := &store.MediaInfo{
|
||||
FileMd5: md5Str,
|
||||
FilePath: filePath,
|
||||
FileName: vars.GlobalFilePath2FileNameMap[filePath],
|
||||
FileExt: vars.GlobalFilePath2FileExtMap[filePath],
|
||||
FileSize: size,
|
||||
MimeType: vars.GlobalFilePath2MimeInfoMap[filePath],
|
||||
MediaType: mediaType,
|
||||
Width: width,
|
||||
@@ -28,9 +48,8 @@ func saveMediaRecord(filePath string, mediaType string, width int, height int, d
|
||||
Codec: codec,
|
||||
Format: format,
|
||||
RawInfo: rawInfo,
|
||||
}
|
||||
if st, err := os.Stat(filePath); err == nil {
|
||||
info.FileSize = st.Size()
|
||||
HeadMd5: headMd5,
|
||||
TailMd5: tailMd5,
|
||||
}
|
||||
if err := store.SaveMedia(info); err != nil {
|
||||
fmt.Printf("=== 保存媒体信息失败: %s, 错误: %v\n", filePath, err)
|
||||
|
||||
Reference in New Issue
Block a user