Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always use base dsm host to format camera live view paths #137

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/synology_dsm/api/surveillance_station/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def update(self):
if camera_data["id"] in self._cameras_by_id:
self._cameras_by_id[camera_data["id"]].update(camera_data)
else:
self._cameras_by_id[camera_data["id"]] = SynoCamera(camera_data)
self._cameras_by_id[camera_data["id"]] = SynoCamera(
camera_data, self._dsm._base_url
)

for camera_id in self._cameras_by_id:
self._cameras_by_id[camera_id].update_motion_detection(
Expand Down
28 changes: 20 additions & 8 deletions src/synology_dsm/api/surveillance_station/camera.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
"""SurveillanceStation camera."""
from urllib.parse import urlparse
from urllib.parse import urlsplit

from .const import MOTION_DETECTION_DISABLED
from .const import RECORDING_STATUS


class SynoCamera:
"""An representation of a Synology SurveillanceStation camera."""

def __init__(self, data, live_view_data=None):
def __init__(self, data, base_url, live_view_data=None):
"""Initialize a Surveillance Station camera."""
self._data = data
self.live_view = SynoCameraLiveView(live_view_data)
self.live_view = SynoCameraLiveView(live_view_data, urlsplit(base_url).hostname)
self._motion_detection_enabled = None

def update(self, data):
Expand Down Expand Up @@ -66,35 +69,44 @@ def is_recording(self):
class SynoCameraLiveView:
"""An representation of a Synology SurveillanceStation camera live view."""

def __init__(self, data):
def __init__(self, data, base_url):
"""Initialize a Surveillance Station camera live view."""
self._base_url = base_url
self.update(data)

def __format(self, url):
"""Format live stream based on base url."""
parsed_url = urlparse(url)
auth_and_port_parts = parsed_url.netloc.rsplit(parsed_url.hostname, 1)
new_hostname_netloc = self._base_url.join(auth_and_port_parts)
new_url = parsed_url._replace(netloc=new_hostname_netloc)
return new_url.geturl()

def update(self, data):
"""Update the camera live view."""
self._data = data

@property
def mjpeg_http(self):
"""Return the mjpeg stream (over http) path of the camera."""
return self._data["mjpegHttpPath"]
return self.__format(self._data["mjpegHttpPath"])

@property
def multicast(self):
"""Return the multi-cast path of the camera."""
return self._data["multicstPath"]
return self.__format(self._data["multicstPath"])

@property
def mxpeg_http(self):
"""Return the mxpeg stream path of the camera."""
return self._data["mxpegHttpPath"]
return self.__format(self._data["mxpegHttpPath"])

@property
def rtsp_http(self):
"""Return the RTSP stream (over http) path of the camera."""
return self._data["rtspOverHttpPath"]
return self.__format(self._data["rtspOverHttpPath"])

@property
def rtsp(self):
"""Return the RTSP stream path of the camera."""
return self._data["rtspPath"]
return self.__format(self._data["rtspPath"])
7 changes: 6 additions & 1 deletion tests/test_synology_dsm_6.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,12 @@ def test_surveillance_station(self, dsm_6):
assert dsm_6.surveillance_station.get_all_cameras()
assert dsm_6.surveillance_station.get_camera(1)
assert dsm_6.surveillance_station.get_camera_live_view_path(1)
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "rtsp")
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "rtsp") == "rtsp://syno:[email protected]:554/Sms=1.unicast"
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "mjpeg_http") == "http://nas.mywebsite.me:5000/webapi/entry.cgi?api=SYNO.SurveillanceStation.Stream.VideoStreaming&version=1&method=Stream&format=mjpeg&cameraId=1&StmKey=\"stmkey1234567890\""
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "multicast") == "rtsp://syno:[email protected]:554/Sms=1.multicast"
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "mxpeg_http") == "http://nas.mywebsite.me:5000/webapi/entry.cgi?api=SYNO.SurveillanceStation.Stream.VideoStreaming&version=1&method=Stream&format=mxpeg&cameraId=1&StmKey=\"stmkey1234567890\""
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "rtsp_http") == "rtsp://nas.mywebsite.me:5000/webman/3rdparty/SurveillanceStation/cgi/rtsp.cgi?Sms=1.unicast&DsId=0&StmKey=stmkey1234567890"
assert dsm_6.surveillance_station.get_camera_live_view_path(1, "rtsp") == "rtsp://syno:[email protected]:554/Sms=1.unicast"

# Motion detection
assert dsm_6.surveillance_station.enable_motion_detection(1).get("success")
Expand Down