|
| 1 | +from contextlib import asynccontextmanager |
| 2 | + |
1 | 3 | from starlette.applications import Starlette |
2 | 4 | from starlette.middleware import Middleware |
3 | 5 | from starlette.middleware.cors import CORSMiddleware |
|
9 | 11 | from .config import COMPOSITION_URL, FISHJAM_ID, FISHJAM_TOKEN |
10 | 12 | from .fishjam_service import FishjamService |
11 | 13 |
|
12 | | -fishjam = FishjamService(FISHJAM_ID, FISHJAM_TOKEN) |
13 | | -composition = CompositionService(FISHJAM_TOKEN, COMPOSITION_URL) |
14 | | - |
15 | | - |
16 | | -def start_composing() -> None: |
17 | | - composition.register_assets() |
18 | | - composition.play_movie() |
19 | | - composition.camera() |
20 | | - composition.stream_to( |
21 | | - fishjam.livestream_whip_url(), fishjam.create_streamer_token() |
22 | | - ) |
23 | 14 |
|
| 15 | +def clean_up(*services) -> None: |
| 16 | + for service in services: |
| 17 | + if service is None: |
| 18 | + continue |
24 | 19 |
|
25 | | -def cleanup() -> None: |
26 | | - for service in (composition, fishjam): |
27 | 20 | try: |
28 | 21 | service.cleanup() |
29 | 22 | except Exception as error: |
30 | 23 | print(f"cleanup failed: {error}") |
31 | 24 |
|
32 | 25 |
|
33 | | -async def streamer(_request: Request) -> Response: |
34 | | - camera = composition.camera() |
| 26 | +@asynccontextmanager |
| 27 | +async def lifespan(app: Starlette): |
| 28 | + fishjam = composition = None |
| 29 | + |
| 30 | + try: |
| 31 | + fishjam = FishjamService(FISHJAM_ID, FISHJAM_TOKEN) |
| 32 | + composition = CompositionService(FISHJAM_TOKEN, COMPOSITION_URL) |
| 33 | + composition.register_assets() |
| 34 | + composition.play_movie() |
| 35 | + composition.camera() |
| 36 | + composition.stream_to( |
| 37 | + fishjam.livestream_whip_url(), fishjam.create_streamer_token() |
| 38 | + ) |
| 39 | + except Exception: |
| 40 | + clean_up(composition, fishjam) |
| 41 | + raise |
| 42 | + |
| 43 | + app.state.fishjam = fishjam |
| 44 | + app.state.composition = composition |
| 45 | + |
| 46 | + try: |
| 47 | + yield |
| 48 | + finally: |
| 49 | + clean_up(composition, fishjam) |
| 50 | + print("deleted the composition and the livestream room") |
| 51 | + |
| 52 | + |
| 53 | +async def streamer(request: Request) -> Response: |
| 54 | + camera = request.app.state.composition.camera() |
35 | 55 |
|
36 | 56 | return JSONResponse({"url": camera.url, "token": camera.bearer_token}) |
37 | 57 |
|
38 | 58 |
|
39 | | -async def viewer(_request: Request) -> Response: |
| 59 | +async def viewer(request: Request) -> Response: |
| 60 | + fishjam = request.app.state.fishjam |
| 61 | + |
40 | 62 | return JSONResponse({ |
41 | 63 | "url": fishjam.livestream_whep_url(), |
42 | 64 | "token": fishjam.create_viewer_token(), |
43 | 65 | }) |
44 | 66 |
|
45 | 67 |
|
46 | 68 | app = Starlette( |
| 69 | + lifespan=lifespan, |
47 | 70 | routes=[ |
48 | 71 | Route("/streamer", streamer, methods=["GET"]), |
49 | 72 | Route("/viewer", viewer, methods=["GET"]), |
|
0 commit comments