camera.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package parking
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/url"
  6. "strings"
  7. "wails-app/internal/dao"
  8. "wails-app/internal/global"
  9. )
  10. // CameraStreamOption 是工作台使用的安全摄像头信息,不包含用户名和密码。
  11. type CameraStreamOption struct {
  12. DeviceCode string `json:"device_code"`
  13. DeviceName string `json:"device_name"`
  14. ChannelID uint `json:"channel_id"`
  15. ChannelCode string `json:"channel_code"`
  16. ChannelName string `json:"channel_name"`
  17. Protocol string `json:"protocol"`
  18. PlayURL string `json:"play_url"`
  19. SnapshotURL string `json:"snapshot_url"`
  20. Status string `json:"status"`
  21. Online bool `json:"online"`
  22. }
  23. // ListCameraStreams 返回启用摄像头的浏览器播放配置,并按通道绑定到道闸设备。
  24. func (s *PassageService) ListCameraStreams() ([]CameraStreamOption, error) {
  25. if global.GVA_DB == nil {
  26. return nil, errors.New("数据库未初始化")
  27. }
  28. var cameras []dao.Camera
  29. if err := global.GVA_DB.Preload("BoundChannel").Where("is_active = ?", true).
  30. Order("device_name ASC").Find(&cameras).Error; err != nil {
  31. return nil, err
  32. }
  33. options := make([]CameraStreamOption, 0, len(cameras))
  34. for _, camera := range cameras {
  35. protocol := camera.StreamProtocol
  36. if protocol == "" {
  37. protocol = "webrtc"
  38. }
  39. playURL := camera.StreamURL
  40. systemConversionEnabled := strings.ToLower(strings.TrimSpace(global.GVA_CONFIG.Camera.ConversionMode)) != "edge"
  41. if systemConversionEnabled && isSystemMJPEG(protocol) {
  42. token := issueCameraStreamToken(camera.DeviceCode)
  43. prefix := global.GVA_CONFIG.System.RouterPrefix
  44. if prefix == "" {
  45. prefix = "/api"
  46. }
  47. playURL = fmt.Sprintf("%s/parking/camera/stream/%s/%s", strings.TrimRight(prefix, "/"), url.PathEscape(camera.DeviceCode), token)
  48. protocol = "mjpeg"
  49. } else if isSystemMJPEG(protocol) {
  50. // 切到 edge 模式后,沿用数据库中的 StreamURL(由边缘或外部媒体网关提供)。
  51. protocol = "webrtc"
  52. }
  53. status := camera.Status
  54. if status == "" {
  55. status = "offline"
  56. }
  57. options = append(options, CameraStreamOption{
  58. DeviceCode: camera.DeviceCode,
  59. DeviceName: camera.DeviceName,
  60. ChannelID: camera.ChannelID,
  61. ChannelCode: cameraChannelCode(camera.BoundChannel),
  62. ChannelName: cameraChannelName(camera.BoundChannel),
  63. Protocol: protocol,
  64. PlayURL: playURL,
  65. SnapshotURL: camera.SnapshotURL,
  66. Status: status,
  67. Online: camera.Status == "online" || camera.Status == "connected",
  68. })
  69. }
  70. return options, nil
  71. }
  72. func cameraChannelCode(channel *dao.Channel) string {
  73. if channel == nil {
  74. return ""
  75. }
  76. return channel.ChannelCode
  77. }
  78. func cameraChannelName(channel *dao.Channel) string {
  79. if channel == nil {
  80. return ""
  81. }
  82. return channel.ChannelName
  83. }