create endpoint to start a recording

This commit is contained in:
lebaudantoine
2024-10-28 10:28:01 +01:00
parent f7ed70dc9c
commit c27cb21e18
3 changed files with 77 additions and 1 deletions
+29
View File
@@ -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
+47 -1
View File
@@ -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
+1
View File
@@ -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]