tchellomello / python-arlo

Python Arlo is a library written in Python 2.7/3x that exposes the Netgear Arlo cameras as Python objects.
GNU Lesser General Public License v3.0
100 stars 35 forks source link

View RTMPS live stream access #8

Open ryanwinter opened 7 years ago

ryanwinter commented 7 years ago

cam_object.live_streaming() provides the live stream which is returned as type rtmps://. This would indicate that it is an encrypted RTMP stream.

At this point, I haven't seen anyone successfully open the stream. I have tried to stream with ffmpeg however received errors of various types.

I suspect either a certificate is required, or some token is needed to access/decrypt the stream.

ryanwinter commented 7 years ago

I spent a little time on this yesterday. I install Android x86 and installed the Arlo app within the VM.

However when trying to launch the Arlo app, it crashes instantly. Everything else appears to work on in the VM, so I'm a little uncertain on why this decided to fail. Will take another look tonight.

ryanwinter commented 7 years ago

The second thing I noticed, while poking around in the Android APK, is that there are libraries for ffmpeg, x264. There is also a wowza certificate in the assets folder.

So hopefully they aren't doing anything funky and these libraries are all that's needed to decode the stream.

jwillaz commented 7 years ago

I did some inspection using Fiddler as a proxy for my phone while running the Android app and opening a live stream. The things you noted above are correct. There is a wowza secure stream player used. There are also 2 certs I noted in the trace. One was a Netgear Arlo cert. The other was an Amazon AWS cert. The stream is tunneled from AWS.

ryanwinter commented 7 years ago

I believe this is the documentation outlined the server side encrpytion: https://www.wowza.com/docs/how-to-protect-rtmp-streaming-using-securetoken-modulesecuretoken

ryanwinter commented 7 years ago

So I believe the web interface and likely the android app are using a flash player to stream. Seeing as flash isn't possible on the apple devices, I'm wondering if they are using a different stream protocol instead.

If so, this might be an easier way to access the live stream.

I have an apple device and tried to use fiddler to view what was going on, but when I turn on https decryption, I get certificate errors on the device.

ryanwinter commented 7 years ago

By changing the user agent string to "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G36 NETGEAR/v1 (iOS Vuezone)",

I get the following stream response: "rtsp://52.38.114.182:443/vzmodulelive/?egressToken=&userAgent=iOS&cameraId="

So yes as I suspected, the iOS is using a different stream format (Android is possibly using this as well). I haven't successfully managed to stream this yet with ffmpeg, but will give it a try later tonight.

ryanwinter commented 7 years ago

I poked around with this the other night, mostly trying to play the RTSP stream with no success. I was able to connect to the rtsp server with openssl and validate that it did provide a correct certificate.

I also decided to snoop on the traffic from the camera itself, however it appears that the camera initiates all traffic, and its SSL encrypted.

Still want to investigate more, trying to understand how the netgear servers initiates camera requests. It appears that the camera keeps the encrypted connection constantly open, and this is used, however this seems a bit weird. Once I figure out how to do an SSL man in the middle attack with my setup I will post some results.

jwillaz commented 7 years ago

You are definitely onto something. I'm on a hotel network that seemingly does throttling / dropping of video connections. Whenever I try to connect to my live camera feeds through a web browser, the feed gets disconnected. However, if I use the Android app on the hotel network, it connects and streams no problem. Obviously something wonky about how the hotel filters connections, but it at least confirms that there is a distinct difference in how the site and apps are streaming. This is foreign territory for me, though.

ryanwinter commented 7 years ago

Foreign for me as well, been a crash course of hacking my network :) I have an android device which I will take home and have a look at what that is doing. I suspect it's probably using the same rtsp stream that the ios devices are using.

I will try and read up more on the wowza documentation on RTSP streaming, hopefully this will have some key on what I should be doing.

tchellomello commented 7 years ago

This is awesome guys

chaddotson commented 7 years ago

Any updates? I've been attempting to start the stream via librtmp unfortunately I keep getting a failure to start the stream. It does get connected however.


import librtmp

rtmp = librtmp.RTMP(url=camurl, token=arlo._PyArlo__token, live=True)
rtmp.connect()

stream = rtmp.create_stream()
data = stream.read(1024)

rtmp.close()
jwillaz commented 7 years ago

This is a secured stream, so I don't think it will be possible without the appropriate certificate.

chaddotson commented 7 years ago

My first goal is updating the thumbnail on the website and on the mobile app. So, I think that if i can manage to get the stream online (not actually decode it) for a second or so, that will happen. Merely getting the url almost does it.

I've also tried the following which downloads their player. Though I suspect the reason this doesn't work is that they also load a flowplayer rtmp plugin.


import librtmp

rtmp = librtmp.RTMP(url=url,
                    token=arlo._PyArlo__token,
                    swfurl="https://arlo.netgear.com/flowplayer/flowplayer.commercial.swf",
                    live=True)
rtmp.connect()

stream = rtmp.create_stream()
data = stream.read(1024)

rtmp.close()
chaddotson commented 7 years ago

Has anyone dug into the flashvars? They look interesting to say the least. I suspect the token field contained in those is what we need.

chaddotson commented 7 years ago

Seems that flashvars references to the plugins used to securely stream to the client. I've been attempting to find if python-librtmp has a feature to do this; so far, it doesn't appear so.

njschwartz commented 7 years ago

I would also like to know if anyone has made any further progress here. Overall I am pretty happy with my arlo cameras, but having access to the live stream wherever I want it would be huge. I have played around and gotten about as far as others have. I can get the tokens etc but cannot figure out how to put it all together to play a stream. Is anyone else actively looking at this or has it gone cold?

chaddotson commented 7 years ago

I look at it when I have a chance. Last time I did was 12 days ago. I'd say any help in the area would be appreciated. It should be possible. We should have everything we need to start the stream. I wonder whether python-librtmp doesn't support all the features we need or we haven't hit the right arguments yet.

njschwartz commented 7 years ago

I pulled the private key and certs from the apk. Hopefully someone smarter than I can use them to get the stream to play?
certs.zip

tchellomello commented 7 years ago

@chaddotson @jwillaz did you see the certs the @njschwartz pulled from the APK?

↪ openssl  x509 -in wowza.netgear.com.crt  -subject -noout -dates
subject=C = US, ST = California, L = San Jose, O = "Netgear, Inc.", OU = IT, CN = wowza.netgear.com
notBefore=Aug 28 20:31:35 2014 GMT
notAfter=Aug 23 20:31:35 2034 GMT

↪ openssl  x509 -in client.crt   -subject -noout -dates
subject=C = US, ST = California, L = San Jose, O = Netgear Inc, OU = arlo, CN = fw, emailAddress = arlofw@netgear.com
notBefore=Jan  6 00:48:47 2017 GMT
notAfter=Jan  5 00:48:47 2021 GMT

↪ openssl x509 -in client.crt -pubkey -noout | openssl  md5
(stdin)= e32804cdc0c3d9d630e1fac594aa6002
↪ openssl  pkey  -in client-key.pem  -pubout  | openssl  md5
(stdin)= e32804cdc0c3d9d630e1fac594aa6002
jwillaz commented 7 years ago

Having the certs is definitely a good start. Unfortunately, I'm not sure how to use them. I don't have any experience with this protocol, and I've fallen into the same rut other have succumbed to with trying to playback the stream in something like FlowPlayer. If I could get my phone to properly proxy through Fiddler, I'd be interested in seeing the traffic from the Arlo app and also from the SmartThings integration to see if there are common calls.

chaddotson commented 7 years ago

Wondering if this Node solution actually works? See startStream.

https://github.com/zakmckracken1988/node-arlo-api/blob/master/arlo-api/index.js

chaddotson commented 7 years ago

@ryanwinter Been rereading the thread. Going back to your statement about the camera initiating the stream. I believe this indeed is the case, at least to netgear servers. It seems to me that the camera's poll every few seconds looking for incoming commands.

ryanwinter commented 7 years ago

@chaddotson, this just means that all communications needs to be initiated through Netgears servers. Not really a problem as such, but kind of annoying cause it would be speedier to connect directly through to the camera.

I think the camera maintains a open connection to the server, maybe it polls instead.

chaddotson commented 7 years ago

@ryanwinter agreed no real issue there.

I've not had a chance to look into that node project I found.

It seems simply requesting the URL gets the camera to connect to netgear. Next thing that seems a bit wonky is that the netgear site doesn't get an updated thumbnail unless some video was transferred. Have we fully investigated the post payload?

CarterBrehm commented 7 years ago

Sorry to revive an old thread, but has there been any progress on this? I just got one of the 3-camera systems and I'm really bummed I can't integrate it into my normal HA system.

chaddotson commented 7 years ago

I've been too busy to look into it since my last post. I would still love to be able to script access.

chaddotson commented 6 years ago

@deanmcguire You got it! I've also recently figured out how to get up to date snapshots. I need to write it up and PR it though.

chaddotson commented 6 years ago

Anyone looking for snapshots, just issued the PR https://github.com/tchellomello/python-arlo/pull/65

chaddotson commented 6 years ago

Confirmed working with this package @deanmcguire . Setting user-agent to

'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202 NETGEAR/v1 (iOS Vuezone)'

With this, the camera live_streaming call yields a rtsp link. As he suggests in the other project, this must be changed to the secure rtsps. Once done, ffmpeg will process. I will start a PR for this.

rittet commented 6 years ago

@tchellomello could the fix @deanmcguire link to be applied to the HA-component?

chaddotson commented 6 years ago

Ok. successfully captured frames from the live stream using opencv (assuming the alternative user-agent is set). Thoughts about an optimal user-agent setting?

ghost commented 6 years ago

how do you change the user agent to iPhone, as mentioned above?

ghost commented 6 years ago

Got that working, now how do you keep the stream alive for more than 30 seconds?

tchellomello commented 6 years ago

@chaddotson any success?

Ipaulsen commented 6 years ago

Just jumping into this. I am using this example. I have 3 cameras I can print object with vars about the camera var is set cameras = arlo.GetDevices('camera'),print(cameras[1]). trying to get snapshot from the live stream running into this error when running the example EventStream' object has no attribute 'event_stream_thread. Any ideas?

stefannilsson commented 6 years ago

Any other projects you guys know of that can guide us closer towards the goal?