dgreif / ring

Unofficial packages for Ring Doorbells, Cameras, Alarm System, and Smart Lighting
MIT License
1.17k stars 155 forks source link

Stream instantly closes after it opens #1421

Closed z1haze closed 1 month ago

z1haze commented 1 month ago

Streaming Issue

I have just discovered this package today, and have begun to play with it. I have a rather simple script to to stream a camera, however for whatever reason the calls are ending virtually instantly after the steams are started. I looked through the wiki to see if there was anything that could tell me what I'm doing wrong, but I didn't find anything. Attaching my relevant scripts and logs here. Hopefully I'm doing something glaringly obvious, because I have a handful of these ring cameras and I'd love to be able to make use of them in my current NVR. Thank you for creating this package.

const startRTSPStream = (camera: RingCamera) => {
  const streamUrl = `${process.env.RTSP_URL}/cam-${camera.id}`;

  console.log(`Starting RTSP video stream of camera ${camera.id} to ${streamUrl}`);

  camera.streamVideo({
    output: [
      '-f',
      'rtsp',
      '-c:v',
      'libx264',
      '-preset',
      'ultrafast',
      '-tune',
      'zerolatency',
      '-b',
      `${process.env.VIDEO_BITRATE}`,
      '-filter:v',
      `fps=${process.env.VIDEO_FRAMERATE}`,
      streamUrl,
    ],
  })
    .then(streamSession => {
      let began = Date.now();

      console.log('Stream session started...');

      streamSession.onCallEnded.subscribe(() => {
        console.log('Ring call lasted ' + ((Date.now() - began)/1000) + 's.');

        setTimeout(() => {
          startRTSPStream(camera);
        }, 1000 * 10);
      });
    })
}

ringApi.getCameras().then(cameras => {
  console.log(`Found ${cameras.length} camera(s).`);

  for(let camera of cameras) {
    startRTSPStream(camera);
  }
});

Proposed Solution

no solution.

Environment

Other (ring-client-api)

What operating system are you on?

Mac

Relevant log output

npx ts-node ./src/index.ts
Found 1 camera(s).
Starting RTSP video stream of camera 155460945 to rtsp://127.0.0.1:8554/cam-155460945
Stream session started...
Ring call lasted 0.829s.
Starting RTSP video stream of camera 155460945 to rtsp://127.0.0.1:8554/cam-155460945
Stream session started...
Ring call lasted 0.517s.

Honesty Time

tsightler commented 1 month ago

Most likely your ffmpeg parameters are wrong and it is exiting, you should log the output of ffmpeg, for example by using the -report parameter, and take a look.

z1haze commented 1 month ago

Thanks for your input there. That helped me narrow down my issue and get everything working. I have been successful at getting my ring cameras to stream pretty much continuously to an rtsp server. I am able to view the streams through VLC so can confirm it all works. I do have a problem though, and I'm so new with this I'm not sure where to look...but I'm using frigate as an NVR and when I enter the same URL that i enter in VLC (that works) into a go2rtc config in frigate, I get nothing from it. It shows 0 links, 0 streams, and I'm not sure why.

image

This is what it shows under info: image

My frigate config image image

I am not sure if I am supposed to be explicitly setting the codec for h264 or something? If so, I don't know how to do that, anyway.

I am using https://www.npmjs.com/package/rtsp-streaming-server for my rtsp server, btw

z1haze commented 1 month ago

I actually am already streaming in h264, so that isnt the issue. These are my output options

// RTSP_URL="rtsp://127.0.0.1"
// RTSP_SERVER_PORT=8554
// RTSP_CLIENT_PORT=554
// VIDEO_BITRATE="1536k"
// VIDEO_FRAMERATE=20

const streamUrl = `${process.env.RTSP_URL}:${process.env.RTSP_SERVER_PORT}/${toKebabCase(camera.name) ?? 'cam-' + camera.id}`;

camera.streamVideo({
  output: [
    '-f',
    'rtsp',
    '-c:v',
    'libx264',
    '-preset',
    'ultrafast',
    '-tune',
    'zerolatency',
    '-b',
    `${process.env.VIDEO_BITRATE}`,
    '-filter:v',
    `fps=${process.env.VIDEO_FRAMERATE}`,
    streamUrl,
  ],
})...
tsightler commented 1 month ago

You might want to check out ring-mqtt (my person project) which already does all of this, or Scrypted, which can do the same. In general, you will be sad with forever streaming with Ring cameras because Ring devices simply aren't desgined for this, they still record everything in the cloud, streams still go via the cloud and have to be restarted every 10 minutes (although this is mostly automatic), and you get no motion notifications or anything else from you device while streaming. Also, Ring devices aren't generally designed for this so many will overheat or otherwise become unstable after a few days of streaming. You are generally far better offer just purchasing a device designed for this use case.

Regardless, if you are a glutton for pain and want to down the same path that so many others before you have tried, feel free to keep going. However, as your questions are now about go2rtc and or other libraries and not this project, I'm going to close this issue here, but I will wish you luck in your endeavors.

tsightler commented 1 month ago

Also, I will mention you don't need to re-encode into H.264, you can just use copy mode, as Ring already streams in H.264, so that is mostly just wasting CPU.

z1haze commented 1 month ago

Thanks for the feedback. I enjoy the tinkering will continue to try to improve on it. I have a bunch of ring cameras since I replaced everything a few months ago and don't want to just sell them or throw them away. Thought it was worth a try. I've been able to get both a main and sub stream going from each camera to the rtsp server and feed that into go2rtc. It's super slow though when deploying it in an lxc, despite there not being hardly any CPU utilization. Wish I knew what that was happening. Thanks for your feedback though. Can you tell me what you mean by copy the h264 to save cpu? That might be helpful in my issue

tsightler commented 1 month ago

In your code above you are using -c:v libx264 which is telling ffmpeg to transcode the video stream to H.264, but the video from Ring cameras is already H.264 so this step is largely not required. Again, you can just look at projects like ring-mqtt which already do the same thing (ring-mqtt is designed to integrate with other tools via MQTT, but you don't have to use that part, you can just use the RTPS server which exposes each discovered cameras as a local RTSP camera). That project uses ffmpeg with just the -c:v copy mode to copy the existing video stream vs transcoding it.

That being said, you are doing some filtering for some reasons that I might not understand, but Ring cameras are already fairly low bit-rate H.264 at 20 frames per second, I'd expect Frigate to deal with that easily.

I don't support users of NVR tools like Frigate using ring-mqtt not because it doesn't work, but because I don't want to spend my life answering questions about all the limitations all the time, nor do I want the project to become known for that capability since it would dramatically increase the chances of Ring shutting down these 3rd-party API projects completely as it costs them money to have Ring cameras out there streaming all the time and I'm sure their pricing model would not support that if it became a popular thing.

z1haze commented 1 month ago

awesome, thank you!. That actually seemed to help out a lot with the issue I was seeing. I was trying to create a "sub" stream though at a lower resolution and lower fps for the detection to run on, but it seems that both streams are now using the same fps and resolutions. I suspect that is related to the copy happening now on the -c:v flag. Is there a way to use copy but also change the resolution and fps, or is what I'm doing not really saving me any computing power? I'm just trying to follow the pattern that I use for my other cameras that typically have a lower quality stream to use for viewing, and a higher quality stream for recording, so that I can easily view them on the go over a cellular network

tsightler commented 1 month ago

It's not possible to change the resolution/bitrate without re-encoding, but I'm not sure how required it is. Ring cameras are already only 20 fps.