Skip to content

Commit 19f4342

Browse files
committed
added lowLatency/dvr exception, check for new HLS options, added methods in deprecated class to Client class
1 parent 750e1d1 commit 19f4342

File tree

4 files changed

+170
-17
lines changed

4 files changed

+170
-17
lines changed

opentok/archives.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import pytz
55
from enum import Enum
66

7+
from .exceptions import ArchiveError
8+
79
if PY3:
810
from datetime import timezone
911

opentok/broadcast.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22
from enum import Enum
3-
from six import iteritems, u
3+
from six import u
44

55

66
class Broadcast(object):

opentok/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,11 @@ class BroadcastStreamModeError(OpenTokException):
108108
"""
109109

110110
pass
111+
112+
113+
class BroadcastHLSOptionsError(OpenTokException):
114+
"""
115+
Indicates that HLS options have been set incorrectly.
116+
117+
dvr and lowLatency modes cannot both be set to true in a broadcast.
118+
"""

opentok/opentok.py

Lines changed: 159 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from .broadcast import Broadcast, BroadcastStreamModes
3535
from .exceptions import (
3636
ArchiveStreamModeError,
37+
BroadcastHLSOptionsError,
3738
BroadcastStreamModeError,
3839
OpenTokException,
3940
RequestError,
@@ -47,6 +48,7 @@
4748
SetStreamClassError,
4849
BroadcastError,
4950
DTMFError
51+
5052
)
5153

5254

@@ -1274,8 +1276,8 @@ class names (Strings) to apply to the stream. For example:
12741276

12751277
def start_broadcast(self, session_id, options, stream_mode=BroadcastStreamModes.auto):
12761278
"""
1277-
Use this method to start a live streaming for an OpenTok session. This broadcasts the
1278-
session to an HLS (HTTP live streaming) or to RTMP streams. To successfully start
1279+
Use this method to start a live streaming broadcast for an OpenTok session. This broadcasts
1280+
the session to an HLS (HTTP live streaming) or to RTMP streams. To successfully start
12791281
broadcasting a session, at least one client must be connected to the session. You can only
12801282
start live streaming for sessions that use the OpenTok Media Router (with the media mode set
12811283
to routed); you cannot use live streaming with sessions that have the media mode set to
@@ -1309,7 +1311,8 @@ def start_broadcast(self, session_id, options, stream_mode=BroadcastStreamModes.
13091311
If you include RTMP streaming, you can specify up to five target RTMP streams. For
13101312
each RTMP stream, specify 'serverUrl' (the RTMP server URL), 'streamName' (the stream
13111313
name, such as the YouTube Live stream name or the Facebook stream key), and
1312-
(optionally) 'id' (a unique ID for the stream)
1314+
(optionally) 'id' (a unique ID for the stream). You can optionally specify lowLatency or
1315+
DVR mode, but these options are mutually exclusive.
13131316
13141317
String 'resolution' optional: The resolution of the broadcast, either "640x480"
13151318
(SD, the default) or "1280x720" (HD)
@@ -1322,6 +1325,14 @@ def start_broadcast(self, session_id, options, stream_mode=BroadcastStreamModes.
13221325
:rtype A Broadcast object, which contains information of the broadcast: id, sessionId
13231326
projectId, createdAt, updatedAt, resolution, status and broadcastUrls
13241327
"""
1328+
1329+
if 'hls' in options['outputs']:
1330+
if 'lowLatency' in options['outputs']['hls'] and 'dvr' in options['outputs']['hls']:
1331+
if options['outputs']['hls']['lowLatency'] == True and options['outputs']['hls']['dvr'] == True:
1332+
raise BroadcastHLSOptionsError(
1333+
'HLS options "lowLatency" and "dvr" cannot both be set to "True".'
1334+
)
1335+
13251336
payload = {
13261337
"sessionId": session_id,
13271338
"streamMode": stream_mode.value
@@ -1615,8 +1626,152 @@ def _create_jwt_auth_header(self):
16151626
}
16161627

16171628
return jwt.encode(payload, self.api_secret, algorithm="HS256")
1629+
1630+
1631+
def mute_all(self,
1632+
session_id: str,
1633+
excludedStreamIds: Optional[List[str]]) -> requests.Response:
1634+
1635+
"""
1636+
Mutes all streams in an OpenTok session.
1637+
1638+
You can include an optional list of streams IDs to exclude from being muted.
1639+
1640+
In addition to existing streams, any streams that are published after the call to
1641+
this method are published with audio muted. You can remove the mute state of a session
1642+
by calling the OpenTok.disable_force_mute() method.
1643+
1644+
:param session_id The session ID
1645+
1646+
:param excludedStreamIds A list of stream IDs for streams that should not be muted.
1647+
This is an optional property. If you omit this property, all streams in the session will be muted.
1648+
"""
1649+
1650+
options = {}
1651+
url = self.endpoints.get_mute_all_url(session_id)
1652+
1653+
try:
1654+
if excludedStreamIds:
1655+
options = {'active': True, 'excludedStreams': excludedStreamIds }
1656+
else:
1657+
options = {'active': True, 'excludedStreams': []}
1658+
1659+
response = requests.post(url, headers=self.get_headers(), data=json.dumps(options))
1660+
1661+
if response:
1662+
return response
1663+
elif response.status_code == 400:
1664+
raise GetStreamError("Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID.")
1665+
elif response.status_code == 403:
1666+
raise AuthError("Failed to mute, invalid credentials.")
1667+
elif response.status_code == 404:
1668+
raise NotFoundError("The session or a stream is not found.")
1669+
except Exception as e:
1670+
raise OpenTokException(
1671+
("There was an error thrown by the OpenTok SDK, please check that your session_id {0} and excludedStreamIds (if exists) {1} are valid").format(
1672+
session_id, excludedStreamIds))
1673+
1674+
1675+
def disable_force_mute(self, session_id: str) -> requests.Response:
1676+
"""
1677+
Disables the active mute state of the session. After you call this method, new streams
1678+
published to the session will no longer have audio muted.
1679+
1680+
After you call the mute_all() method, any streams published after
1681+
the call are published with audio muted. Call the OpenTok.disable_force_mute() method
1682+
to remove the mute state of a session, so that new published streams are not
1683+
automatically muted.
1684+
1685+
:param session_id The session ID.
1686+
"""
1687+
1688+
options = {'active': False}
1689+
url = self.endpoints.get_mute_all_url(session_id)
1690+
1691+
response = requests.post(url, headers=self.get_headers(), data=json.dumps(options))
1692+
1693+
1694+
try:
1695+
if response:
1696+
return response
1697+
elif response.status_code == 400:
1698+
raise GetStreamError("Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID.")
1699+
elif response.status_code == 403:
1700+
raise AuthError("Failed to mute, invalid credentials.")
1701+
elif response.status_code == 404:
1702+
raise NotFoundError("The session or a stream is not found.")
1703+
except Exception as e:
1704+
raise OpenTokException(
1705+
("There was an error thrown by the OpenTok SDK, please check that your session_id {0} is valid").format(
1706+
session_id))
1707+
1708+
1709+
def mute_stream(self, session_id: str, stream_id: str) -> requests.Response:
1710+
"""
1711+
Mutes a single stream in an OpenTok session.
1712+
1713+
:param session_id The session ID.
1714+
1715+
:param stream_id The stream ID.
1716+
"""
1717+
1718+
try:
1719+
if stream_id:
1720+
url = self.endpoints.get_stream_url(session_id, stream_id) + "/mute"
1721+
1722+
response = requests.post(url, headers=self.get_headers())
1723+
1724+
if response:
1725+
return response
1726+
elif response.status_code == 400:
1727+
raise GetStreamError("Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID.")
1728+
elif response.status_code == 403:
1729+
raise AuthError("Failed to mute, invalid credentials.")
1730+
elif response.status_code == 404:
1731+
raise NotFoundError("Mute not found")
1732+
except Exception as e:
1733+
raise OpenTokException(
1734+
("There was an error thrown by the OpenTok SDK, please check that your session_id {0} and stream_id {1} are valid").format(
1735+
session_id, stream_id))
16181736

16191737

1738+
def play_dtmf(self, session_id: str, connection_id: str, digits: str, options: dict = {}) -> requests.Response:
1739+
"""
1740+
Plays a DTMF string into a session or to a specific connection
1741+
1742+
:param session_id The ID of the OpenTok session that the participant being called
1743+
will join
1744+
1745+
:param connection_id An optional parameter used to send the DTMF tones to a specific
1746+
connection in a session.
1747+
1748+
:param digits DTMF digits to play
1749+
Valid DTMF digits are 0-9, p, #, and * digits. 'p' represents a 500ms pause if a delay is
1750+
needed during the input process.
1751+
1752+
"""
1753+
1754+
try:
1755+
if not connection_id:
1756+
url = self.endpoints.get_dtmf_all_url(session_id)
1757+
payload = {"digits": digits}
1758+
else:
1759+
url = self.endpoints.get_dtmf_specific_url(session_id, connection_id)
1760+
payload = {"digits": digits}
1761+
1762+
response = requests.post(url, headers=self.get_json_headers(), data=json.dumps(payload))
1763+
1764+
if response.status_code == 200:
1765+
return response
1766+
elif response.status_code == 400:
1767+
raise DTMFError("One of the properties digits, sessionId or connectionId is invalid.")
1768+
elif response.status_code == 403:
1769+
raise AuthError("Failed to create session, invalid credentials. Please check your OpenTok API Key or JSON web token")
1770+
elif response.status_code == 404:
1771+
raise NotFoundError("The session does not exists or the client specified by the connection_id is not connected to the session")
1772+
except Exception as e:
1773+
raise OpenTokException(
1774+
(f"There was an error thrown by the OpenTok SDK, please check that your session_id: {session_id}, connection_id (if exists): {connection_id} and digits: {digits} are valid"))
16201775

16211776
class OpenTok(Client):
16221777
def __init__(
@@ -1646,15 +1801,11 @@ def mute_all(self,
16461801

16471802
"""
16481803
Mutes all streams in an OpenTok session.
1649-
16501804
You can include an optional list of streams IDs to exclude from being muted.
1651-
16521805
In addition to existing streams, any streams that are published after the call to
16531806
this method are published with audio muted. You can remove the mute state of a session
16541807
by calling the OpenTok.disableForceMute() method.
1655-
16561808
:param session_id The session ID
1657-
16581809
:param excludedStreamIds A list of stream IDs for streams that should not be muted.
16591810
This is an optional property. If you omit this property, all streams in the session will be muted.
16601811
"""
@@ -1688,12 +1839,10 @@ def disable_force_mute(self, session_id: str) -> requests.Response:
16881839
"""
16891840
Disables the active mute state of the session. After you call this method, new streams
16901841
published to the session will no longer have audio muted.
1691-
16921842
After you call the mute_all() method, any streams published after
16931843
the call are published with audio muted. Call the OpenTok.disable_force_mute() method
16941844
to remove the mute state of a session, so that new published streams are not
16951845
automatically muted.
1696-
16971846
:param session_id The session ID.
16981847
"""
16991848

@@ -1721,9 +1870,7 @@ def disable_force_mute(self, session_id: str) -> requests.Response:
17211870
def mute_stream(self, session_id: str, stream_id: str) -> requests.Response:
17221871
"""
17231872
Mutes a single stream in an OpenTok session.
1724-
17251873
:param session_id The session ID.
1726-
17271874
:param stream_id The stream ID.
17281875
"""
17291876

@@ -1750,17 +1897,13 @@ def mute_stream(self, session_id: str, stream_id: str) -> requests.Response:
17501897
def play_dtmf(self, session_id: str, connection_id: str, digits: str, options: dict = {}) -> requests.Response:
17511898
"""
17521899
Plays a DTMF string into a session or to a specific connection
1753-
17541900
:param session_id The ID of the OpenTok session that the participant being called
17551901
will join
1756-
17571902
:param connection_id An optional parameter used to send the DTMF tones to a specific
17581903
connectoiin in a session.
1759-
17601904
:param digits DTMF digits to play
17611905
Valid DTMF digits are 0-9, p, #, and * digits. 'p' represents a 500ms pause if a delay is
17621906
needed during the input process.
1763-
17641907
"""
17651908

17661909
try:
@@ -1783,4 +1926,4 @@ def play_dtmf(self, session_id: str, connection_id: str, digits: str, options: d
17831926
raise NotFoundError("The session does not exists or the client specified by the connection_id is not connected to the session")
17841927
except Exception as e:
17851928
raise OpenTokException(
1786-
(f"There was an error thrown by the OpenTok SDK, please check that your session_id: {session_id}, connection_id (if exists): {connection_id} and digits: {digits} are valid"))
1929+
(f"There was an error thrown by the OpenTok SDK, please check that your session_id: {session_id}, connection_id (if exists): {connection_id} and digits: {digits} are valid"))

0 commit comments

Comments
 (0)