feat(core): 优化媒体文件扫描和处理功能

- 添加跳过ffprobe相关文件的逻辑,避免处理临时释放文件
- 修复图片处理中的变量引用错误
- 实现大文件指纹复用机制,避免重复全量读取计算MD5
- 新增文件头尾采样指纹算法,提升大文件处理性能
- 重构ffprobe内嵌资源管理,支持多平台自动选择对应版本
- 添加媒体信息数据库的指纹索引和去向跟踪功能
- 优化程序启动流程,失败时跳过媒体整理但保留图片处理
- 更新文档说明多平台ffprobe支持和构建要求
This commit is contained in:
2025-03-21 21:00:59 +08:00
parent b276e8c56f
commit 066e28a2d6
16 changed files with 156 additions and 45 deletions
+25 -6
View File
@@ -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)