{"id":19845464,"url":"https://github.com/opentok/opentok-python-sdk","last_synced_at":"2025-05-15T12:02:30.904Z","repository":{"id":1745792,"uuid":"2571725","full_name":"opentok/Opentok-Python-SDK","owner":"opentok","description":"OpenTok Python SDK","archived":false,"fork":false,"pushed_at":"2025-04-30T12:49:02.000Z","size":763,"stargazers_count":73,"open_issues_count":2,"forks_count":83,"subscribers_count":57,"default_branch":"main","last_synced_at":"2025-05-15T12:02:03.302Z","etag":null,"topics":["opentok","python","python-sdk","tokbox"],"latest_commit_sha":null,"homepage":"https://tokbox.com/developer/sdks/python/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opentok.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2011-10-13T19:14:51.000Z","updated_at":"2025-04-30T12:49:06.000Z","dependencies_parsed_at":"2024-01-12T07:37:59.790Z","dependency_job_id":"fbf25c0b-94f2-4d92-844d-b9f6625b3ad3","html_url":"https://github.com/opentok/Opentok-Python-SDK","commit_stats":{"total_commits":357,"total_committers":32,"mean_commits":11.15625,"dds":0.7787114845938375,"last_synced_commit":"24a7e732308129834e48d65ed8fe20ad008ce626"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentok%2FOpentok-Python-SDK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentok%2FOpentok-Python-SDK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentok%2FOpentok-Python-SDK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentok%2FOpentok-Python-SDK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opentok","download_url":"https://codeload.github.com/opentok/Opentok-Python-SDK/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opentok","python","python-sdk","tokbox"],"created_at":"2024-11-12T13:07:59.309Z","updated_at":"2025-05-15T12:02:30.809Z","avatar_url":"https://github.com/opentok.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"==================\nOpenTok Python SDK\n==================\n\n.. image:: https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg \n   :target: CODE_OF_CONDUCT.md\n\n.. image:: https://assets.tokbox.com/img/vonage/Vonage_VideoAPI_black.svg\n   :height: 48px\n   :alt: Tokbox is now known as Vonage\n\nThe OpenTok Python SDK lets you generate\n`sessions \u003chttp://tokbox.com/opentok/tutorials/create-session/\u003e`_ and\n`tokens \u003chttp://tokbox.com/opentok/tutorials/create-token/\u003e`_ for `OpenTok \u003chttp://www.tokbox.com/\u003e`_\napplications, and `archive \u003chttp://www.tokbox.com/platform/archiving\u003e`_ OpenTok sessions.\n\nNote!\n-----\n\nThis library is designed to work with the Tokbox/OpenTok platform, part of the Vonage Video API. If you are looking to use the Vonage Video API and are using the Vonage Customer Dashboard, you will want to install the `Vonage Server SDK for Python \u003chttps://github.com/Vonage/vonage-python-sdk\u003e`_, which includes support for the Vonage Video API.\n\nNot sure which exact platform you are using? Take a look at `this guide \u003chttps://api.support.vonage.com/hc/en-us/articles/10817774782492\u003e`_.\n\nIf you are using the Tokbox platform, do not worry! The Tokbox platform is not going away, and this library will continue to be updated. While we encourage customers to check out the new Unified platform, there is no rush to switch. Both platforms run the exact same infrastructure and capabilities. The main difference is a unified billing interface and easier access to `Vonage's other CPaaS APIs \u003chttps://www.vonage.com/communications-apis/\u003e`_.\n\nIf you are new to the Vonage Video API, head on over to the `Vonage Customer Dashboard \u003chttps://dashboard.vonage.com\u003e`_ to sign up for a developer account and check out the `Vonage Server SDK for Python \u003chttps://github.com/Vonage/vonage-python-sdk\u003e`_. \n\n\nInstallation using Pip (recommended):\n-------------------------------------\n\nPip helps manage dependencies for Python projects using the PyPI index. Find more info here:\nhttp://www.pip-installer.org/en/latest/\n\nAdd the ``opentok`` package as a dependency in your project. The most common way is to add it to your\n``requirements.txt`` file::\n\n  opentok\u003e=3.0\n\nNext, install the dependencies::\n\n  $ pip install -r requirements.txt\n\n\nUsage\n-----\n\nInitializing\n~~~~~~~~~~~~\n\nImport the package at the top of any file where you will use it. At the very least you will need the\n``Client`` class. Then initialize a Client instance with your own API Key and API Secret.\n\n.. code:: python\n\n  from opentok import Client\n\n  opentok = Client(api_key, api_secret)\n\nCreating Sessions\n~~~~~~~~~~~~~~~~~\n\nTo create an OpenTok Session, use the ``opentok.create_session()`` method. There are optional\nkeyword parameters for this method:\n\n* ``location`` which can be set to a string containing an IP address.\n\n* ``media_mode`` which is a String (defined by the MediaModes class).\n  This determines whether the session will use the\n  `OpenTok Media Router \u003chttps://tokbox.com/developer/guides/create-session/#media-mode\u003e`_\n  or attempt to send streams directly between clients. A routed session is required for some\n  OpenTok features (such as archiving).\n\n* ``archive_mode`` which specifies whether the session will be automatically archived (``always``)\n  or not (``manual``).\n\n* ``archive_name`` which indicates the archive name for all the archives in auto archived session. \n  A session that begins with archive mode 'always' will be using this archive name for all archives of that session.\n  Passing 'archive_name' with archive mode 'manual' will cause an error response.\n\n* ``archive_resolution`` which indicates the archive resolution for all the archives in auto archived session.\n  Valid values are '640x480', '480x640', '1280x720', '720x1280', '1920x1080' and '1080x1920'.\n  A session that begins with archive mode 'always' will be using this resolution for all archives of that session.\n  Passing 'archive_resolution' with archive mode 'manual' will cause an error response.\n\n* ``e2ee`` which is a boolean. This specifies whether to enable\n  `end-to-end encryption \u003chttps://tokbox.com/developer/guides/end-to-end-encryption/\u003e`_\n  for the OpenTok session.\n\nThis method returns a ``Session`` object. Its ``session_id`` attribute is useful when saving to a persistent\nstore (such as a database).\n\n.. code:: python\n\n  # Create a session that attempts to send streams directly between clients (falling back\n  # to use the OpenTok TURN server to relay streams if the clients cannot connect):\n  session = opentok.create_session()\n\n  from opentok import MediaModes\n  # A session that uses the OpenTok Media Router, which is required for archiving:\n  session = opentok.create_session(media_mode=MediaModes.routed)\n\n  # An automatically archived session:\n  session = opentok.create_session(media_mode=MediaModes.routed, archive_mode=ArchiveModes.always)\n\n  # An automatically archived session with the archive name and resolution specified:\n  session = opentok.create_session(\n    media_mode=MediaModes.routed,\n    archive_mode=ArchiveModes.always,\n    archive_name='my_archive',\n    archive_resolution='1920x1080'\n  )\n\n  # A session with a location hint\n  session = opentok.create_session(location=u'12.34.56.78')\n\n  # Store this session ID in the database\n  session_id = session.session_id\n\nGenerating Tokens\n~~~~~~~~~~~~~~~~~\n\nOnce a Session is created, you can start generating Tokens for clients to use when connecting to it.\nYou can generate a token either by calling the ``opentok.generate_token(session_id)`` method or by\ncalling the ``session.generate_token()`` method on a ``Session`` instance after creating it. Both\nhave a set of optional keyword parameters: ``role``, ``expire_time``, ``data``, and\n``initial_layout_class_list``.\n\n.. code:: python\n\n  # Generate a Token from just a session_id (fetched from a database)\n  token = opentok.generate_token(session_id)\n  # Generate a Token by calling the method on the Session (returned from create_session)\n  token = session.generate_token()\n\n  from opentok import Roles\n  # Set some options in a token\n  token = session.generate_token(role=Roles.moderator,\n                                 expire_time=int(time.time()) + 10,\n                                 data=u'name=Johnny'\n                                 initial_layout_class_list=[u'focus'])\n\nWorking with Archives\n~~~~~~~~~~~~~~~~~~~~~\n\nYou can only archive sessions that use the OpenTok Media\nRouter (sessions with the media mode set to routed).\n\nYou can start the recording of an OpenTok Session using the ``opentok.start_archive(session_id)``\nmethod. This method takes an optional keyword argument ``name`` to assign a name to the archive.\nThis method will return an ``Archive`` instance. Note that you can only start an Archive on\na Session that has clients connected.\n\n.. code:: python\n\n  archive = opentok.start_archive(session_id, name=u'Important Presentation')\n\n  # Store this archive_id in the database\n  archive_id = archive.id\n\nYou can also disable audio or video recording by setting the `has_audio` or `has_video` property of\nthe `options` parameter to `false`:\n\n.. code:: python\n\n  archive = opentok.start_archive(session_id, name=u'Important Presentation', has_video=False)\n\n  # Store this archive_id in the database\n  archive_id = archive.id\n\nBy default, all streams are recorded to a single (composed) file. You can record the different\nstreams in the session to individual files (instead of a single composed file) by setting the\n``output_mode`` parameter of the ``opentok.start_archive()`` method `OutputModes.individual`.\n\n.. code:: python\n\n  archive = opentok.start_archive(session_id, name=u'Important Presentation', output_mode=OutputModes.individual)\n\n  # Store this archive_id in the database\n  archive_id = archive.id\n\nTo add an individual stream to an archive, use the\n``opentok.add_archive_stream(archive_id, stream_id, has_audio, has_video)`` method:\n\n.. code:: python\n\n  opentok.add_archive_stream(archive.id, stream_id, has_audio=True, has_video=True)\n\nTo remove a stream from an archive, use the ``opentok.remove_archive_stream()`` method:\n\n.. code:: python\n\n  opentok.remove_archive_stream(archive.id, stream_id)\n\nComposed archives (output_mode=OutputModes.composed) have an optional ``resolution`` parameter.\nIf no value is supplied, the archive will use the default resolution, \"640x480\".\nYou can set this to another resolution by setting the\n``resolution`` parameter of the ``opentok.start_archive()`` method.\n\nYou can specify the following archive resolutions:\n\n* \"640x480\" (SD landscape, default resolution)\n* \"480x640\" (SD portrait)\n* \"1280x720\" (HD landscape)\n* \"720x1280\" (HD portrait)\n* \"1920x1080\" (FHD landscape)\n* \"1080x1920\" (FHD portrait)\n\nSetting the ``resolution`` parameter while setting the ``output_mode`` parameter to\n``OutputModes.individual`` results in an error.\n\n.. code:: python\n\n  archive = opentok.start_archive(session_id, name=u'Important Presentation', resolution=\"1280x720\")\n\n  # Store this archive_id in the database\n  archive_id = archive.id\n\nYou can enable multiple simultaneous archives by specifying a unique value for the ``multi_archive_tag`` \nparameter in the ``start_archive`` method.\n\n.. code:: python\n\n  archive = opentok.start_archive(session_id, name=u'Important Presentation', multi_archive_tag='MyArchiveTag')\n\nYou can stop the recording of a started Archive using the ``opentok.stop_archive(archive_id)``method. \nYou can also do this using the ``archive.stop()`` method of an ``Archive`` instance.\n\n.. code:: python\n\n  # Stop an Archive from an archive_id (fetched from database)\n  opentok.stop_archive(archive_id)\n  # Stop an Archive from an instance (returned from opentok.start_archive)\n  archive.stop()\n\nTo get an ``Archive`` instance (and all the information about it) from an archive ID, use the\n``opentok.get_archive(archive_id)`` method.\n\n.. code:: python\n\n  archive = opentok.get_archive(archive_id)\n\nTo delete an Archive, you can call the ``opentok.delete_archive(archive_id)`` method or the\n``archive.delete()`` method of an ``Archive`` instance.\n\n.. code:: python\n\n  # Delete an Archive from an archive ID (fetched from database)\n  opentok.delete_archive(archive_id)\n  # Delete an Archive from an Archive instance (returned from opentok.start_archive or\n  opentok.get_archive)\n  archive.delete()\n\nYou can also get a list of all the Archives you've created (up to 1000) with your API Key. This is\ndone using the ``opentok.list_archives()`` method. There are three optional keyword parameters:\n``count``, ``offset`` and ``session_id``; they can help you paginate through the results and\nfilter by session ID. This method returns an instance of the ``ArchiveList`` class.\n\n.. code:: python\n\n  archive_list = opentok.list_archives()\n\n  # Get a specific Archive from the list\n  archive = archive_list.items[i]\n\n  # Iterate over items\n  for archive in iter(archive_list):\n    pass\n\n  # Get the total number of Archives for this API Key\n  total = archive_list.total\n\nNote that you can also create an automatically archived session, by passing in\n``ArchiveModes.always`` as the ``archive_mode`` parameter when you call the\n``opentok.create_session()`` method (see \"Creating Sessions,\" above).\n\nFor composed archives, you can change the layout dynamically, using the `opentok.set_archive_layout(archive_id, type, stylesheet)` method:\n\n.. code:: python\n\n  opentok.set_archive_layout('ARCHIVEID', 'horizontalPresentation')\n\nSetting the layout of composed archives is optional. By default, composed archives use the `best fit` layout.  Other valid values are: `custom`, `horizontalPresentation`, `pip` and `verticalPresentation`. If you specify a `custom` layout type, set the stylesheet parameter:\n\n.. code:: python\n\n  opentok.set_archive_layout(\n      'ARCHIVEID',\n      'custom',\n      'stream.instructor {position: absolute; width: 100%;  height:50%;}'\n  )\n\nFor other layout types, do not set the stylesheet property. For more information see\n`Customizing the video layout for composed archives \u003chttps://tokbox.com/developer/guides/archiving/layout-control.html\u003e`_.\n\nFor more information on archiving, see the\n`OpenTok archiving \u003chttps://tokbox.com/opentok/tutorials/archiving/\u003e`_ programming guide.\n\nSending Signals\n~~~~~~~~~~~~~~~~~~~~~\n\nOnce a Session is created, you can send signals to everyone in the session or to a specific connection. You can send a signal by calling the ``signal(session_id, payload)`` method of the ``Client`` class. The ``payload`` parameter is a dictionary used to set the ``type``, ``data`` fields. Ỳou can also call the method with the parameter ``connection_id`` to send a signal to a specific connection ``signal(session_id, data, connection_id)``.\n\n.. code:: python\n\n  # payload structure\n  payload = {\n      'type': 'type', #optional\n      'data': 'signal data' #required\n  }\n\n  connection_id = '2a84cd30-3a33-917f-9150-49e454e01572'\n\n  # To send a signal to everyone in the session:\n  opentok.signal(session_id, payload)\n\n  # To send a signal to a specific connection in the session:\n  opentok.signal(session_id, payload, connection_id)\n\nWorking with Streams\n~~~~~~~~~~~~~~~~~~~~~\n\nYou can get information about a stream by calling the `get_stream(session_id, stream_id)` method of the `Client` class.\n\nThe method returns a Stream object that contains information of an OpenTok stream:\n\n* ``id``: The stream ID\n* ``videoType``: \"camera\" or \"screen\"\n* ``name``: The stream name (if one was set when the client published the stream)\n* ``layoutClassList``: It's an array of the layout classes for the stream\n\n.. code:: python\n\n  session_id = 'SESSIONID'\n  stream_id = '8b732909-0a06-46a2-8ea8-074e64d43422'\n\n  # To get stream info:\n  stream = opentok.get_stream(session_id, stream_id)\n\n  # Stream properties:\n  print stream.id #8b732909-0a06-46a2-8ea8-074e64d43422\n  print stream.videoType #camera\n  print stream.name #stream name\n  print stream.layoutClassList #['full']\n\nAlso, you can get information about all the streams in a session by calling the `list_streams(session_id)` method of the `Client` class.\n\nThe method returns a StreamList object that contains a list of all the streams\n\n.. code:: python\n\n  # To get all streams in a session:\n  stream_list = opentok.list_streams(session_id)\n\n  # Getting the first stream of the list\n  stream = stream_list.items[0]\n\n  # Stream properties:\n  print stream.id #8b732909-0a06-46a2-8ea8-074e64d43422\n  print stream.videoType #camera\n  print stream.name #stream name\n  print stream.layoutClassList #['full']\n\nYou can change the layout classes for streams in a session by calling the `set_stream_class_lists(session_id, stream_list)` method of the `Client` class.\n\nThe layout classes define how the stream is displayed in the layout of a composed OpenTok archive.\n\n.. code:: python\n\n  # This list contains the information of the streams that will be updated. Each element\n  # in the list is a dictionary with two properties: 'id' and 'layoutClassList'. The 'id'\n  # property is the stream ID (a String), and the 'layoutClassList' is an array of class\n  # names (Strings) to apply to the stream.\n  payload = [\n      {'id': '7b09ec3c-26f9-43d7-8197-f608f13d4fb6', 'layoutClassList': ['focus']},\n      {'id': '567bc941-6ea0-4c69-97fc-70a740b68976', 'layoutClassList': ['top']},\n      {'id': '307dc941-0450-4c09-975c-705740d08970', 'layoutClassList': ['bottom']}\n  ]\n\n  opentok.set_stream_class_lists('SESSIONID', payload)\n\nFor more information see\n`Changing the composed archive layout classes for an OpenTok stream \u003chttps://tokbox.com/developer/rest/#change-stream-layout-classes-composed\u003e`_.\n\nForce Disconnect\n~~~~~~~~~~~~~~~~~~~~~\n\nYour application server can disconnect a client from an OpenTok session by calling the force_disconnect(session_id, connection_id) method of the Client class, or the force_disconnect(connection_id) method of the Session class.\n\n.. code:: python\n\n  session_id = 'SESSIONID'\n  connection_id = 'CONNECTIONID'\n\n  # To send a request to disconnect a client:\n  opentok.force_disconnect(session_id, connection_id)\n\nWorking with SIP Interconnect\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can connect your SIP platform to an OpenTok session, the audio from your end of the SIP call is added to the OpenTok session as an audio-only stream. \nThe OpenTok Media Router mixes audio from other streams in the session and sends the mixed audio to your SIP endpoint.\n\n.. code:: python\n\n  session_id = u('SESSIONID')\n  token = u('TOKEN')\n  sip_uri = u('sip:user@sip.partner.com;transport=tls')\n\n  # call the method with the required parameters\n  sip_call = opentok.dial(session_id, token, sip_uri)\n\n  # the method also supports aditional options to establish the sip call\n  options = {\n      'from': 'from@example.com',\n      'headers': {\n          'headerKey': 'headerValue'\n      },\n      'auth': {\n          'username': 'username',\n          'password': 'password'\n      },\n      'secure': True,\n      'video': True,\n      'observeForceMute': True,\n      'streams': ['stream-id-1', 'stream-id-2']\n  }\n\n  # call the method with aditional options\n  sip_call = opentok.dial(session_id, token, sip_uri, options)\n\nFor more information, including technical details and security considerations, see the\n`OpenTok SIP interconnect \u003chttps://tokbox.com/developer/guides/sip/\u003e`_ developer guide.\n\nWorking with Broadcasts\n~~~~~~~~~~~~~~~~~~~~~~~\n\nOpenTok broadcast lets you share live OpenTok sessions with many viewers.\n\nYou can use the ``opentok.start_broadcast()`` method to start a live stream for an OpenTok session.\nThis broadcasts the session to HLS (HTTP live streaming) or to RTMP streams.\n\nTo successfully start broadcasting a session, at least one client must be connected to the session.\n\nThe live streaming broadcast can target one HLS endpoint and up to five RTMP servers simulteneously for a session. You can only start live streaming for sessions that use the OpenTok Media Router; you cannot use live streaming with sessions that have the media mode set to relayed.\n\n.. code:: python\n\n  session_id = 'SESSIONID'\n  options = {\n    'layout': {\n      'type': 'custom',\n      'stylesheet': 'the layout stylesheet (only used with type == custom)'\n    },\n    'maxDuration': 5400,\n    'hasAudio': True,\n    'hasVideo': True,\n    'maxBitrate': 2000000,\n    'outputs': {\n      'hls': {},\n      'rtmp': [{\n        'id': 'foo',\n        'serverUrl': 'rtmp://myfooserver/myfooapp',\n        'streamName': 'myfoostream'\n      }, {\n        'id': 'bar',\n        'serverUrl': 'rtmp://mybarserver/mybarapp',\n        'streamName': 'mybarstream'\n      }]\n    },\n    'resolution': '640x480'\n  }\n\n  broadcast = opentok.start_broadcast(session_id, options)\n\nYou can specify the following broadcast resolutions:\n\n* \"640x480\" (SD landscape, default resolution)\n* \"480x640\" (SD portrait)\n* \"1280x720\" (HD landscape)\n* \"720x1280\" (HD portrait)\n* \"1920x1080\" (FHD landscape)\n* \"1080x1920\" (FHD portrait)\n\nYou can specify a maximum bitrate between 100000 and 6000000.\n\n.. code:: python\n\n  session_id = 'SESSIONID'\n  options = {\n    'multiBroadcastTag': 'unique_broadcast_tag'\n    'layout': {\n      'type': 'custom',\n      'stylesheet': 'the layout stylesheet (only used with type == custom)'\n    },\n    'maxDuration': 5400,\n    'maxBitrate': 2000000,\n    'outputs': {\n      'hls': {},\n      'rtmp': [{\n        'id': 'foo',\n        'serverUrl': 'rtmp://myfooserver/myfooapp',\n        'streamName': 'myfoostream'\n      }, {\n        'id': 'bar',\n        'serverUrl': 'rtmp://mybarserver/mybarapp',\n        'streamName': 'mybarstream'\n      }]\n    },\n    'resolution': '640x480'\n  }\n\n  broadcast = opentok.start_broadcast(session_id, options)\n  \nTo enable multiple simultaneous broadcasts on the same session, specify a unique value for the \n``multiBroadcastTag`` parameter in ``options`` when calling the ``opentok.start_broadcast`` method.\n\nYou can broadcast only audio, or only video, for a stream by setting ``hasAudio`` or ``hasVideo``\nto ``False`` as required. These fields are ``True`` by default.\n\n.. code:: python\n\n  session_id = 'SESSIONID'\n  options = {\n    'layout': {\n      'type': 'custom',\n      'stylesheet': 'the layout stylesheet (only used with type == custom)'\n    },\n    'maxDuration': 5400,\n    'hasAudio': True,\n    'hasVideo': False,\n    'maxBitrate': 2000000,\n    'outputs': {\n      'hls': {},\n      'rtmp': [{\n        'id': 'foo',\n        'serverUrl': 'rtmp://myfooserver/myfooapp',\n        'streamName': 'myfoostream'\n      }, {\n        'id': 'bar',\n        'serverUrl': 'rtmp://mybarserver/mybarapp',\n        'streamName': 'mybarstream'\n      }]\n    },\n    'resolution': '640x480'\n  }\n\n  broadcast = opentok.start_broadcast(session_id, options)\n\nYou can stop a started Broadcast using the ``opentok.stop_broadcast(broadcast_id)`` method.\n\n.. code:: python\n\n  # getting the ID from a broadcast object\n  broadcast_id = broadcast.id\n\n  # stop a broadcast\n  broadcast = opentok.stop_broadcast(broadcast_id)\n\nYou can get details on a broadcast that is in-progress using the method ``opentok.get_broadcast(broadcast_id)``.\n\n.. code:: python\n\n  broadcast_id = '1748b7070a81464c9759c46ad10d3734'\n\n  # get broadcast details\n  broadcast = opentok.get_broadcast(broadcast_id)\n\n  print broadcast.json()\n\n  # print result\n  # {\n  #   \"createdAt\": 1437676551000,\n  #   \"id\": \"1748b707-0a81-464c-9759-c46ad10d3734\",\n  #   \"projectId\": 100,\n  #   \"resolution\": \"640x480\",\n  #   \"sessionId\": \"2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4\",\n  #   \"status\": \"started\",\n  #   \"updatedAt\": 1437676551000,\n  #   \"broadcastUrls\": {\n  #       \"hls\": \"http://server/fakepath/playlist.m3u8\",\n  #       \"rtmp\": {\n  #           \"bar\": {\n  #               \"serverUrl\": \"rtmp://mybarserver/mybarapp\",\n  #               \"status\": \"live\",\n  #               \"streamName\": \"mybarstream\"\n  #           },\n  #           \"foo\": {\n  #               \"serverUrl\": \"rtmp://myfooserver/myfooapp\",\n  #               \"status\": \"live\",\n  #               \"streamName\": \"myfoostream\"\n  #           }\n  #       }\n  #   }\n  # }\n\nYou can dynamically change the layout type of a live streaming broadcast.\n\n.. code:: python\n\n  # Valid values to 'layout_type' are: 'custom', 'horizontalPresentation',\n  # 'pip' and 'verticalPresentation' \n  opentok.set_broadcast_layout('BROADCASTID', 'horizontalPresentation')\n\n  # if you specify a 'custom' layout type, set the stylesheet parameter:\n  opentok.set_broadcast_layout(\n      'BROADCASTID',\n      'custom',\n      'stream.instructor {position: absolute; width: 100%;  height:50%;}'\n  )\n\nYou can add streams to a broadcast using the ``opentok.add_broadcast_stream()`` method:\n\n.. code:: python\n\n  opentok.add_broadcast_stream(broadcast_id, stream_id)\n\nConversely, streams can be removed from a broadcast with the ``opentok.remove_broadcast_stream()`` method.\n\n.. code:: python\n\n  opentok.remove_broadcast_stream(broadcast_id, stream_id)\n\nFor more information about OpenTok live streaming broadcasts, see the\n`Broadcast developer guide \u003chttps://tokbox.com/developer/guides/broadcast/\u003e`_.\n\n\nConnecting audio to a WebSocket\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou can send audio to a WebSocket with the ``opentok.connect_audio_to_websocket`` method.\nFor more information, see the\n`Audio Connector developer guide \u003chttps://tokbox.com/developer/guides/audio-connector/\u003e`_.\n\n.. code:: python\n\n  websocket_options = {\"uri\": \"wss://service.com/ws-endpoint\"}\n  websocket_audio_connection = opentok.connect_audio_to_websocket(session_id, opentok_token, websocket_options)\n\nAdditionally, you can list only the specific streams you want to send to the WebSocket, and/or the additional headers that are sent, \nby adding these fields to the ``websocket_options`` object.\n\n.. code:: python\n\n  websocket_options = {\n    \"uri\": \"wss://service.com/ws-endpoint\",\n    \"streams\": [\n      \"streamId-1\",\n      \"streamId-2\"\n    ],\n    \"headers\": {\n      \"headerKey\": \"headerValue\"\n    }\n  }\n\n\nUsing the Live Captions API\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou can enable live captioning for an OpenTok session with the ``opentok.start_captions`` method.\nFor more information, see the\n`Live Captions API developer guide \u003chttps://tokbox.com/developer/guides/live-captions/\u003e`.\n\n.. code:: python\n\n  captions = opentok.start_captions(session_id, opentok_token)\n\nYou can also specify optional parameters, as shown below.\n\n.. code:: python\n\n  captions = opentok.start_captions(\n    session_id,\n    opentok_token,\n    language_code='en-GB',\n    max_duration=10000,\n    partial_captions=False,\n    status_callback_url='https://example.com',\n  )\n\nYou can stop an ongoing live captioning session by calling the ``opentok.stop_captions`` method.\n\n.. code:: python\n\n  opentok.stop_captions(captions_id)\n\nConfiguring Timeout\n-------------------\nTimeout is passed in the Client constructor:\n\n``self.timeout = timeout``\n\nIn order to configure timeout, first create an instance:\n\n``opentok = Client(...., timeout=value)``\n\nAnd then proceed to change the value with\n\n``opentok.timeout = value``\n\nMuting streams\n--------------\n\nYou can mute all streams in a session using the ``opentok.mute_all()`` method:\n\n.. code:: python\n\n  opentok.mute_all(session_id)\n\n  # You can also specify streams to exclude (e.g. main presenter)\n  excluded_stream_ids = ['1234', '5678']\n  opentok.mute_all(session_id, excluded_stream_ids)\n\nIn addition to existing streams, any streams that are published after the call to\nthis method are published with audio muted. You can remove the mute state of a session\nby calling the ``opentok.disableForceMute()`` method:\n\n.. code:: python\n\n  opentok.disable_force_mute(session_id)\n\nAfter calling the ``opentok.disableForceMute()`` method, new streams that are published\nto the session will not be muted.\n\nYou can mute a single stream using the ``opentok.mute_stream()`` method:\n\n.. code:: python\n\n  opentok.mute_stream(session_id, stream_id)\n\nDTMF\n------\n\nYou can send dual-tone multi-frequency (DTMF) digits to SIP endpoints. You can play DTMF tones\nto all clients connected to session or to a specific connection:\n\n.. code:: python\n  \n  digits = '12345'\n  opentok.play_dtmf(session_id, digits)\n\n  # To a specific connection\n  opentok.play_dtmf(session_id, connection_id, digits)\n\nAppending to the User Agent\n---------------------------\n\nYou can append a string to the user agent that is sent with requests:\n\n.. code:: python\n\n  opentok.append_to_user_agent('my-appended-string')\n\nSamples\n-------\n\nThere are two sample applications included in this repository. To get going as fast as possible, clone the whole\nrepository and follow the Walkthroughs:\n\n- `HelloWorld \u003csample/HelloWorld/README.md\u003e`_\n- `Archiving \u003csample/Archiving/README.md\u003e`_\n\nDocumentation\n-------------\n\nReference documentation is available at https://tokbox.com/developer/sdks/python/reference/.\n\nRequirements\n------------\n\nYou need an OpenTok API key and API secret, which you can obtain at https://dashboard.tokbox.com/\n\nThe OpenTok Python SDK requires Python 3.5 or higher\n\nRelease Notes\n-------------\n\nSee the `Releases \u003chttps://github.com/opentok/Opentok-Python-SDK/releases\u003e`_ page for details about\neach release.\n\nImportant changes since v2.2\n----------------------------\n\n**Changes in v2.2.1:**\n\nThe default setting for the create_session() method is to create a session with the media mode set\nto relayed. In previous versions of the SDK, the default setting was to use the OpenTok Media Router\n(media mode set to routed). In a relayed session, clients will attempt to send streams directly\nbetween each other (peer-to-peer); if clients cannot connect due to firewall restrictions, the\nsession uses the OpenTok TURN server to relay audio-video streams.\n\n**Changes in v2.2.0:**\n\nThis version of the SDK includes support for working with OpenTok archives.\n\nThe Client.create_session() method now includes a media_mode parameter, instead of a p2p parameter.\n\n**Changes in v3.X.X:**\n\nThis version of the SDK includes significant improvements such as top level entity naming, where the Opentok class is now `Client`.  We also implemented a standardised logging module, improved naming conventions and JWT generation to make developer experience more rewarding.\n\nFor details, see the reference documentation at\nhttps://tokbox.com/developer/sdks/python/reference/.\n\nDevelopment and Contributing\n----------------------------\n\nInterested in contributing? We :heart: pull requests! See the `Development \u003cDEVELOPING.md\u003e`_ and\n`Contribution \u003cCONTRIBUTING.md\u003e`_ guidelines.\n\nGetting Help\n------------\n\nWe love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either:\n\n* Open an issue on this repository\n* See https://support.tokbox.com/ for support options\n* Tweet at us! We're `@VonageDev on Twitter \u003chttps://twitter.com/VonageDev\u003e`_\n* Or `join the Vonage Developer Community Slack \u003chttps://developer.nexmo.com/community/slack\u003e`_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentok%2Fopentok-python-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopentok%2Fopentok-python-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentok%2Fopentok-python-sdk/lists"}