Files
MeBox/internal/model/strm.go
T
truewhile 0eb3f104f4 feat: Emby 远程挂载(联邦聚合)功能 beta
- 新增 emby_remote 提供方:通过 STRM 账号体系配置远程 Emby 地址/用户名/密码
- EmbyService 聚合远程媒体库 Views/Items/详情/最近添加/全局搜索,远程数据不落库
- 条目 ID 统一伪装为 embyremote~{account}~{id},请求按账号路由回远程
- 播放支持账号级 proxy_play 配置:默认客户端直连远程;开启后由 MMTL 反向代理流/字幕
- 图片/元数据全部实时透传远程,播放状态(已看/收藏)透传回远程 Emby
- cloud 包新增 emby Provider(Ping/List/Resolve),账号测试/目录浏览自动生效
- 前端 STRM 页面支持 Emby 远程挂载账号(地址+凭据+代理开关)
2026-09-01 10:44:01 +08:00

144 lines
7.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// STRM 管理子系统数据模型。
//
// 参考 QMediaSync 的 STRM 同步设计:网盘账号(account)+ 同步目录(sync path)
// 生成 .strm 文件(内容为指向本服务播放端点的一行 URL),视频元数据文件经
// 下载/上传队列与远端网盘双向同步。
package model
import "time"
// Strm 提供方类型。cloud.Local 常量保持一致。
const (
StrmProvider115 = "cloud115" // 115 网盘(Cookie + 二维码登录)
StrmProviderCloudDrive = "clouddrive2" // CloudDrive2(WebDAV 桥接)
StrmProviderOpenList = "openlist" // OpenList / AList 兼容桥接
StrmProviderLocal = "local" // 本地目录(无账号)
StrmProviderEmbyRemote = "emby_remote" // 远程 Emby 服务器(API 网关聚合挂载,不走 STRM 同步)
)
// StrmAccount 是一个网盘账号(STRM 同步数据源凭据)。
type StrmAccount struct {
Base
Name string `gorm:"size:128" json:"name"` // 展示名
Provider string `gorm:"size:32;index" json:"provider"` // StrmProvider*
Config string `gorm:"type:text" json:"-"` // JSON:cookie / url / username / password / token
Enabled bool `gorm:"default:true" json:"enabled"` // 是否启用(禁用后同步跳过)
LastTestAt *time.Time `json:"last_test_at"` // 最近一次连通性测试
LastTestResult string `gorm:"size:512" json:"last_test_result"` // ok 或错误信息
LastTestOK bool `json:"last_test_ok"`
}
// StrmSyncPath 是一条 STRM 同步目录配置:把网盘(或本地)某目录下的视频生成
// .strm 文件写到 LocalPath,元数据按需下载/上传。
type StrmSyncPath struct {
Base
Name string `gorm:"size:128" json:"name"` // 展示名
AccountID string `gorm:"size:36;index" json:"account_id"` // StrmAccount.ID;local 为空
Provider string `gorm:"size:32" json:"provider"` // StrmProvider*(冗余,便于列表展示)
RemotePath string `gorm:"size:1024" json:"remote_path"` // 远端目录:115=目录ID,OpenList/CD2=路径,local=源目录
LocalPath string `gorm:"size:1024" json:"local_path"` // STRM/元数据本地输出目录
// STRM 链接配置(空值继承全局 strm.* 设置)
StrmBaseURL string `gorm:"size:512" json:"strm_base_url"` // 覆盖 strm.base_url
VideoExt string `gorm:"size:512" json:"video_ext"` // 逗号分隔,覆盖 strm.video_ext
MetaExt string `gorm:"size:512" json:"meta_ext"` // 逗号分隔,覆盖 strm.meta_ext
ExcludeName string `gorm:"size:512" json:"exclude_name"` // 逗号分隔,文件名包含即跳过
MinVideoSizeMB int64 `json:"min_video_size_mb"` // 小于该大小(MB)的视频不生成 STRM
AddPath int `json:"add_path"` // STRM 链接 path 参数:1=完整远端路径 2=仅文件名 3=不带
DownloadMeta bool `gorm:"default:true" json:"download_meta"` // 同步时下载元数据文件(nfo/图片/字幕)
UploadMeta bool `json:"upload_meta"` // 同步时把本地元数据上传到远端
DeleteDir bool `json:"delete_dir"` // 清理多余文件时删除空目录
Cron string `gorm:"size:128" json:"cron"` // 5 段 cron 表达式(可选)
EnableCron bool `json:"enable_cron"` // 是否按 Cron 定时同步
SyncMode string `gorm:"size:32;default:'incremental'" json:"sync_mode"` // 默认同步模式:incremental / full
Enabled bool `gorm:"default:true" json:"enabled"`
LastSyncAt *time.Time `json:"last_sync_at"`
LastSyncStatus string `gorm:"size:16" json:"last_sync_status"` // idle/running/ok/error/canceled
LastSyncMessage string `gorm:"size:1024" json:"last_sync_message"`
}
// STRM 同步类型。
const (
StrmSyncTypeIncremental = "incremental"
StrmSyncTypeFull = "full"
)
// StrmSyncRecord 是一次同步执行的记录。
const (
StrmSyncRecordPending = "pending"
StrmSyncRecordRunning = "running"
StrmSyncRecordDone = "done"
StrmSyncRecordFailed = "failed"
StrmSyncRecordCanceled = "canceled"
)
type StrmSyncRecord struct {
Base
SyncPathID string `gorm:"size:36;index" json:"sync_path_id"`
SyncType string `gorm:"size:32;default:'incremental'" json:"sync_type"` // incremental / full
Status string `gorm:"size:16;index" json:"status"`
Total int64 `json:"total"` // 远端发现的文件总数
NewStrm int64 `json:"new_strm"` // 本次新建/更新的 strm 数
NewMeta int64 `json:"new_meta"` // 本次入队的元数据下载数
Uploaded int64 `json:"uploaded"` // 本次入队的上传数
Pruned int64 `json:"pruned"` // 本次清理的本地多余文件数
Skipped int64 `json:"skipped"` // 内容未变化跳过的 strm 数
Message string `gorm:"size:1024" json:"message"`
StartedAt *time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at"`
}
// STRM 任务状态。
const (
StrmTaskPending = "pending"
StrmTaskRunning = "running"
StrmTaskDone = "done"
StrmTaskFailed = "failed"
StrmTaskCanceled = "canceled"
)
// StrmDownloadTask 是 strm 元数据下载队列任务(远端网盘 → 本地)。
type StrmDownloadTask struct {
Base
SyncPathID string `gorm:"size:36;index" json:"sync_path_id"`
AccountID string `gorm:"size:36;index" json:"account_id"`
Provider string `gorm:"size:32" json:"provider"`
FileName string `gorm:"size:512" json:"file_name"`
RemoteRef string `gorm:"size:1024" json:"remote_ref"` // 远端文件引用(pickcode / 路径)
RemoteDir string `gorm:"size:1024" json:"remote_dir"`
LocalPath string `gorm:"size:1024" json:"local_path"` // 本地目标文件
Size int64 `json:"size"`
Status string `gorm:"size:16;index" json:"status"`
Error string `gorm:"size:1024" json:"error"`
RetryCount int `json:"retry_count"`
NextTryAt *time.Time `json:"next_try_at"` // 失败重试退避;空或已过则可被认领
StartedAt *time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at"`
}
// StrmUploadTask 是 strm 元数据上传队列任务(本地 → 远端网盘)。
type StrmUploadTask struct {
Base
SyncPathID string `gorm:"size:36;index" json:"sync_path_id"`
AccountID string `gorm:"size:36;index" json:"account_id"`
Provider string `gorm:"size:32" json:"provider"`
FileName string `gorm:"size:512" json:"file_name"`
LocalPath string `gorm:"size:1024" json:"local_path"` // 本地源文件
RemotePath string `gorm:"size:1024" json:"remote_path"` // 远端目标路径
Size int64 `json:"size"`
Status string `gorm:"size:16;index" json:"status"`
Error string `gorm:"size:1024" json:"error"`
RetryCount int `json:"retry_count"`
NextTryAt *time.Time `json:"next_try_at"` // 失败重试退避;空或已过则可被认领
StartedAt *time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at"`
}
// StrmDirCache 缓存远端网盘目录 ID 与相对路径映射(支持 115 增量同步秒级寻址)。
type StrmDirCache struct {
Base
SyncPathID string `gorm:"size:36;index:idx_strm_dir_cache,priority:1" json:"sync_path_id"`
DirID string `gorm:"size:128;index:idx_strm_dir_cache,priority:2" json:"dir_id"`
Path string `gorm:"size:1024" json:"path"` // 相对根目录的路径
}