修复 ai 设置被覆盖问题

This commit is contained in:
xugo
2026-03-12 14:53:54 +08:00
parent 8f0f501eca
commit 475980ef9e
4 changed files with 30 additions and 25 deletions
+6
View File
@@ -141,6 +141,12 @@ postgres 和 mysql 的格式即:
开启分析后,每路流占用约 200MB 内存 2 核
注意:开启 AI 分析后,即使没有人观看,系统也会自动保持视频流不关闭以确保 AI 持续分析。
> 为什么开启 AI 分析后,即是没人观看,流也不会自动停止
ai 分析会拉取一道流,程序会以为有人观看
> 国标设备在线,通道离线?
属于 ipc 的问题,请检查 ipc 后台注册的 平台 sip_id 和 域是否与 gowvp/owl 一致。
+7 -17
View File
@@ -36,24 +36,14 @@
# 录像存储根目录(相对于工作目录)
StorageDir = './configs/recordings'
# 录像保留天数(超过则清理)
RetainDays = 7
RetainDays = 3
# 磁盘使用率阈值(百分比),超过则触发循环覆盖
DiskUsageThreshold = 99.0
DiskUsageThreshold = 95.0
# MP4 切片时长(秒)
SegmentSeconds = 60
# 是否禁用 GB28181 通道录制(true=禁用)
DisabledGB28181 = false
# 是否禁用 RTMP 通道录制(true=禁用)
DisabledRTMP = false
# 是否禁用 RTSP 通道录制(true=禁用)
DisabledRTSP = false
# 是否禁用 ONVIF 通道录制(true=禁用)
DisabledONVIF = false
SegmentSeconds = 300
[Data]
# 数据库支持 sqlite/postgres/mysql, 使用 sqlite 时 dsn 应当填写文件存储路径
# postgres://postgres:123456@127.0.0.1:5432/gb28181?sslmode=disable
# mysql://root:123456@127.0.0.1:5432/gb28181?sslmode=disable
[Data.Database]
Dsn = './configs/data.db'
MaxIdleConns = 10
@@ -77,9 +67,9 @@
# 服务监听的 tcp/udp 端口号
Port = 15060
# gb/t28181 20 位国标 ID
ID = '34020000002000000001'
ID = '34030000002000000003'
# 域
Domain = '3402000000'
Domain = '3403000000'
# 注册密码
Password = ''
@@ -93,8 +83,8 @@
# 媒体服务器类型 zlm/lalmax
Type = 'zlm'
# 用于流媒体 webhook 回调
WebHookIP = '192.168.1.3'
WebHookIP = '192.168.1.5'
# 媒体服务器 RTP 端口范围
RTPPortRange = '20000-20100'
# 媒体服务器 SDP IP
SDPIP = '192.168.1.3'
SDPIP = '192.168.1.5'
+5 -6
View File
@@ -156,15 +156,14 @@ func (g Adapter) SaveChannels(channels []*Channel) error {
currentChannelIDs = append(currentChannelIDs, channel.ChannelID)
if existing, ok := existingMap[channel.ChannelID]; ok {
// 通道已存在,更新信息
// 只更新设备上报的字段,保留用户手动配置的 EnabledAI / Zones / RecordMode
_ = g.store.Channel().Edit(ctx, existing, func(c *Channel) error {
c.Name = channel.Name
c.IsOnline = channel.IsOnline
// TODO: 这里需要优化,更新的时候不应该覆盖上次的存储配置
recordMode := channel.Ext.GetRecordMode()
c.Ext = channel.Ext
c.Ext.RecordMode = recordMode
c.Ext.Manufacturer = channel.Ext.Manufacturer
c.Ext.Firmware = channel.Ext.Firmware
c.Ext.GBVersion = channel.Ext.GBVersion
c.Ext.Model = channel.Ext.Model
return nil
}, orm.Where("id=?", existing.ID))
} else {
+12 -2
View File
@@ -163,9 +163,18 @@ func (a AIWebhookAPI) onStopped(c *gin.Context, in *AIStoppedInput) (AIWebhookOu
return newAIWebhookOutputOK(), nil
}
// StartAISyncLoop 启动 AI 任务同步协程,每 5 分钟检测一次数据库中 enabled_ai 状态与内存 aiTasks 的差异并同步
// StartAISyncLoop 启动 AI 任务同步协程,启动后立即执行一次同步,之后每 5 分钟检测一次
// 立即执行是为了在服务重启后尽快恢复之前开启的 AI 分析任务
func (a *AIWebhookAPI) StartAISyncLoop(ctx context.Context, smsCore sms.Core) {
go func() {
// 延迟 30 秒再首次同步,等待设备注册和 catalog 更新完成,避免读到过期状态
select {
case <-ctx.Done():
return
case <-time.After(30 * time.Second):
a.syncAITasks(ctx, smsCore)
}
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()
@@ -187,9 +196,10 @@ func (a *AIWebhookAPI) syncAITasks(ctx context.Context, smsCore sms.Core) {
return
}
// 查询所有通道
// 查询所有在线通道
channels, _, err := a.ipcCore.FindChannel(ctx, &ipc.FindChannelInput{
PagerFilter: web.PagerFilter{Page: 1, Size: 999},
IsOnline: "true",
})
if err != nil {
a.log.ErrorContext(ctx, "sync ai tasks: find channels failed", "err", err)