feat: 设备管理页导出所有设备的视频流地址CSV
This commit is contained in:
parent
425bf2ca92
commit
ac305f3106
@ -773,6 +773,7 @@ func (u *UI) Routes() (chi.Router, error) {
|
||||
r.Post("/wizard/create-source", u.actionWizardCreateSource)
|
||||
r.Get("/devices", u.pageDevices)
|
||||
r.Post("/devices/cleanup-offline", u.actionDevicesCleanupOffline)
|
||||
r.Get("/devices/export-channels", u.actionDevicesExportChannels)
|
||||
r.Get("/devices/{id}/control", u.pageDeviceControl)
|
||||
r.Get("/plans", u.redirectPlansToSceneTemplates)
|
||||
r.Get("/plans/{name}", u.redirectPlanToSceneTemplate)
|
||||
@ -1667,6 +1668,52 @@ func (u *UI) actionDevicesCleanupOffline(w http.ResponseWriter, r *http.Request)
|
||||
http.Redirect(w, r, "/devices?msg="+urlQueryEscape(fmt.Sprintf("已清理 %d 台离线设备", deleted)), http.StatusFound)
|
||||
}
|
||||
|
||||
func (u *UI) actionDevicesExportChannels(w http.ResponseWriter, r *http.Request) {
|
||||
u.ensureDevicesLoaded()
|
||||
devices := u.registry.GetDevices()
|
||||
|
||||
w.Header().Set("Content-Type", "text/csv; charset=utf-8")
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=video_channels.csv")
|
||||
w.Write([]byte("\xef\xbb\xbf"))
|
||||
w.Write([]byte("设备名,IP,通道名,视频源,RTSP地址,HLS地址\n"))
|
||||
|
||||
if u.preview == nil {
|
||||
return
|
||||
}
|
||||
units, _ := u.preview.ListRecognitionUnits()
|
||||
for _, unit := range units {
|
||||
// Find which device this unit is assigned to
|
||||
devName := ""
|
||||
devIP := ""
|
||||
for _, dev := range devices {
|
||||
if dev == nil {
|
||||
continue
|
||||
}
|
||||
if assignment, err := u.preview.GetDeviceAssignment(dev.DeviceID); err == nil && assignment != nil {
|
||||
for _, ref := range assignment.RecognitionUnits {
|
||||
if ref == unit.Ref {
|
||||
devName = dev.DisplayName()
|
||||
devIP = dev.IP
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if devName != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
rtspPort := unit.RTSPPort
|
||||
if rtspPort == "" {
|
||||
rtspPort = "8555"
|
||||
}
|
||||
rtsp := fmt.Sprintf("rtsp://%s:%s/live/%s", devIP, rtspPort, unit.Name)
|
||||
hls := fmt.Sprintf("http://%s:9000/hls/%s/index.m3u8", devIP, unit.Name)
|
||||
fmt.Fprintf(w, "%s,%s,%s,%s,%s,%s\n",
|
||||
escapeCSV(devName), escapeCSV(devIP), escapeCSV(unit.Name),
|
||||
escapeCSV(unit.VideoSourceRef), escapeCSV(rtsp), escapeCSV(hls))
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UI) pageDeviceAdd(w http.ResponseWriter, r *http.Request) {
|
||||
u.render(w, r, "device_add", PageData{Title: "新增设备"})
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
{{end}}
|
||||
<button type="submit" id="time-sync-btn" name="action" value="time_sync" class="secondary" style="display:none">⏱ 时间同步</button>
|
||||
<a class="btn secondary" href="{{.BatchConfigURL}}">下发设备分配</a>
|
||||
<a class="btn secondary" href="/devices/export-channels">导出视频地址</a>
|
||||
<a class="btn secondary" href="/devices">清空选择</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user