Skip to content

Commit ac08396

Browse files
authored
Merge pull request #199 from opentok/add_mute_feature
Modify mute_all function and add function to disable force mute
2 parents fb5faa7 + 08fea9d commit ac08396

File tree

2 files changed

+90
-38
lines changed

2 files changed

+90
-38
lines changed

opentok/opentok.py

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ def create_session(
407407
proxies=self.proxies,
408408
timeout=self.timeout,
409409
)
410-
410+
411411
response.encoding = "utf-8"
412412

413413
if response.status_code == 403:
@@ -754,13 +754,13 @@ def list_archives(self, offset=None, count=None, session_id=None):
754754
return self.get_archives(offset, count, session_id)
755755

756756
def add_archive_stream(
757-
self,
757+
self,
758758
archive_id: str,
759759
stream_id: str,
760760
has_audio: bool = True,
761-
has_video: bool = True
761+
has_video: bool = True
762762
) -> requests.Response:
763-
763+
764764
"""
765765
This method will add streams to the archive with addStream for new participant(choosing audio, video or both).
766766
@@ -1120,16 +1120,15 @@ def dial(self, session_id, token, sip_uri, options=[]):
11201120
}
11211121
11221122
Boolean 'secure': A Boolean flag that indicates whether the media must be transmitted
1123-
encrypted (true) or not (false, the default)
1123+
encrypted (true) or not (False, the default)
11241124
1125-
Boolean 'observeForceMute': A Boolean flag that determines whether the SIP endpoint should
1126-
honor the force mute action. The force mute action allows a moderator to force clients to
1127-
mute audio in streams they publish. It defaults to False if moderator does not want to observe
1128-
force mute a stream and set to True if the moderator wants to observe force mute a stream.
1125+
Boolean 'observeForceMute': Whether the SIP endpoint should honor a force mute action
1126+
(True) or not (False, the default). A force mute action allows a moderator to force clients to
1127+
mute audio in streams they publish.
11291128
1130-
Boolean 'video': A Boolean flag that indicates whether the SIP call will include video(true)
1131-
or not(false, which is the default). With video included, the SIP client's video is included
1132-
in the OpenTok stream that is sent to the OpenTok session. The SIP client will receive a single
1129+
Boolean 'video': Whether the SIP call will include video (true)
1130+
or not (False, the default). With video included, the SIP client's video is included
1131+
in the OpenTok stream that is sent to the OpenTok session. The SIP client will receive a single
11331132
composed video of the published streams in the OpenTok session.
11341133
11351134
This is an example of what the payload POST data body could look like:
@@ -1154,7 +1153,7 @@ def dial(self, session_id, token, sip_uri, options=[]):
11541153
}
11551154
11561155
1157-
:rtype: A SipCall object, which contains data of the SIP call: id, connectionId and streamId.
1156+
:rtype: A SipCall object, which contains data of the SIP call: id, connectionId and streamId.
11581157
This is what the response body should look like after returning with a status code of 200:
11591158
11601159
{
@@ -1184,7 +1183,7 @@ def dial(self, session_id, token, sip_uri, options=[]):
11841183
if "observeForceMute" in options:
11851184
observeForceMute = True
11861185
payload["sip"]["observeForceMute"] = options["observeForceMute"]
1187-
1186+
11881187
if "video" in options:
11891188
video = True
11901189
payload["sip"]["video"] = options["video"]
@@ -1382,7 +1381,7 @@ def stop_broadcast(self, broadcast_id):
13821381
self.json_headers(),
13831382
self.proxies,
13841383
)
1385-
1384+
13861385
response = requests.post(
13871386
endpoint,
13881387
headers=self.get_json_headers(),
@@ -1408,13 +1407,13 @@ def stop_broadcast(self, broadcast_id):
14081407
raise RequestError("OpenTok server error.", response.status_code)
14091408

14101409
def add_broadcast_stream(
1411-
self,
1410+
self,
14121411
broadcast_id: str,
14131412
stream_id: str,
14141413
has_audio: bool = True,
1415-
has_video: bool = True
1414+
has_video: bool = True
14161415
) -> requests.Response:
1417-
1416+
14181417
"""
14191418
This method will add streams to the broadcast with addStream for new participant(choosing audio, video or both).
14201419
@@ -1462,7 +1461,7 @@ def add_broadcast_stream(
14621461
else:
14631462
raise RequestError("OpenTok server error.", response.status_code)
14641463

1465-
1464+
14661465
def remove_broadcast_stream(self, broadcast_id: str, stream_id: str) -> requests.Response:
14671466
"""
14681467
This method will remove streams from the broadcast with removeStream.
@@ -1616,8 +1615,8 @@ def _create_jwt_auth_header(self):
16161615
}
16171616

16181617
return jwt.encode(payload, self.api_secret, algorithm="HS256")
1619-
1620-
1618+
1619+
16211620

16221621
class OpenTok(Client):
16231622
def __init__(
@@ -1641,36 +1640,34 @@ def __init__(
16411640
app_version=app_version
16421641
)
16431642

1644-
def mute_all(self,
1645-
session_id: str,
1646-
excludedStreamIds: Optional[List[str]],
1647-
active: bool= True) -> requests.Response:
1643+
def mute_all(self,
1644+
session_id: str,
1645+
excludedStreamIds: Optional[List[str]]) -> requests.Response:
16481646

16491647
"""
16501648
Mutes all streams in an OpenTok session.
16511649
1652-
You can include an optional list of streams IDs to exclude from being muted.
1650+
You can include an optional list of streams IDs to exclude from being muted.
1651+
1652+
In addition to existing streams, any streams that are published after the call to
1653+
this method are published with audio muted. You can remove the mute state of a session
1654+
by calling the OpenTok.disableForceMute() method.
16531655
16541656
:param session_id The session ID
16551657
1656-
:param excludedStreamIds A list of stream IDs for streams that should not be muted.
1658+
:param excludedStreamIds A list of stream IDs for streams that should not be muted.
16571659
This is an optional property. If you omit this property, all streams in the session will be muted.
1658-
1659-
:param active Whether streams published after the call, in addition to the current streams
1660-
in the session, should be muted (True) or not (False).
16611660
"""
16621661

16631662
options = {}
16641663
url = self.endpoints.get_mute_all_url(session_id)
16651664

16661665
try:
16671666
if excludedStreamIds:
1668-
if active:
1669-
options = {'active': active, 'excludedStreams': excludedStreamIds }
1667+
options = {'active': True, 'excludedStreams': excludedStreamIds }
16701668
else:
1671-
active = False
1672-
options = {'active': active, 'excludedStreams': []}
1673-
1669+
options = {'active': True, 'excludedStreams': []}
1670+
16741671
response = requests.post(url, headers=self.get_headers(), data=json.dumps(options))
16751672

16761673
if response:
@@ -1686,15 +1683,48 @@ def mute_all(self,
16861683
("There was an error thrown by the OpenTok SDK, please check that your session_id {0} and excludedStreamIds (if exists) {1} are valid").format(
16871684
session_id, excludedStreamIds))
16881685

1689-
1686+
1687+
def disable_force_mute(self, session_id: str) -> requests.Response:
1688+
"""
1689+
Disables the active mute state of the session. After you call this method, new streams
1690+
published to the session will no longer have audio muted.
1691+
1692+
After you call the mute_all() method, any streams published after
1693+
the call are published with audio muted. Call the OpenTok.disable_force_mute() method
1694+
to remove the mute state of a session, so that new published streams are not
1695+
automatically muted.
1696+
1697+
:param session_id The session ID.
1698+
"""
1699+
1700+
options = {'active': False}
1701+
url = self.endpoints.get_mute_all_url(session_id)
1702+
1703+
response = requests.post(url, headers=self.get_headers(), data=json.dumps(options))
1704+
1705+
1706+
try:
1707+
if response:
1708+
return response
1709+
elif response.status_code == 400:
1710+
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.")
1711+
elif response.status_code == 403:
1712+
raise AuthError("Failed to mute, invalid credentials.")
1713+
elif response.status_code == 404:
1714+
raise NotFoundError("The session or a stream is not found.")
1715+
except Exception as e:
1716+
raise OpenTokException(
1717+
("There was an error thrown by the OpenTok SDK, please check that your session_id {0} is valid").format(
1718+
session_id))
1719+
16901720

16911721
def mute_stream(self, session_id: str, stream_id: str) -> requests.Response:
16921722
"""
16931723
Mutes a single stream in an OpenTok session.
16941724
16951725
:param session_id The session ID.
16961726
1697-
:param stream_id The stream iD.
1727+
:param stream_id The stream ID.
16981728
"""
16991729

17001730
try:
@@ -1754,4 +1784,3 @@ def play_dtmf(self, session_id: str, connection_id: str, digits: str, options: d
17541784
except Exception as e:
17551785
raise OpenTokException(
17561786
(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"))
1757-

tests/test_opentok.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,29 @@ def test_mute_all_exclude_streams(self):
5252
response.headers["x-opentok-auth"].should.equal(self.jwt_token_string)
5353
response.headers["Content-Type"].should.equal("application/json")
5454

55+
@httpretty.activate
56+
def test_disable_force_mute(self):
57+
self.url = "https://api.opentok.com/v2/project/{0}/session/{1}/mute".format(
58+
self.api_key,
59+
self.session_id)
60+
61+
httpretty.register_uri(httpretty.POST,
62+
self.url,
63+
responses=[
64+
httpretty.Response(body='{}',
65+
content_type="application/json",
66+
adding_headers= {"x-opentok-auth": self.jwt_token_string},
67+
status=201)
68+
])
69+
70+
71+
response = requests.post(self.url)
72+
73+
response.text.should.equal('{}')
74+
response.headers["x-opentok-auth"].should.equal(self.jwt_token_string)
75+
response.headers["Content-Type"].should.equal("application/json")
76+
77+
5578
@httpretty.activate
5679
def test_mute_single_stream(self):
5780
self.url = "https://api.opentok.com/v2/project/{0}/session/{1}/stream/{2}/mute".format(

0 commit comments

Comments
 (0)