blakeblackshear / frigate

NVR with realtime local object detection for IP cameras
https://frigate.video
MIT License
19.04k stars 1.74k forks source link

Unable to View Live Stream with RC-1 #1631

Closed TheFuzz4 closed 3 years ago

TheFuzz4 commented 3 years ago

Describe the bug When clicking on a camera the live stream just shows a white or black box that then flashes Version of frigate Output from /api/version

Config file Include your full config file wrapped in triple back ticks.

logger:
  default: debug

mqtt:
  host: 192.168.7.42
  port: 1883
  topic_prefix: frigate
  stats_interval: 60

database:
  path: /media/frigate/database/frigate.db

ffmpeg:
  # Optional: global ffmpeg args (default: shown below)
  global_args: -hide_banner -loglevel warning
  # Optional: global hwaccel args (default: shown below)
  # Optional: global input args (default: shown below)
  input_args: -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -stimeout 5000000 -use_wallclock_as_timestamps 1
  # Optional: global output args
  output_args:
    # Optional: output args for detect streams (default: shown below)
    detect: -f rawvideo -pix_fmt yuv420p
    # Optional: output args for record streams (default: shown below)
    record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an
    # Optional: output args for rtmp streams (default: shown below)
    rtmp: -c copy -f flv

record:
  # Optional: Enable recording (default: shown below)
  enabled: True
  # Optional: Number of days to retain (default: shown below)
  retain_days: 0
  # Optional: Event recording settings
  events:
    # Optional: Enable event recording retention settings (default: shown below)
    enabled: False
    # Optional: Maximum length of time to retain video during long events. (default: shown below)
    # NOTE: If an object is being tracked for longer than this amount of time, the cache
    #       will begin to expire and the resulting clip will be the last x seconds of the event unless retain_days under record is > 0.
    max_seconds: 300
    # Optional: Number of seconds before the event to include in the event (default: shown below)
    pre_capture: 5
    # Optional: Number of seconds after the event to include in the event (default: shown below)
    post_capture: 5
    # Optional: Retention settings for event
    retain:
      # Required: Default retention days (default: shown below)
      default: 10
      # Optional: Per object retention days
      objects:
        person: 15

cameras:
  Driveway:
    ffmpeg:
      input_args:
        - -avoid_negative_ts
        - make_zero
        - -fflags
        - nobuffer
        - -flags
        - low_delay
        - -strict
        - experimental
        - -fflags
        - +genpts+discardcorrupt
        - -rw_timeout
        - "5000000"
        - -use_wallclock_as_timestamps
        - "1"
      output_args:
        record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtmp://192.168.5.7:1935/bcs/channel0_main.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - record
        - path: rtmp://192.168.5.7:1935/bcs/channel0_sub.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      FrontDriveway:
        coordinates: 413,243,368,309,415,323,432,480,0,480,0,346,0,298,61,266,203,226
      Street:
        coordinates: 108,186,72,167,90,141,184,116,410,112,525,112,561,133,640,176,640,255,533,248,413,241,295,231,203,214
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
      required_zones: [FrontDriveway]
    objects:
      track:
        - person
        - cat
        - dog
        - car
        - bicycle
        - motorcycle
  OutsideFrontDoor:
    ffmpeg:
      input_args:
        - -avoid_negative_ts
        - make_zero
        - -fflags
        - nobuffer
        - -flags
        - low_delay
        - -strict
        - experimental
        - -fflags
        - +genpts+discardcorrupt
        - -rw_timeout
        - "5000000"
        - -use_wallclock_as_timestamps
        - "1"
      output_args:
        record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtmp://192.168.5.12:1935/bcs/channel0_main.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - record
        - path: rtmp://192.168.5.12:1935/bcs/channel0_sub.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      FrontDoor:
        coordinates: 72,195,158,303,192,353,147,480,0,480,0,346,0,298,0,268,0,187
      FrontSideWalk:
        coordinates: 269,301,190,321,158,291,147,277,227,229,292,202,362,193,458,185,521,210,640,266,640,422,425,331,348,310
      SideDriveway:
        coordinates: 640,203,640,312,68,183,69,111
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
        - cat
        - dog
  FrontDoorbell:
    ffmpeg:
      inputs:
        - path: rtsp://user:password@192.168.7.17:554/mpeg/media.amp
          roles:
          - record
          - detect
          - rtmp
    detect:
      width: 1280
      height: 720
      fps: 5
    live:
      height: 480
      quality: 8
    motion:
      mask:
      - 251,396,1041,387,1031,279,259,276
    zones:
      FrontDoor:
        coordinates: 561,563,606,511,537,498,492,486,463,478,486,458,564,445,620,437,685,432,766,422,918,382,1042,370,1044,503,1036,556,1075,720,485,720
      SideDriveway:
        coordinates: 608,509,436,542,379,548,0,582,0,453
        filters:
          person:
            threshold: 0.7
          car:
            threshold: 0.7
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
  LivingRoom1:
    ffmpeg:
      inputs:
        - path: rtsp://admin:Password@192.168.71.109:554/11
          roles:
          - record
        - path: rtsp://admin:Password@192.168.71.109:554/12
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 352
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      LivingRoom:
        coordinates: 165,352,640,352,640,71,364,0,287,31,144,90
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
  Office1:
    ffmpeg:
      input_args:
        - -avoid_negative_ts
        - make_zero
        - -fflags
        - nobuffer
        - -flags
        - low_delay
        - -strict
        - experimental
        - -fflags
        - +genpts+discardcorrupt
        - -rw_timeout
        - "5000000"
        - -use_wallclock_as_timestamps
        - "1"
      output_args:
        record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtmp://192.168.5.6:1935/bcs/channel0_main.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - record
        - path: rtmp://192.168.5.6:1935/bcs/channel0_sub.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      Office:
        coordinates: 640,0,640,362,640,480,0,480,0,0
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
        - dog
  BackFence1:
    ffmpeg:
      input_args:
        - -avoid_negative_ts
        - make_zero
        - -fflags
        - nobuffer
        - -flags
        - low_delay
        - -strict
        - experimental
        - -fflags
        - +genpts+discardcorrupt
        - -rw_timeout
        - "5000000"
        - -use_wallclock_as_timestamps
        - "1"
      output_args:
        record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtmp://192.168.5.10:1935/bcs/channel0_main.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - record
        - path: rtmp://192.168.5.10:1935/bcs/channel0_sub.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      BackSideWalk:
        coordinates: 417,85,410,177,348,328,268,480,55,480,61,397,193,323,252,219,371,106
    motion:
      mask:
      - 0,83,127,57,263,34,384,92,0,389
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
        - cat
        - dog
        - car
        - bicycle
        - motorcycle
  DiningRoom:
    ffmpeg:
      inputs:
        - path: rtsp://user:Password@192.168.5.5:88/Streaming/Channels/1
          roles:
          - record
        - path: rtsp://user:Password@192.168.5.5:88/Streaming/Channels/2
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    motion:
      mask:
      - 427,0,428,36,334,37,344,83,151,109,136,0
    zones:
      DiningRoomZone:
        coordinates: 578,236,640,480,369,480,216,480,0,480,0,128,109,76,226,145,483,143,483,231
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
        - dog
  ToyRoom1:
    ffmpeg:
      input_args:
        - -avoid_negative_ts
        - make_zero
        - -fflags
        - nobuffer
        - -flags
        - low_delay
        - -strict
        - experimental
        - -fflags
        - +genpts+discardcorrupt
        - -rw_timeout
        - "5000000"
        - -use_wallclock_as_timestamps
        - "1"
      output_args:
        record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtmp://192.168.5.8:1935/bcs/channel0_main.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - record
        - path: rtmp://192.168.5.8:1935/bcs/channel0_sub.bcs?channel=0&stream=0&user=user&password=Password
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 480
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      ToyRoom:
        coordinates: 640,142,640,480,416,480,216,480,55,480,0,480,0,319,0,246,385,139
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500
    objects:
      track:
        - person
        - cat
        - dog
  BackYard1:
    ffmpeg:
      inputs:
        - path: rtsp://admin:Password@192.168.5.2:88/videoMain
          roles:
          - record
        - path: rtsp://admin:Password@192.168.5.2:88/videoSub
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 360
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      ChickenCoop:
        coordinates: 240,197,101,185,79,110,232,110
      BackYard:
        coordinates: 0,360,321,360,286,217,0,211
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    objects:
      track:
        - person
        - dog
        - cat
  ChickenCoop1:
    ffmpeg:
      output_args:
        record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy
      inputs:
        - path: rtsp://admin:Password@192.168.5.9:554/11
          roles:
          - record
        - path: rtsp://admin:Password@192.168.5.9:554/12
          roles:
          - detect
          - rtmp
    detect:
      width: 640
      height: 352
      fps: 5
    live:
      height: 480
      quality: 8
    zones:
      ChickenCoop:
        coordinates: 0,352,640,352,640,119,0,114
    snapshots:
      # Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
      # This value can be set via MQTT and will be updated in startup based on retained value
      enabled: true
      # Optional: print a timestamp on the snapshots (default: shown below)
      timestamp: true
      # Optional: draw bounding box on the snapshots (default: shown below)
      bounding_box: true
      # Optional: crop the snapshot (default: shown below)
      crop: False
#      # Optional: height to resize the snapshot to (default: original size)
#      height: 175
      # Optional: Camera override for retention settings (default: global values)
      retain:
        # Required: Default retention days (default: shown below)
        default: 10
        # Optional: Per object retention days
        objects:
          person: 15
    objects:
      track:
        - person
        - dog
        - cat
birdseye:
  # Optional: Enable birdseye view (default: shown below)
  enabled: True
  # Optional: Width of the output resolution (default: shown below)
  width: 1280
  # Optional: Height of the output resolution (default: shown below)
  height: 720
  # Optional: Encoding quality of the mpeg1 feed (default: shown below)
  # 1 is the highest quality, and 31 is the lowest. Lower quality feeds utilize less CPU resources.
  quality: 8
  # Optional: Mode of the view. Available options are: objects, motion, and continuous
  #   objects - cameras are included if they have had a tracked object within the last 30 seconds
  #   motion - cameras are included if motion was detected in the last 30 seconds
  #   continuous - all cameras are included always
  mode: objects
detectors:
  coral:
    type: edgetpu
    device: usb

Frigate container logs

[2021-08-27 18:12:32] ws4py                          INFO    : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:40880]
[2021-08-27 18:12:32] ws4py                          INFO    : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:40880]```

**Frigate stats**
```json
{
BackFence1: {
camera_fps: 5,
capture_pid: 255,
detection_fps: 0,
pid: 235,
process_fps: 5,
skipped_fps: 0
},
BackYard1: {
camera_fps: 5,
capture_pid: 278,
detection_fps: 0,
pid: 240,
process_fps: 5,
skipped_fps: 0
},
ChickenCoop1: {
camera_fps: 5.1,
capture_pid: 290,
detection_fps: 0.8,
pid: 242,
process_fps: 0.4,
skipped_fps: 0
},
DiningRoom: {
camera_fps: 5.1,
capture_pid: 262,
detection_fps: 0,
pid: 236,
process_fps: 5.1,
skipped_fps: 0
},
Driveway: {
camera_fps: 5,
capture_pid: 243,
detection_fps: 0,
pid: 227,
process_fps: 5,
skipped_fps: 0
},
FrontDoorbell: {
camera_fps: 5,
capture_pid: 246,
detection_fps: 0.8,
pid: 231,
process_fps: 0.6,
skipped_fps: 0
},
LivingRoom1: {
camera_fps: 0,
capture_pid: 247,
detection_fps: 0,
pid: 232,
process_fps: 0,
skipped_fps: 0
},
Office1: {
camera_fps: 5.1,
capture_pid: 252,
detection_fps: 0.8,
pid: 234,
process_fps: 0.4,
skipped_fps: 0
},
OutsideFrontDoor: {
camera_fps: 5,
capture_pid: 245,
detection_fps: 0.8,
pid: 229,
process_fps: 0.3,
skipped_fps: 0
},
ToyRoom1: {
camera_fps: 5,
capture_pid: 267,
detection_fps: 0,
pid: 238,
process_fps: 5,
skipped_fps: 0
},
detection_fps: 3.2,
detectors: {
coral: {
detection_start: 1630110900.654782,
inference_speed: 333.65,
pid: 218
}
},
service: {
storage: {
/dev/shm: {
free: 50.7,
mount_type: "tmpfs",
total: 67.1,
used: 16.4
},
/media/frigate/clips: {
free: 510966.6,
mount_type: "nfs",
total: 536870.9,
used: 25904.3
},
/media/frigate/recordings: {
free: 510966.6,
mount_type: "nfs",
total: 536870.9,
used: 25904.3
},
/tmp/cache: {
free: 968.2,
mount_type: "tmpfs",
total: 1000,
used: 31.8
}
},
uptime: 325,
version: "0.9.0-4efc584"
}
}

Screenshots image Computer Hardware

Camera Info: Not camera specific happens with all of my cameras

Additional context Just updated to the RC-1 to test it out and check it out and I like living on the edge

blakeblackshear commented 3 years ago

Are you running frigate behind a reverse proxy? The new live view uses websockets. Try inspecting the page in the browser to see what errors are in the console.

Also, I would definitely remove your output_args. The defaults changed in 0.9.0, and you are overriding them.

TheFuzz4 commented 3 years ago

I am kind of running it behind a reverse proxy. I'm using the tunnel from cloudflare. I do it this way because I can expose it to the internet but using CloudFlare Teams I can lock down who has access to it.
Removed the output_args from the config. Ok hit it directly via IP and the streams do load that way. Now to figure out how to get a websocket to pass through the cloudflare tunnel. I'll let you know what I find for others that might decide to try out the tunnel.

TheFuzz4 commented 3 years ago

I lied I haven't solved this yet but I am making headway will update once I have the correct configurations.

blakeblackshear commented 3 years ago

@mitchross this sounds similar to your issue

mitchross commented 3 years ago

Yes very similiar.. @TheFuzz4 https://github.com/blakeblackshear/frigate/issues/1527

The only difference I have is that I'm hosting on unraid -> nginix reverse proxy manager ( docker ) -> cloudflare tunnel.

This issue for sure is websockets, but I can't pin point the issue. Its defiantly related to https://github.com/blakeblackshear/frigate/blob/release-0.9.0/web/src/components/JSMpegPlayer.jsx

The actual JSMpegPlayer library is failing to connect to the WS and is going into an infinite retry loop.

Ive debugged everything. Here are some of the things Ive tried

  1. Web(internet) -> Unraid direct IP:port ( works )... aka just port forward unraid docker hosting frigate... This is expected to work, but it's our control variable.

  2. Web (internet ) -> nginix reverse proxy manager -> frigate unraid docker instance... Both HTTPS and NO HTTPS and bypass cloudflare ( fails )

  3. Web (internet ) -> cloudflare -> frigate unraid docker instance.. ( bypass nginix reverse proxy manager ) ( fails)

@TheFuzz4 The craziest thing I've found so far to work is to goto the live stream camera page, restart docker, paste the live stream URL into browser ( ie new tab ) and it will work until you navigate away. Its not a solution, it's just an observation.

TheFuzz4 commented 3 years ago

@mitchross yeah I think you and I are pretty much in the same boat I just don't have Unraid (I'm a oldschool freenas/Trunas and I don't want to make the switch) My setup is a dedicated VM running Ubuntu with the cloudflared daemon on it.
What works for me is smacking the host directly and all of that works great.
I could setup a route through HA Proxy and see if that works and bypass the cloudflared but ultimately I'd like to figure out how to get it to work with cloudflared because I like the "no firewall holes needed" approach. I stayed up late last night trying every scenario under the sun with different paths in the ingress for the cloudflared /live/ /ws/ If there are other paths that are needed for the WS to make the connection I'll gladly add them to my ingress rule in the cloudflared config. I even went so far as to put a catch all rule in the config so that anything not matching the http service in the ingress would default over to the ws protocol Here is my current config

ingress:
  - hostname: frigate.hostname.com
    service: http://localhost:5000
  - service: ws://localhost:5000

I'm not going to give up on this one. I'm looking through the jsx now to see what I can find in there. I'm no java developer just a cloud infra engineer who works in AKS all day :). But I can typically read code and get most of the gist of what its attempting to do.

Update:

  const url = `${baseUrl.replace(/^http/, 'ws')}/live/${camera}`

Not sure if it matters or not here but for those of using cloudflare our traffic is all sent over https. I'll have to plug in the HA Proxy and have CF route to me that way and see if this makes a difference or not I doubt it would but if this is doing a replace on http in the baseurl in our case it replaces https with wss. It shouldn't make a difference I wouldn't imagine since we're running just straight ws:// in the container. I dunno just a thought.

mitchross commented 3 years ago

@TheFuzz4 Yea ive hit pure VM and no unraid too.. Unraid is irrelevant in this scenario, just threw it out there for extra context.

For what its worth, I custom compiled a version with " const url = ${baseUrl.replace(/^http/, 'wss')}/live/${camera} for the websocket secure method. It doesn't make a difference. Nginix reverse proxy and/or cloudflared already upgrade the protocol and will add the extra 's' automatically... so you end up with wsss if you try to change the regex.

The issue is in the core of the jsmpeg player, I'm pretty sure of it. https://github.com/cycjimmy/react-jsmpeg-player-demo/issues/7

"JSMpeg comes with a tiny WebSocket "relay", written in Node.js. This server accepts an MPEG-TS source over HTTP and serves it via WebSocket to all connecting Browsers. The incoming HTTP stream can be generated using ffmpeg, gstreamer or by other means." - https://github.com/phoboslab/jsmpeg#streaming-via-websockets

Websocket Relay code -> https://github.com/phoboslab/jsmpeg/blob/master/websocket-relay.js

This may be of interest -> https://github.com/kyriesent/node-rtsp-stream/issues/37 but the project assumes you can use your cert/pem in your code which we probably cannot since its on the fly with cloudflare.

The only way I could see around this, while probably insecure-ish ( though I don't care at this point). Would be to find a way around upgrading Websocket over SSL ( ie WSS ) via cloud flare or ngnix or whatever.

or maybe some sorta of relay of the relay hack https://stackoverflow.com/questions/45802281/is-it-possible-to-relay-a-websocket-through-nginx-over-tls

@blakeblackshear if you have any ideas, feel free to chime in. Im 100% now the issue is that jsmpeg player doesn't support WSS or if it does cloudflared/ngnix ( pick your favorite ssl/lets encypt toolkit ) is jacking with the connection.

LOL free job if u can solve this - https://www.upwork.com/freelance-jobs/apply/Configure-jsmpeg-display-video-stream-from-WSS-HTTPS-page_~01c75fa685d8f4f048/

blakeblackshear commented 3 years ago

I am using mine with https/wss just fine. Also, I am not using the node rtsp relay from the jsmpeg project.

mitchross commented 3 years ago

I am using mine with https/wss just fine. Also, I am not using the node rtsp relay from the jsmpeg project.

Ok interesting. How are you using https? lets encrypt? also are you accessing over a (sub)domain?

blakeblackshear commented 3 years ago

Let's encrypt with traefik. I use a subdomain dedicated to frigate. https://frigate.blakeshome.com

blakeblackshear commented 3 years ago

Screenshot from 2021-08-28 15-47-40

TheFuzz4 commented 3 years ago

Hmm so this might just be with Cloudflare doing its reverse proxy thing?

mitchross commented 3 years ago

Hmm so this might just be with Cloudflare doing its reverse proxy thing?

I don't know. Im completely stumped.

mitchross commented 3 years ago

@TheFuzz4

I made a simple nodeJS websocket server and using cloudflare + nginix reverse proxy and everything is fine over ssl/wss. So I don't think the issue is 100% cloudflares fault, but related. Im still trying to figure out what the heck is going on.

mitchross commented 3 years ago

@TheFuzz4 I've given up hope. I ended up reverting this change https://github.com/blakeblackshear/frigate/commit/861ee0485d47d9a1441c9d825a39bdcbff4edd07 and built my own docker image and I'm just gonna use that.

TheFuzz4 commented 3 years ago

@mitchross I wonder if you can get your image to be in the repo for Frigate. Sorry I haven't had a chance to test out some things this week been slammed with work things. I've got a few cycles today though I can throw to you, to help test and what not.

mitchross commented 3 years ago

@mitchross I wonder if you can get your image to be in the repo for Frigate. Sorry I haven't had a chance to test out some things this week been slammed with work things. I've got a few cycles today though I can throw to you, to help test and what not.

thellamafarm#7609 on discord if you want to chat in more real time.

cdn4lf commented 3 years ago

I'm moving this comment over here. I upgraded to the beta and have received the following in my logs.

    self.result = application(self.environ, self.start_response)
  File "/usr/local/lib/python3.8/dist-packages/ws4py/server/wsgiutils.py", line 101, in __call__
    raise HandshakeError('Header %s is not defined' % key)
ws4py.exc.HandshakeError: Header HTTP_UPGRADE is not defined

When I open the UI viewer and click the live view on my camera, this is in my logs. When I click debug, everything is working as expected. I'm running in docker, on a pi4 with NGINX Proxy Manager on my network.

mitchross commented 3 years ago

@cdn4lf do you see logs like this? This is what I see.

0.0.1:5002 | Remote => 127.0.0.1:42792] [2021-09-02 17:22:49] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49006] [2021-09-02 17:22:50] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49006] [2021-09-02 17:22:52] ws4py INFO : Terminating websocket [Local => 127.0.0.1:5002 | Remote => 127.0.0.1:42792] [2021-09-02 17:22:56] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49008] [2021-09-02 17:22:56] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49008] [2021-09-02 17:23:01] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49010] [2021-09-02 17:23:02] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49010] [2021-09-02 17:23:07] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49012] [2021-09-02 17:23:08] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49012] [2021-09-02 17:23:13] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49014] [2021-09-02 17:23:15] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49014] [2021-09-02 17:23:20] ws4py INFO : Managing websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49016] [2021-09-02 17:23:20] ws4py INFO : Terminating websocket [Local => 127.0.0.1:8082 | Remote => 127.0.0.1:49016]

cdn4lf commented 3 years ago

I haven't yet. What did you do immediately before seeing that? I can try to recreate it myself.

blakeblackshear commented 3 years ago

@cdn4lf I saw that error when developing the frigate proxy addon. See here for an nginx config that I know works: https://github.com/blakeblackshear/frigate-hass-addons/tree/main/frigate_proxy/rootfs/etc/nginx

cdn4lf commented 3 years ago

I'm using NPM, so I turned on websocket support and that seems to have cleared the NGINX issues. Only comment now is the live stream seems to take about 10 seconds to come up.

mitchross commented 3 years ago

I'm using NPM, so I turned on websocket support and that seems to have cleared the NGINX issues. Only comment now is the live stream seems to take about 10 seconds to come up.

How are you doing https? Try your setup with cloudflare and you will run into these issues.

cdn4lf commented 3 years ago

https with let's encrypt. No change regardless of http vs https. There is still a delay in calling up the live feed, anywhere from 1/2 second to 10+.

Edit to add: This also happens when I view with the local IP address/port, so it isn't a https issue.

mitchross commented 3 years ago

https with let's encrypt. No change regardless of http vs https. There is still a delay in calling up the live feed, anywhere from 1/2 second to 10+.

Are you portforwarding on router? Are you using a custom domain too ?

The issue I have is between Dns -> cloudflare -> (argo tunnel / dns )-> ngninx -> frigate

cdn4lf commented 3 years ago

Nope, nothing regarding this on the router. Using the local network I'm going to my 192.168.x.x:15000 (I changed the port). When there it opens the UI. Direct connection, nothing fancy.

On HA I have it mapped using iframe and a subdomain. That's going HA out, ddns server (external), nginx/let's encrypt, frigate

mitchross commented 3 years ago

Nope, nothing regarding this on the router. Using the local network I'm going to my 192.168.x.x:15000 (I changed the port). When there it opens the UI. Direct connection, nothing fancy.

On HA I have it mapped using iframe and a subdomain. That's going HA out, ddns server (external), nginx/let's encrypt, frigate

How do you access externally if you don't port forward? Afaik you can only avoid port forwarding by using a tunnel of some sort...

assuming ddns like duck dns are you doing something like frigate.duckdns.org ?

Just curious how you go from the internet to HA without port forwarding..

cdn4lf commented 3 years ago

I'm using NGINX, so everything is inbound to the router on port 80/443, NGINX does the distribution from there.

mitchross commented 3 years ago

@blakeblackshear Where in the python code can I put a breakpoint for debugging the jsmpeg player web socket connection?

blakeblackshear commented 3 years ago

output.py

mitchross commented 3 years ago

output.py

Im trying to figure out where the log "terminating websocket comes from". Ive got break points working so trying to compare local host vs cloudflare to see if I can get a better picture of whats going on.

blakeblackshear commented 3 years ago

It's almost certainly buried deep in a dependency.

mitchross commented 3 years ago

It's almost certainly buried deep in a dependency.

On a local, I get this everytime.

image

On cloudflare'd I get this first image

Followed by ( notice the server terminated "true" flag ) image

This "2 step" process repeats over and over.

blakeblackshear commented 3 years ago

It's probably some issue with the handshake. If I had to guess, it's an obscure bug in the ws4py library. The plan is to move to fastapi eventually, but that will be a significant effort.

mitchross commented 3 years ago

It's probably some issue with the handshake. If I had to guess, it's an obscure bug in the ws4py library. The plan is to move to fastapi eventually, but that will be a significant effort.

Its probably not the most ideal, but it would be cool if you had a settings option for "use legacy live stream player" for use with the non jsmpeg player.

Right now I just build my own image reverting the jsmpeg play for now. Only downside is I have to keep up with changes on the v9 branch and rebuild my docker image. Not the end of the world tho...

blakeblackshear commented 3 years ago

Once the final release is out, it won't be much to keep up with.

mitchross commented 3 years ago

Once the final release is out, it won't be much to keep up with.

Great point. Im good with that.

mitchross commented 3 years ago

@blakeblackshear One last idea... Is there a way I can not proxy the web sockets thru ssl ?

Looks like the web socket runs on 8082... wonder if i can expose that in the compse file and do some sort of custom path in ngnix and have SSL off for just /live/ paths?

blakeblackshear commented 3 years ago

You can override the nginx config however you want. I'm not sure how you have implemented auth, but having everything on a single domain/port makes standard cookie based auth easy. There are other things I'm probably not thinking about. The browser may not like unsecured websocket connections from a https site.

mitchross commented 3 years ago

@TheFuzz4 I got some new info

For fun, I decided to set up Hass OS and add the frigate nvr proxy add on. I think used my normal setup of ngnix reverse proxy manage + cloudflare.

I can see the video streams in the frigate proxy addon in hass OS over SSL.

I haven't quite figured out a solve for the normal UI route, but this is a bit promising.

mitchross commented 3 years ago

@TheFuzz4

I did some more experimentation. I'm using SWAG container and removed cloudflare from the picture. The base docker v9 works fine over https. I'm convinced it's an issue with Cloudflare certs now.

TheFuzz4 commented 3 years ago

@mitchross thanks for the updates on this. So do you think its with the public certs? Interesting that there would be an issue with those.

mitchross commented 3 years ago

@TheFuzz4

I tried to use SWAG + lets encrypt cert and then point my go daddy DNS at cloudflare so I at least had cloud flare protection and it still broke. So I cant seem to pin point what the issue is in cloud flare.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

evanhfox commented 2 years ago

@mitchross Did you ever get further on this? Have been following your troubleshooting steps and trying to pin point things myself as well. I've got the majority of my services exposed via CF Tunnels & Teams.

mitchross commented 2 years ago

@mitchross Did you ever get further on this? Have been following your troubleshooting steps and trying to pin point things myself as well. I've got the majority of my services exposed via CF Tunnels & Teams.

Im glad you asked because I gave up since I figured it was impossible. Looks like its finally resolved. https://github.com/cloudflare/cloudflared/issues/526

evanhfox commented 2 years ago

Thanks for the link, @mitchross... I'd missed this update from CF in my googling. Looks like swapping to QUIC has improved this and some other cases for me. Thanks!

hellovurtech commented 2 years ago

Thanks for the link, @mitchross... I'd missed this update from CF in my googling. Looks like swapping to QUIC has improved this and some other cases for me. Thanks!

Can you share your Cloudflared config file?

evanhfox commented 2 years ago

Sure. I assume you're wanting to see how QUIC can be enabled to fix this issue. It is configured at the root of the cloudflared config file. See an example below (note that standard YAML spacing rules apply):

tunnel: <Tunnel ID>
credentials-file: /home/<path to json credentials file>.json
protocol: quic

ingress:
# HTTP Services
  - hostname: example-service.<mydomain>.me
    service: http://x.x.x.x

# SSH Services
  - hostname: example-ssh.<mydomain>.me
    service: ssh://x.x.x.x

# Catch-all rule, which just responds with 404 if traffic doesn't match any of the earlier rules
  - service: http_status:404
hellovurtech commented 2 years ago

That did the trick, thank you!

Complete config file for Cloudflare's Tunnel Service package, cloudflared, for the next googler:

tunnel: <Tunnel UUID>
credentials-file: /root/.cloudflared/<Tunnel UUID>.json
protocol: quic

ingress:
  - hostname: homeassistant.<domain>.com  #Note: Remember to allow trusted_proxy in HA config
    service: http://<IP ADDR>:8123
  - hostname: frigate.<domain>..com
    service: http://<IP ADDR>:5000
  - hostname: frigate.<domain>..com
    path: /ws
    service: ws://<IP ADDR>:5000
  - hostname: frigate.<domain>.com
    path: /live
    service: ws://<IP ADDR>:5000
  - service: http_status:404