bourdakos1 / ring-streamer

2 stars 0 forks source link

Integrating `ring-client-api` #1

Open dgreif opened 5 years ago

dgreif commented 5 years ago

@bourdakos1 I figured it's probably easier if we pulled this conversation off on it's own. I appreciate your willingness to work together. I know how it goes when you get wrapped up in the technical side and do whatever it takes to just get it working.

Regarding your issues with getting a sip session through ring-client-api, I think I know what the issue is. By default, I do not poll the api for ding events. The homebridge-ring plugin turns this setting on by default, but I didn't want to force all users of the pure api client into polling. All you need to do is pass cameraDingsPollingSeconds: 1 (meaning poll every 1 second, you can change this to whatever value you prefer) to get active ding polling enabled. Then when you call createSipSession, it will hit the vod endpoint and the sip info will come down in the next poll.

Like I said in the other thread, you seem to know what you are doing with what you accomplished here. I could really use a second set of eyes to help figure out things like sip keep-alive and audio streaming to homebridge. Let me know if you are interested in helping out.

bourdakos1 commented 5 years ago

@dgreif ahhhh okay, I didn't set cameraDingsPollingSeconds so that explains it. Does it make sense to automatically poll when calling createSipSession?

From what I've gathered, the SIP conversation goes a little something like this:

INVITE -->
<-- Trying
<-- Ringing
<-- OK
ACK -->
<==RTP starts==>

Your code sends 2 additional INFO requests (I'm not sure what they do) Nothing changes when I remove them 🤷‍♂️

In the initial INVITE is where we negotiate the initial terms of the call (the audio/video encoding formats etc...) You can change these terms by sending another INVITE within the same session and if the other party responds with OK, then the terms of the session are changed. I'm not sure if you can negotiate a change in the to field, if so maybe you can send an INVITE with a newly generate address.

I'm not sure if the standard keep-alive will work, just because the calls get terminated in clients like blink. I think with keep-alive you agree on a frequency and periodically send udp messages.

Also, calls are cancelled after 30 seconds if the other party doesn't receive the ACK, so that could be a silent issue

I'm not really familiar with homebridge so I don't know how much help I'll be with setting up audio. I can at least try and get audio outputted to a file like I did with video.

My main focus was just to get a video stream working, because I'm a computer vision nerd and I wanted to try detecting things like mailman/UPS or just some leaves blowing in the wind haha, but I'm glad to help get other things working as well :)

bourdakos1 commented 5 years ago

Another thing is that whenever you start a dialog you get tags, in you code you don't keep track of the tag which can cause an issue in the dialog flow. When you send the INVITE the to param should come back with a tag, something like i3rye89qwoa, you need to keep that and send it with the next dialog message (in this case ACK) otherwise the other party might reject it because the tag wasn't specified

bourdakos1 commented 5 years ago

Also what do you think about this for the SIP Session API? I can make some pull requests

const sipSession = await camera.createSipSession()

const h264Builder = new H264Builder('output.h264')
sipSession.videoStream.on('message', rtpPacket => {
  h264Builder.addPacket(rtpPacket)
})

sipSession.audioStream.on('message', rtpPacket => {
  // Do something with audio packet.
})

sipSession.on('end', () => {
  process.exit()
})

await sipSession.start()

if (forSomeReasonWeWantToStop) {
  sipSession.stop()
}
dgreif commented 5 years ago

All very good points! I'll try to respond to each:

Thanks for putting so much effort into this. It's really nice to have someone else with their head this deep into the code. I have a lot of users, but most of them are not developers and can't help solve some of these hard problems.

dgreif commented 5 years ago

I just added the tag to the to field and the stream now appears to stay open indefinitely. I think it needs to receive messages back through RTP/RTCP for it to stay open, but HomeKit generates that for me. Thanks for the info, I'll release an update right now!

bourdakos1 commented 5 years ago

Oh that’s amazing! I did not think it would be that easy haha, how exciting!

I’m cool with reactive for the callbacks and I can try and get the RTP messages working for non homebridge support

And again I’m really sorry about not crediting you initially, you code was definitely key for solving this for me, I definitely just got way to excited when it finally started working

dgreif commented 5 years ago

No worries about the credit thing. I reacted impulsively because I had just put a ton of effort into that code last week, but you really didn't do anything wrong. I'm over it, and excited to have someone on board that I can bounce SIP issues around with!