Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions livekit-api/livekit/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,6 @@
"AccessToken",
"TokenVerifier",
"WebhookReceiver",
"TwirpError",
"TwirpErrorCode",
]
3 changes: 1 addition & 2 deletions livekit-api/livekit/api/_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

from typing import Dict
import aiohttp
from abc import ABC
from .twirp_client import TwirpClient
Expand All @@ -17,7 +16,7 @@ def __init__(self, session: aiohttp.ClientSession, host: str, api_key: str, api_

def _auth_header(
self, grants: VideoGrants | None, sip: SIPGrants | None = None
) -> Dict[str, str]:
) -> dict[str, str]:
tok = AccessToken(self.api_key, self.api_secret)
if grants:
tok.with_grants(grants)
Expand Down
16 changes: 16 additions & 0 deletions livekit-api/livekit/api/egress_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def __init__(self, session: aiohttp.ClientSession, url: str, api_key: str, api_s
super().__init__(session, url, api_key, api_secret)

async def start_room_composite_egress(self, start: RoomCompositeEgressRequest) -> EgressInfo:
"""Starts a composite recording of a room."""
return await self._client.request(
SVC,
"StartRoomCompositeEgress",
Expand All @@ -46,6 +47,7 @@ async def start_room_composite_egress(self, start: RoomCompositeEgressRequest) -
)

async def start_web_egress(self, start: WebEgressRequest) -> EgressInfo:
"""Starts a recording of a web page."""
return await self._client.request(
SVC,
"StartWebEgress",
Expand All @@ -55,6 +57,7 @@ async def start_web_egress(self, start: WebEgressRequest) -> EgressInfo:
)

async def start_participant_egress(self, start: ParticipantEgressRequest) -> EgressInfo:
"""Starts a recording of a participant."""
return await self._client.request(
SVC,
"StartParticipantEgress",
Expand All @@ -64,6 +67,7 @@ async def start_participant_egress(self, start: ParticipantEgressRequest) -> Egr
)

async def start_track_composite_egress(self, start: TrackCompositeEgressRequest) -> EgressInfo:
"""Starts a composite recording with audio and video tracks."""
return await self._client.request(
SVC,
"StartTrackCompositeEgress",
Expand All @@ -73,6 +77,7 @@ async def start_track_composite_egress(self, start: TrackCompositeEgressRequest)
)

async def start_track_egress(self, start: TrackEgressRequest) -> EgressInfo:
"""Starts a recording of a single track."""
return await self._client.request(
SVC,
"StartTrackEgress",
Expand All @@ -82,6 +87,7 @@ async def start_track_egress(self, start: TrackEgressRequest) -> EgressInfo:
)

async def update_layout(self, update: UpdateLayoutRequest) -> EgressInfo:
"""Updates the layout of a composite recording."""
return await self._client.request(
SVC,
"UpdateLayout",
Expand All @@ -91,6 +97,7 @@ async def update_layout(self, update: UpdateLayoutRequest) -> EgressInfo:
)

async def update_stream(self, update: UpdateStreamRequest) -> EgressInfo:
"""Updates the stream of a RoomComposite, Web, or Participant recording."""
return await self._client.request(
SVC,
"UpdateStream",
Expand All @@ -100,6 +107,14 @@ async def update_stream(self, update: UpdateStreamRequest) -> EgressInfo:
)

async def list_egress(self, list: ListEgressRequest) -> ListEgressResponse:
"""Lists all active egress and recently completed recordings.

Args:
list (ListEgressRequest): arg contains optional filters:
- room_name: str - List all egresses for a specific room
- egress_id: str - Only list egress with matching ID
- active: bool - Only list active egresses
"""
return await self._client.request(
SVC,
"ListEgress",
Expand All @@ -109,6 +124,7 @@ async def list_egress(self, list: ListEgressRequest) -> ListEgressResponse:
)

async def stop_egress(self, stop: StopEgressRequest) -> EgressInfo:
"""Stops an active egress recording."""
return await self._client.request(
SVC,
"StopEgress",
Expand Down
12 changes: 7 additions & 5 deletions livekit-api/livekit/api/livekit_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ def __init__(
if not api_key or not api_secret:
raise ValueError("api_key and api_secret must be set")

if not timeout:
timeout = aiohttp.ClientTimeout(total=60)

self._custom_session = True if session is None else False
self._session = session or aiohttp.ClientSession(timeout=timeout)
self._custom_session = True
self._session = session
if not self._session:
self._custom_session = False
if not timeout:
timeout = aiohttp.ClientTimeout(total=60)
self._session = aiohttp.ClientSession(timeout=timeout)

self._room = RoomService(self._session, url, api_key, api_secret)
self._ingress = IngressService(self._session, url, api_key, api_secret)
Expand Down
22 changes: 22 additions & 0 deletions livekit-api/livekit/api/room_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
UpdateRoomMetadataRequest,
RemoveParticipantResponse,
UpdateSubscriptionsResponse,
ForwardParticipantRequest,
ForwardParticipantResponse,
)
from livekit.protocol.models import Room, ParticipantInfo
from ._service import Service
Expand Down Expand Up @@ -197,6 +199,26 @@ async def remove_participant(
RemoveParticipantResponse,
)

async def forward_participant(self, forward: ForwardParticipantRequest) -> None:
"""Forwards a participant and their published tracks from one room to another.

This feature is only available for LiveKit Cloud/Private Cloud.

Args:
forward (ForwardParticipantRequest): arg containing:
- room: str - Room name
- identity: str - identity of Participant to forward
- destination_room: str - Destination room name
"""
# currently nothing is returned
await self._client.request(
SVC,
"ForwardParticipant",
forward,
self._auth_header(VideoGrants(room_admin=True, room=forward.room)),
ForwardParticipantResponse,
)

async def mute_published_track(
self,
update: MuteRoomTrackRequest,
Expand Down
Loading
Loading