create endpoint to start a recording
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import uuid
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Q
|
||||
from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404
|
||||
@@ -213,6 +214,34 @@ class RoomViewSet(
|
||||
|
||||
return drf_response.Response(data)
|
||||
|
||||
@decorators.action(
|
||||
detail=True,
|
||||
methods=["get"],
|
||||
url_name="start_recording",
|
||||
url_path="start-recording",
|
||||
# permission_classes=[permissions.IsAuthenticated],
|
||||
)
|
||||
def start_room_recording(self, request, pk=None):
|
||||
"""Start room recording."""
|
||||
room = self.get_object()
|
||||
if not room.is_administrator(request.user) and not room.is_owner(request.user):
|
||||
raise PermissionDenied(
|
||||
"You must be an admin or owner to start a recording."
|
||||
)
|
||||
|
||||
# TODO - check if no active recording is already present, we limit room recording to one
|
||||
|
||||
try:
|
||||
response = utils.start_egress(room)
|
||||
except (RuntimeError, ValueError) as e:
|
||||
return drf_response.Response({"error": str(e)})
|
||||
|
||||
# TODO - persist response
|
||||
|
||||
return drf_response.Response(
|
||||
{"message": f"Recording started for room {room.slug}", "egress": response}
|
||||
)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
"""Limit listed rooms to the ones related to the authenticated user."""
|
||||
user = self.request.user
|
||||
|
||||
@@ -3,6 +3,7 @@ Utils functions used in the core app
|
||||
"""
|
||||
|
||||
# ruff: noqa:S311
|
||||
# pylint: disable=no-member
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
@@ -12,7 +13,11 @@ from uuid import uuid4
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from livekit.api import AccessToken, VideoGrants
|
||||
import aiohttp
|
||||
from asgiref.sync import async_to_sync
|
||||
from livekit.api import AccessToken, TwirpError, VideoGrants
|
||||
from livekit.api.egress_service import EgressService
|
||||
from livekit.protocol import egress as proto_egress
|
||||
|
||||
|
||||
def generate_color(identity: str) -> str:
|
||||
@@ -81,3 +86,44 @@ def generate_token(room: str, user, username: Optional[str] = None) -> str:
|
||||
)
|
||||
|
||||
return token.to_jwt()
|
||||
|
||||
|
||||
@async_to_sync
|
||||
async def start_egress(room):
|
||||
"""Start room recording using LiveKit's Egress service."""
|
||||
|
||||
if not room or not room.id:
|
||||
raise ValueError("Invalid room object")
|
||||
|
||||
# FIXME - Temporary, liveKit removes dashes in room's name
|
||||
room_name = str(room.id).replace("-", "")
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
egress_service = EgressService(
|
||||
session=session, **settings.LIVEKIT_CONFIGURATION
|
||||
)
|
||||
|
||||
# TODO - discuss whether we organize recordings in subfolder
|
||||
response = await egress_service.start_room_composite_egress(
|
||||
start=proto_egress.RoomCompositeEgressRequest(
|
||||
room_name=room_name,
|
||||
file_outputs=[
|
||||
proto_egress.EncodedFileOutput(
|
||||
file_type=proto_egress.EncodedFileType.MP4,
|
||||
filepath="{room_name}{time}.mp4",
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
"egress_id": response.egress_id,
|
||||
"filename": response.file.filename,
|
||||
}
|
||||
|
||||
except TwirpError as e:
|
||||
# TODO - log error
|
||||
raise RuntimeError(
|
||||
"An error occurred while starting the room recording."
|
||||
) from e
|
||||
|
||||
@@ -58,6 +58,7 @@ dependencies = [
|
||||
"whitenoise==6.7.0",
|
||||
"mozilla-django-oidc==4.0.1",
|
||||
"livekit-api==0.7.0",
|
||||
"aiohttp==3.10.10",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
Reference in New Issue
Block a user