go2rtc icon indicating copy to clipboard operation
go2rtc copied to clipboard

Forcing IFrames on new consumer.

Open dbuezas opened this issue 2 years ago • 10 comments

Hi Alex! I've been experimenting with DVR-IP quite a bit and found that the startup time of a camera is way longer than when using dedicated Apps like ICSee or XMEye. I also noticed that the video of my DVR-IP cameras starts up instantly on go2rtc AFTER as I connect to them through one of those apps. By adding logs in the code, I realised exactly what's going on:

  • When a new client connects to one of these cameras, an IFrame is sent
  • This IFrame somehow is not sent to the consumer. This results in long wait times.
  • When I connect through an app while waiting, the camera sends an IFrame to all clients
  • This results in an instant startup of the video in go2rtc
  • I can also force an IFrame and very quick startup times by making a 2nd connection to the camera (just a go routine that creates a 2nd connection to the camera)
  • If I reload the webrtc player in the browser, I again have to wait until the next IFrame

So my questions are:

  • Where in the code can I know that a new cliient was added to a dvr ip camera? (this way i can force an iframe by creating a short lived 2nd connection and get super fast video startup times)

Thank you!

dbuezas avatar Jun 28 '23 20:06 dbuezas

The hack I am using at the moment is this: image

I call a 2nd go routine that starts a new connection and then is closed quickly.

The only issue I have is that the video startup time is still super slow if I'm not the first coonsumer in the list, because of stream reuse inside go2rtc

dbuezas avatar Jun 28 '23 20:06 dbuezas

  1. Maybe you just need to call "Claim" or "Start" for existing connection https://github.com/AlexxIT/go2rtc/blob/306451f94f48a03d9922861bed8915eba97201ed/pkg/dvrip/client.go#L113-L126
  2. There is no good place, where producer can know about new consumer. Because "proxy" producer will stop any duplicate GetTrack and Start calls https://github.com/AlexxIT/go2rtc/blob/306451f94f48a03d9922861bed8915eba97201ed/internal/streams/producer.go#L134-L139
  3. Only call that proxy producer wan't stop is GetMedias https://github.com/AlexxIT/go2rtc/blob/306451f94f48a03d9922861bed8915eba97201ed/pkg/dvrip/producer.go#L9

AlexxIT avatar Jun 29 '23 05:06 AlexxIT

Ok thanks for the pointers. I'll research a bit more. This would make dvrip cameras incredibly snappy. I tried sending a "Start" action on the existing connection but that broke the stream. I'll try again to be sure.

Any clue as to why the first IFrame doesn't make it to the consumer? That would already make a big difference

dbuezas avatar Jun 29 '23 07:06 dbuezas

Producer can start send frames before consumer can receive this frames. This is architecture problem for some producer and some consumer formats.

AlexxIT avatar Jun 29 '23 08:06 AlexxIT

I see. The problem has gotten worse since the latest firmwares increase the distance between IFrames. I'll see if I find any orderly way of sending a command to the DVRIP cameras when new consumers come in. This could make it the quickest protocol to start up video :)

dbuezas avatar Jun 29 '23 17:06 dbuezas

Problem also will be fixed with #96

AlexxIT avatar Jun 29 '23 19:06 AlexxIT

@dbuezas did you find a workaround for this in the meantime? My camera also supports rtsp, but I notice the same behaviour when using dvrip or rtsp.

michaelarnauts avatar Jul 27 '24 06:07 michaelarnauts

@michaelarnauts The only work around I found was to add a second stream to the same camera to go2rtc. That stream is not used by anything else, so opening it causes the camera to add an iframe to all streams. Not great but it does make the normal stream "wake up" quickly

dbuezas avatar Jul 27 '24 19:07 dbuezas

@michaelarnauts The only work around I found was to add a second stream to the same camera to go2rtc. That stream is not used by anything else, so opening it causes the camera to add an iframe to all streams. Not great but it does make the normal stream "wake up" quickly

Late reply, i know, but how did you integrate this? I'm trying to find a way to make sure frigate (and Home Assistant) can start playing a stream as soon as possible. Now, it can take up to 10 seconds for a stream to start, while frigate is actively reading the stream, so the data is already passing through the whole pipeline.

I was thinking about transcoding the stream, but that does seem to have the same issue. I've also tried to add you change to go2rtc to initiate a new connection, but the code has been refactored since, and I couldn't find the right location anymore.

michaelarnauts avatar Oct 28 '24 09:10 michaelarnauts

but how did you integrate this?

I didn't. I just had a second stream I would open briefly just to "wake it up". Since then I change the camera for a "HiSeen" branded one that doesn't have the issue.

dbuezas avatar Oct 28 '24 10:10 dbuezas