feat(core): 添加PSD/PSB图片格式支持并重构媒体文件处理
- 新增ReadPsdImage函数支持PSD/PSB格式图片信息读取 - 修改文件扫描逻辑,将视频处理改为媒体候选处理,使用ffprobe统一判定 - 添加对PSB格式的支持,与PSD共享相同8BPS文件头处理 - 重构handle_image.go中的图片处理逻辑,优化错误处理和记录保存 - 更新文件扫描过滤规则,支持更多图片格式并跳过数据库文件 - 添加文件MD5计算功能用于文件唯一性标识 - 修改媒体处理流程,支持音频文件识别和分类处理 - 移除废弃的视频时长转换函数和相关依赖 - 更新依赖版本并添加SQLite支持用于媒体信息存储
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
sqlite "github.com/glebarez/go-sqlite"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// DBFileName 数据库文件名(存放于被整理目录的根目录,扫描时跳过)
|
||||
const DBFileName = "media-info.db"
|
||||
|
||||
// init 将纯Go的sqlite驱动注册为 xorm 认识的 sqlite3 驱动名(避免CGO依赖)
|
||||
func init() {
|
||||
sql.Register("sqlite3", &sqlite.Driver{})
|
||||
}
|
||||
|
||||
// MediaInfo 媒体文件信息记录,按字段拆分存放,便于查询
|
||||
type MediaInfo struct {
|
||||
Id int64 `xorm:"pk autoincr 'id'"`
|
||||
FileMd5 string `xorm:"char(32) index 'file_md5'"` // 文件MD5,唯一标识
|
||||
FilePath string `xorm:"text 'file_path'"` // 扫描时的源路径
|
||||
FileName string `xorm:"varchar(255) 'file_name'"` // 文件名(含扩展名)
|
||||
FileExt string `xorm:"varchar(32) 'file_ext'"` // 扩展名
|
||||
FileSize int64 `xorm:"bigint 'file_size'"` // 文件大小(字节)
|
||||
MimeType string `xorm:"varchar(128) 'mime_type'"` // MIME类型
|
||||
MediaType string `xorm:"varchar(16) index 'media_type'"` // image/video/audio
|
||||
Width int `xorm:"int index 'width'"` // 宽(像素)
|
||||
Height int `xorm:"int index 'height'"` // 高(像素)
|
||||
Duration float64 `xorm:"real 'duration'"` // 时长(秒)
|
||||
Codec string `xorm:"varchar(64) 'codec'"` // 视频编码,如h264/hevc
|
||||
Format string `xorm:"varchar(64) 'format'"` // 容器格式,如mp4/mkv
|
||||
RawInfo string `xorm:"text 'raw_info'"` // ffprobe原始JSON(完整信息兜底)
|
||||
CreatedAt time.Time `xorm:"created 'created_at'"` // 首次入库时间
|
||||
UpdatedAt time.Time `xorm:"updated 'updated_at'"` // 最近更新时间
|
||||
}
|
||||
|
||||
var engine *xorm.Engine
|
||||
|
||||
// Init 初始化数据库引擎并同步表结构
|
||||
func Init(dbPath string) error {
|
||||
e, err := xorm.NewEngine("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.ShowSQL(false)
|
||||
e.SetMaxOpenConns(1) // sqlite同一时刻只允许一个写连接
|
||||
engine = e
|
||||
return engine.Sync(new(MediaInfo))
|
||||
}
|
||||
|
||||
// Close 关闭数据库连接
|
||||
func Close() error {
|
||||
if engine != nil {
|
||||
err := engine.Close()
|
||||
engine = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveMedia 按MD5去重保存/更新媒体信息
|
||||
func SaveMedia(info *MediaInfo) error {
|
||||
if engine == nil {
|
||||
return nil
|
||||
}
|
||||
existing := new(MediaInfo)
|
||||
has, err := engine.Where("file_md5 = ?", info.FileMd5).Get(existing)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if has {
|
||||
info.Id = existing.Id
|
||||
_, err = engine.ID(existing.Id).Update(info)
|
||||
return err
|
||||
}
|
||||
_, err = engine.Insert(info)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user