Skip to content

Embeddable widget design doc

Michael Toomim edited this page Jun 19, 2017 · 18 revisions

This document lays out a proposal for a statebus-y audio/video sharing API.

Proposed API (Requirements)

# Publish audio/video to space "foo" under id "unique_id"
sb['tawk/foo/unique_id'] =
  video: true
  audio: true

# Display all published streams in space foo
for connid in sb['tawk/foo/connections']:
  conn = sb['tawk/foo/connections/' + connid]
  VIDEO
    srcObject: conn.srcObject
  if conn.audio # not muted
    VOLUME_BAR
      width: '10px'
      height: conn.volume

Publishing a stream: sb['tawk//connections/'] = {video, audio}

Saving this state establishes "presence" in a space, with support for publishing audio and video streams. Note that it is different than the high-level TAWK_UI widget, which will include most of the functionality in https://tawk.space (groups, mute button, scratch space, etc). This is the underlying state API intended for folks who want to make their own UI around audio/video chat. Here is a description of its parameters:

space (string, required)

Specifies a video chat room where all participants can access each others' ids and streams. Spaces are not discoverable -- there is no way to list all available spaces. This means creating a random space is equivalent to a private chat. Applications are recommended to prefix their spaces with an application name to prevent collisions with https://tawk.space (e.g. "considerit-foo" does not conflict with "https://tawk.space/foo"). This space corresponds to the path on https://tawk.space/.

id (string, optional, default=random string)

Any string that is unique for the given space. This id is used to identify a "presence" in the space, which includes properties such as the audio/video stream and volume. This parameter is exposed so that applications know which id corresponds to their client.

Value: {audio = false, video = false}

Whether to publish audio and/or video to space. Notes:

  • Specifying neither is fine (this is the default).
  • We will only request camera/mic permissions as needed. Audio-only chat will not turn the camera light on.
  • These can be changed at any time to publish/unpublish a particular stream.
  • In the future this will be expanded to support screen sharing

Exported state (sb['tawk/<space>/**'])

This exported state is entirely independent of the TAWK widget -- you don't need to use the TAWK widget . While the TAWK widget is used to publish streams, this API is used to subscribe to streams. Here is an overview of the API:

sb['tawk/<space>/connections']

An array of publisher ids in no particular order. This is the id from the TAWK widget.

sb['tawk/<space>/connections/<connid>']

An object with properties of the media streams:

{
  // Whether publisher is publishing audio
  audio: true/false,
  // Whether publisher is publishing video
  video: true/false,
  // MediaStream object useful for audio/video tags
  srcObject: MediaStream,
  // Audio volume as measured on the receiver side
  volume: float,
}

Note that media streams are only downloaded when its state is fetched, and are unsubscribed when its state is forgotten.

Detailed Design

TODO after getting signoff on API.

Draft v2 (mike's)

I removed each user's ID, because it seemed unnecessary.

I designed two types of state:

  • Streams of audio and video: tawk/stream/<random_id>
  • Spaces of streams: tawk/space/<space_name>

Streams

# Access your stream with your info at /my_stream
sb['tawk/my_stream']
=> { 
   key: 'tawk/stream/a72jsafj',
   video_url: '...',
   user: 'karthik',
   publishing_audio: true,
   publishing_video: true,
   volume: .24,
   space: {_key: 'tawk/space/floofy'}
}

# You can mute video or audio on your stream
state['tawk/my_stream'].publishing_audio = true
state['tawk/my_stream'].publishing_video = false

# You can publish your stream at any set of spaces you want
state['tawk/my_stream'].space = state['tawk/space/floofy']   # These commands are equivalent

Spaces

# Space state looks like:
{
   key: 'tawk/space/<space>',
   streams: [
      {
         key: 'tawk/stream/a72jsafj',       # We might not need a separate key per stream yet
         video_url: '...',                  # This goes into VIDEO srcObject
         publishing_audio: false,
         publishing_video: false,
         volume: .25,
         user: 'karthik',                   # Alternatively, this could point to a user object
         space: {_key: 'tawk/space/<space>'}
      }
      ...
   ]
}

# Rendering HTML for a space
for stream in sb['tawk/space/<space>'].streams
  VIDEO
    srcObject: stream.video_url
  if stream.publishing_audio
    VOLUME_BAR
      width: '10px'
      height: stream.volume

The space tawk/space/<space_name> will be visible at https://tawk.space/<space_name>. There is no way to list all spaces; which means you can choose a random string to create a private chat.

Note that media streams are only downloaded when its state is fetched, and are unsubscribed when its state is forgotten.