Skip to content

Commit 1e868e2

Browse files
authored
Merge pull request #1078 from mback2k/livestreaming
Support for MPEG-TS livestreaming via local TCP proxy server
2 parents 1c99eff + 4a1ef43 commit 1e868e2

File tree

6 files changed

+1255
-11
lines changed

6 files changed

+1255
-11
lines changed

blinkpy/api.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,18 @@ async def request_command_status(blink, network, command_id):
230230
return await http_get(blink, url)
231231

232232

233+
async def request_command_done(blink, network, command_id):
234+
"""
235+
Request command to be done.
236+
237+
:param blink: Blink instance.
238+
:param network: Sync module network id.
239+
:param command_id: Command id to mark as done.
240+
"""
241+
url = f"{blink.urls.base_url}/network/{network}/command/{command_id}/done/"
242+
return await http_post(blink, url)
243+
244+
233245
@Throttle(seconds=MIN_THROTTLE_TIME)
234246
async def request_homescreen(blink, **kwargs):
235247
"""Request homescreen info."""
@@ -347,7 +359,8 @@ async def request_camera_liveview(blink, network, camera_id):
347359
f"{blink.urls.base_url}/api/v5/accounts/{blink.account_id}"
348360
f"/networks/{network}/cameras/{camera_id}/liveview"
349361
)
350-
response = await http_post(blink, url)
362+
data = dumps({"intent": "liveview"})
363+
response = await http_post(blink, url, data=data)
351364
await wait_for_command(blink, response)
352365
return response
353366

@@ -561,6 +574,7 @@ async def wait_for_command(blink, json_data: dict) -> bool:
561574
network_id = json_data.get("network_id")
562575
command_id = json_data.get("id")
563576
except AttributeError:
577+
_LOGGER.exception("No network_id or id in response")
564578
return False
565579
if command_id and network_id:
566580
for _ in range(0, MAX_RETRY):
@@ -573,3 +587,5 @@ async def wait_for_command(blink, json_data: dict) -> bool:
573587
if status.get("complete"):
574588
return True
575589
await sleep(COMMAND_POLL_TIME)
590+
else:
591+
_LOGGER.debug("No network_id or id in response")

blinkpy/camera.py

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from blinkpy import api
1414
from blinkpy.helpers.constants import TIMEOUT_MEDIA
1515
from blinkpy.helpers.util import to_alphanumeric
16+
from blinkpy.livestream import BlinkLiveStream
1617

1718
_LOGGER = logging.getLogger(__name__)
1819

@@ -413,6 +414,15 @@ async def get_liveview(self):
413414
)
414415
return response["server"]
415416

417+
async def init_livestream(self):
418+
"""Initialize livestream."""
419+
response = await api.request_camera_liveview(
420+
self.sync.blink, self.sync.network_id, self.camera_id
421+
)
422+
if not response["server"].startswith("immis://"):
423+
raise NotImplementedError("Unsupported: {}".format(response["server"]))
424+
return BlinkLiveStream(self, response)
425+
416426
async def image_to_file(self, path):
417427
"""
418428
Write image to file.
@@ -548,13 +558,24 @@ async def get_liveview(self):
548558
f"{self.sync.blink.account_id}/networks/"
549559
f"{self.network_id}/owls/{self.camera_id}/liveview"
550560
)
551-
response = await api.http_post(self.sync.blink, url)
561+
data = dumps({"intent": "liveview"})
562+
response = await api.http_post(self.sync.blink, url, data=data)
563+
await api.wait_for_command(self.sync.blink, response)
564+
return response["server"]
565+
566+
async def init_livestream(self):
567+
"""Initialize livestream."""
568+
url = (
569+
f"{self.sync.urls.base_url}/api/v1/accounts/"
570+
f"{self.sync.blink.account_id}/networks/"
571+
f"{self.network_id}/owls/{self.camera_id}/liveview"
572+
)
573+
data = dumps({"intent": "liveview"})
574+
response = await api.http_post(self.sync.blink, url, data=data)
552575
await api.wait_for_command(self.sync.blink, response)
553-
server = response["server"]
554-
server_split = server.split(":")
555-
server_split[0] = "rtsps"
556-
link = ":".join(server_split)
557-
return link
576+
if not response["server"].startswith("immis://"):
577+
raise NotImplementedError("Unsupported: {}".format(response["server"]))
578+
return BlinkLiveStream(self, response)
558579

559580

560581
class BlinkDoorbell(BlinkCamera):
@@ -620,8 +641,21 @@ async def get_liveview(self):
620641
f"{self.sync.blink.account_id}/networks/"
621642
f"{self.sync.network_id}/doorbells/{self.camera_id}/liveview"
622643
)
623-
response = await api.http_post(self.sync.blink, url)
644+
data = dumps({"intent": "liveview"})
645+
response = await api.http_post(self.sync.blink, url, data=data)
646+
await api.wait_for_command(self.sync.blink, response)
647+
return response["server"]
648+
649+
async def init_livestream(self):
650+
"""Initialize livestream."""
651+
url = (
652+
f"{self.sync.urls.base_url}/api/v1/accounts/"
653+
f"{self.sync.blink.account_id}/networks/"
654+
f"{self.sync.network_id}/doorbells/{self.camera_id}/liveview"
655+
)
656+
data = dumps({"intent": "liveview"})
657+
response = await api.http_post(self.sync.blink, url, data=data)
624658
await api.wait_for_command(self.sync.blink, response)
625-
server = response["server"]
626-
link = server.replace("immis://", "rtsps://")
627-
return link
659+
if not response["server"].startswith("immis://"):
660+
raise NotImplementedError("Unsupported: {}".format(response["server"]))
661+
return BlinkLiveStream(self, response)

0 commit comments

Comments
 (0)