Skip to content

Commit 907be69

Browse files
feat: initial monorepo & server sdk (#61)
Co-authored-by: David Zhao <[email protected]>
1 parent 15934c5 commit 907be69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+4510
-162
lines changed

.gitattributes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
**/*.dll filter=lfs diff=lfs merge=lfs -text
22
**/*.so filter=lfs diff=lfs merge=lfs -text
3-
**/*.dylib filter=lfs diff=lfs merge=lfs -text
3+
**/*.dylib filter=lfs diff=lfs merge=lfs -text
4+
livekit-api/livekit/api/_proto/** linguist-generated=true
5+
livekit-rtc/livekit/rtc/_proto/** linguist-generated=true

.github/workflows/build-api.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Build API
2+
3+
on:
4+
push:
5+
paths:
6+
- livekit-api/**
7+
pull_request:
8+
paths:
9+
- livekit-api/**
10+
workflow_dispatch:
11+
12+
env:
13+
PACKAGE_DIR: ./livekit-api
14+
15+
jobs:
16+
build_wheels:
17+
name: Build API wheel/sdist
18+
runs-on: ubuntu-latest
19+
defaults:
20+
run:
21+
working-directory: ${{ env.PACKAGE_DIR }}
22+
steps:
23+
- uses: actions/checkout@v3
24+
with:
25+
submodules: true
26+
27+
- uses: actions/setup-python@v4
28+
29+
- name: Build wheel
30+
run: |
31+
pip3 install build wheel
32+
python3 -m build --wheel
33+
env:
34+
CIBW_ARCHS: ${{ matrix.archs }}
35+
CIBW_SKIP: "*-musllinux_*"
36+
37+
- name: Build SDist
38+
run: pipx run build --sdist
39+
40+
- uses: actions/upload-artifact@v3
41+
with:
42+
name: api-release
43+
path: |
44+
livekit-api/dist/*.whl
45+
livekit-api/dist/*.tar.gz
46+
47+
publish:
48+
name: Publish API release
49+
needs: build_wheels
50+
runs-on: ubuntu-latest
51+
permissions:
52+
id-token: write
53+
if: startsWith(github.ref, 'refs/tags/api-v')
54+
steps:
55+
- uses: actions/download-artifact@v3
56+
with:
57+
name: api-release
58+
path: dist
59+
60+
- uses: pypa/gh-action-pypi-publish@release/v1
61+
with:
62+
user: __token__
63+

.github/workflows/build-wheels.yml renamed to .github/workflows/build-rtc.yml

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
name: Build
1+
name: Build RTC
22

33
on:
44
push:
5-
branches: ["main"]
6-
tags: ["v*"]
5+
paths:
6+
- livekit-rtc/**
77
pull_request:
8+
paths:
9+
- livekit-rtc/**
810
workflow_dispatch:
911

12+
env:
13+
PACKAGE_DIR: ./livekit-rtc
14+
1015
jobs:
1116
build_wheels:
12-
name: Build wheels (${{ matrix.archs }})
17+
name: Build RTC wheels (${{ matrix.archs }})
1318
runs-on: ${{ matrix.os }}
1419
strategy:
1520
fail-fast: false
@@ -24,7 +29,9 @@ jobs:
2429
archs: AMD64 # ignore windows arm64 for now
2530
- os: macos-latest
2631
archs: x86_64 arm64
27-
32+
defaults:
33+
run:
34+
working-directory: ${{ env.PACKAGE_DIR }}
2835
steps:
2936
- uses: actions/checkout@v3
3037
with:
@@ -39,16 +46,18 @@ jobs:
3946
run: python3 -m cibuildwheel --output-dir dist
4047
env:
4148
CIBW_ARCHS: ${{ matrix.archs }}
42-
CIBW_SKIP: "*-musllinux_*"
4349

4450
- uses: actions/upload-artifact@v3
4551
with:
46-
name: release
47-
path: dist/*.whl
52+
name: rtc-release
53+
path: livekit-rtc/dist/*.whl
4854

4955
make_sdist:
50-
name: Make SDist
56+
name: Make RTC sdist
5157
runs-on: ubuntu-latest
58+
defaults:
59+
run:
60+
working-directory: ${{ env.PACKAGE_DIR }}
5261
steps:
5362
- uses: actions/checkout@v3
5463
with:
@@ -59,21 +68,20 @@ jobs:
5968

6069
- uses: actions/upload-artifact@v3
6170
with:
62-
name: release
63-
path: dist/*.tar.gz
71+
name: rtc-release
72+
path: livekit-rtc/dist/*.tar.gz
6473

6574
publish:
66-
name: Publish
75+
name: Publish RTC release
6776
needs: [build_wheels, make_sdist]
6877
runs-on: ubuntu-latest
6978
permissions:
7079
id-token: write
71-
# only execute on tag push v1 or workflow_dispatch
72-
if: (github.event_name == 'push' && github.ref_type == 'tag') || github.event_name == 'workflow_dispatch'
80+
if: startsWith(github.ref, 'refs/tags/rtc-v')
7381
steps:
7482
- uses: actions/download-artifact@v3
7583
with:
76-
name: release
84+
name: rtc-release
7785
path: dist
7886

7987
- uses: pypa/gh-action-pypi-publish@release/v1

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "client-sdk-rust"]
2-
path = rust-sdks
2+
path = livekit-rtc/rust-sdks
33
url = https://github.com/livekit/rust-sdks
4+
[submodule "livekit-api/protocol"]
5+
path = livekit-api/protocol
6+
url = https://github.com/livekit/protocol

examples/basic_room.py

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,98 +3,98 @@
33
from signal import SIGINT, SIGTERM
44
from typing import Union
55

6-
import livekit
6+
from livekit import rtc
77

88
URL = 'ws://localhost:7880'
99
TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE5MDY2MTMyODgsImlzcyI6IkFQSVRzRWZpZFpqclFvWSIsIm5hbWUiOiJuYXRpdmUiLCJuYmYiOjE2NzI2MTMyODgsInN1YiI6Im5hdGl2ZSIsInZpZGVvIjp7InJvb20iOiJ0ZXN0Iiwicm9vbUFkbWluIjp0cnVlLCJyb29tQ3JlYXRlIjp0cnVlLCJyb29tSm9pbiI6dHJ1ZSwicm9vbUxpc3QiOnRydWV9fQ.uSNIangMRu8jZD5mnRYoCHjcsQWCrJXgHCs0aNIgBFY' # noqa
1010

1111

12-
async def main(room: livekit.Room) -> None:
12+
async def main(room: rtc.Room) -> None:
1313

1414
@room.listens_to("participant_connected")
15-
def on_participant_connected(participant: livekit.RemoteParticipant) -> None:
15+
def on_participant_connected(participant: rtc.RemoteParticipant) -> None:
1616
logging.info(
1717
"participant connected: %s %s", participant.sid, participant.identity)
1818

1919
@room.listens_to("participant_disconnected")
20-
def on_participant_disconnected(participant: livekit.RemoteParticipant):
20+
def on_participant_disconnected(participant: rtc.RemoteParticipant):
2121
logging.info("participant disconnected: %s %s",
2222
participant.sid, participant.identity)
2323

2424
@room.listens_to("local_track_published")
25-
def on_local_track_published(publication: livekit.LocalTrackPublication,
26-
track: Union[livekit.LocalAudioTrack,
27-
livekit.LocalVideoTrack]):
25+
def on_local_track_published(publication: rtc.LocalTrackPublication,
26+
track: Union[rtc.LocalAudioTrack,
27+
rtc.LocalVideoTrack]):
2828
logging.info("local track published: %s", publication.sid)
2929

3030
@room.listens_to("active_speakers_changed")
31-
def on_active_speakers_changed(speakers: list[livekit.Participant]):
31+
def on_active_speakers_changed(speakers: list[rtc.Participant]):
3232
logging.info("active speakers changed: %s", speakers)
3333

3434
@room.listens_to("local_track_unpublished")
35-
def on_local_track_unpublished(publication: livekit.LocalTrackPublication):
35+
def on_local_track_unpublished(publication: rtc.LocalTrackPublication):
3636
logging.info("local track unpublished: %s", publication.sid)
3737

3838
@room.listens_to("track_published")
39-
def on_track_published(publication: livekit.RemoteTrackPublication,
40-
participant: livekit.RemoteParticipant):
39+
def on_track_published(publication: rtc.RemoteTrackPublication,
40+
participant: rtc.RemoteParticipant):
4141
logging.info("track published: %s from participant %s (%s)",
4242
publication.sid, participant.sid, participant.identity)
4343

4444
@room.listens_to("track_unpublished")
45-
def on_track_unpublished(publication: livekit.RemoteTrackPublication,
46-
participant: livekit.RemoteParticipant):
45+
def on_track_unpublished(publication: rtc.RemoteTrackPublication,
46+
participant: rtc.RemoteParticipant):
4747
logging.info("track unpublished: %s", publication.sid)
4848

4949
@room.listens_to("track_subscribed")
50-
def on_track_subscribed(track: livekit.Track,
51-
publication: livekit.RemoteTrackPublication,
52-
participant: livekit.RemoteParticipant):
50+
def on_track_subscribed(track: rtc.Track,
51+
publication: rtc.RemoteTrackPublication,
52+
participant: rtc.RemoteParticipant):
5353
logging.info("track subscribed: %s", publication.sid)
54-
if track.kind == livekit.TrackKind.KIND_VIDEO:
55-
_video_stream = livekit.VideoStream(track)
54+
if track.kind == rtc.TrackKind.KIND_VIDEO:
55+
_video_stream = rtc.VideoStream(track)
5656
# video_stream is an async iterator that yields VideoFrame
57-
elif track.kind == livekit.TrackKind.KIND_AUDIO:
57+
elif track.kind == rtc.TrackKind.KIND_AUDIO:
5858
print("Subscribed to an Audio Track")
59-
_audio_stream = livekit.AudioStream(track)
59+
_audio_stream = rtc.AudioStream(track)
6060
# audio_stream is an async iterator that yields AudioFrame
6161

6262
@room.listens_to("track_unsubscribed")
63-
def on_track_unsubscribed(track: livekit.Track,
64-
publication: livekit.RemoteTrackPublication,
65-
participant: livekit.RemoteParticipant):
63+
def on_track_unsubscribed(track: rtc.Track,
64+
publication: rtc.RemoteTrackPublication,
65+
participant: rtc.RemoteParticipant):
6666
logging.info("track unsubscribed: %s", publication.sid)
6767

6868
@room.listens_to("track_muted")
69-
def on_track_muted(publication: livekit.RemoteTrackPublication,
70-
participant: livekit.RemoteParticipant):
69+
def on_track_muted(publication: rtc.RemoteTrackPublication,
70+
participant: rtc.RemoteParticipant):
7171
logging.info("track muted: %s", publication.sid)
7272

7373
@room.listens_to("track_unmuted")
74-
def on_track_unmuted(publication: livekit.RemoteTrackPublication,
75-
participant: livekit.RemoteParticipant):
74+
def on_track_unmuted(publication: rtc.RemoteTrackPublication,
75+
participant: rtc.RemoteParticipant):
7676
logging.info("track unmuted: %s", publication.sid)
7777

7878
@room.listens_to("data_received")
7979
def on_data_received(data: bytes,
80-
kind: livekit.DataPacketKind,
81-
participant: livekit.Participant):
80+
kind: rtc.DataPacketKind,
81+
participant: rtc.Participant):
8282
logging.info("received data from %s: %s", participant.identity, data)
8383

8484
@room.listens_to("connection_quality_changed")
85-
def on_connection_quality_changed(participant: livekit.Participant,
86-
quality: livekit.ConnectionQuality):
85+
def on_connection_quality_changed(participant: rtc.Participant,
86+
quality: rtc.ConnectionQuality):
8787
logging.info("connection quality changed for %s", participant.identity)
8888

8989
@room.listens_to("track_subscription_failed")
90-
def on_track_subscription_failed(participant: livekit.RemoteParticipant,
90+
def on_track_subscription_failed(participant: rtc.RemoteParticipant,
9191
track_sid: str,
9292
error: str):
9393
logging.info("track subscription failed: %s %s",
9494
participant.identity, error)
9595

9696
@room.listens_to("connection_state_changed")
97-
def on_connection_state_changed(state: livekit.ConnectionState):
97+
def on_connection_state_changed(state: rtc.ConnectionState):
9898
logging.info("connection state changed: %s", state)
9999

100100
@room.listens_to("connected")
@@ -127,7 +127,7 @@ def on_reconnected() -> None:
127127
logging.StreamHandler()])
128128

129129
loop = asyncio.get_event_loop()
130-
room = livekit.Room(loop=loop)
130+
room = rtc.Room(loop=loop)
131131

132132
async def cleanup():
133133
await room.disconnect()

examples/e2ee.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,24 @@
33
from signal import SIGINT, SIGTERM
44

55
import numpy as np
6-
7-
import livekit
6+
from livekit import rtc
87

98
URL = 'ws://localhost:7880'
109
TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE5MDY2MTMyODgsImlzcyI6IkFQSVRzRWZpZFpqclFvWSIsIm5hbWUiOiJuYXRpdmUiLCJuYmYiOjE2NzI2MTMyODgsInN1YiI6Im5hdGl2ZSIsInZpZGVvIjp7InJvb20iOiJ0ZXN0Iiwicm9vbUFkbWluIjp0cnVlLCJyb29tQ3JlYXRlIjp0cnVlLCJyb29tSm9pbiI6dHJ1ZSwicm9vbUxpc3QiOnRydWV9fQ.uSNIangMRu8jZD5mnRYoCHjcsQWCrJXgHCs0aNIgBFY' # noqa
1110

1211
# ("livekitrocks") this is our shared key, it must match the one used by your clients
13-
SHARED_KEY = b"livekitrocks"
12+
SHARED_KEY = b"liveitrocks"
1413

1514

16-
async def draw_cube(source: livekit.VideoSource):
15+
async def draw_cube(source: rtc.VideoSource):
1716
W, H, MID_W, MID_H = 1280, 720, 640, 360
1817
cube_size = 60
1918
vertices = (np.array([[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
2019
[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]) * cube_size)
2120
edges = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6],
2221
[6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]]
2322

24-
frame = livekit.ArgbFrame(livekit.VideoFormatType.FORMAT_ARGB, W, H)
23+
frame = rtc.ArgbFrame(livekit.VideoFormatType.FORMAT_ARGB, W, H)
2524
arr = np.ctypeslib.as_array(frame.data)
2625
angle = 0
2726

@@ -48,41 +47,41 @@ async def draw_cube(source: livekit.VideoSource):
4847
idx = (y + dy) * W * 4 + (x + dx) * 4
4948
arr[idx:idx+4] = [255, 255, 255, 255]
5049

51-
f = livekit.VideoFrame(
52-
0, livekit.VideoRotation.VIDEO_ROTATION_0, frame.to_i420())
50+
f = rtc.VideoFrame(
51+
0, rtc.VideoRotation.VIDEO_ROTATION_0, frame.to_i420())
5352
source.capture_frame(f)
5453
angle += 0.02
5554

5655
code_duration = asyncio.get_event_loop().time() - start_time
5756
await asyncio.sleep(1 / 30 - code_duration)
5857

5958

60-
async def main(room: livekit.Room):
59+
async def main(room: rtc.Room):
6160
@room.listens_to("e2ee_state_changed")
62-
def on_e2ee_state_changed(participant: livekit.Participant,
63-
state: livekit.EncryptionState) -> None:
61+
def on_e2ee_state_changed(participant: rtc.Participant,
62+
state: rtc.EncryptionState) -> None:
6463
logging.info("e2ee state changed: %s %s", participant.identity, state)
6564

6665
logging.info("connecting to %s", URL)
6766
try:
68-
e2ee_options = livekit.E2EEOptions()
67+
e2ee_options = rtc.E2EEOptions()
6968
e2ee_options.key_provider_options.shared_key = SHARED_KEY
7069

71-
await room.connect(URL, TOKEN, options=livekit.RoomOptions(
70+
await room.connect(URL, TOKEN, options=rtc.RoomOptions(
7271
auto_subscribe=True,
7372
e2ee=e2ee_options
7473
))
7574

7675
logging.info("connected to room %s", room.name)
77-
except livekit.ConnectError as e:
76+
except rtc.ConnectError as e:
7877
logging.error("failed to connect to the room: %s", e)
7978
return False
8079

8180
# publish a track
82-
source = livekit.VideoSource()
83-
track = livekit.LocalVideoTrack.create_video_track("cube", source)
84-
options = livekit.TrackPublishOptions()
85-
options.source = livekit.TrackSource.SOURCE_CAMERA
81+
source = rtc.VideoSource()
82+
track = rtc.LocalVideoTrack.create_video_track("cube", source)
83+
options = rtc.TrackPublishOptions()
84+
options.source = rtc.TrackSource.SOURCE_CAMERA
8685
publication = await room.local_participant.publish_track(track, options)
8786
logging.info("published track %s", publication.sid)
8887

@@ -94,7 +93,7 @@ def on_e2ee_state_changed(participant: livekit.Participant,
9493
logging.StreamHandler()])
9594

9695
loop = asyncio.get_event_loop()
97-
room = livekit.Room(loop=loop)
96+
room = rtc.Room(loop=loop)
9897

9998
async def cleanup():
10099
await room.disconnect()

0 commit comments

Comments
 (0)