major refactoring + docker progress

This commit is contained in:
Micha Albert 2024-09-09 16:37:02 -04:00
parent ecb8a80f8b
commit e75f8c944a
No known key found for this signature in database
GPG key ID: 33149159A417BBCE
35 changed files with 227 additions and 104 deletions

3
.gitignore vendored
View file

@ -187,4 +187,5 @@ cython_debug/
#.idea/
*.dat
dev.db*
dev.db*
.*env

View file

@ -0,0 +1,11 @@
FROM python:3.12-alpine
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./main.py" ]

View file

@ -0,0 +1,17 @@
import subprocess
import time
import requests
active_stream = requests.get("http://backend:8000/api/v1/active_stream").text
old_active_stream = active_stream
proc = None
while True:
proc = subprocess.Popen([f"ffmpeg -re -i rtmp://mediamtx:1935/{active_stream} -c:a copy rtmp://host.containers.internal:1936/active-input"], shell=True)
time.sleep(3)
active_stream = requests.get("http://backend:8000/api/v1/active_stream").text
if old_active_stream is not active_stream:
proc.terminate()
proc = subprocess.Popen([f"ffmpeg -re -i rtmp://mediamtx:1935/{active_stream} -c:a copy rtmp://host.containers.internal:1936/active-input"], shell=True)
old_active_stream = active_stream

View file

@ -0,0 +1 @@
requests

21
backend/Dockerfile Normal file
View file

@ -0,0 +1,21 @@
FROM python:3.12-slim
EXPOSE 8000
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN apt-get update
RUN apt-get install -y python3-opencv
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py schema.prisma .
COPY migrations .
RUN prisma generate
CMD [ "fastapi", "run", "main.py" ]

View file

@ -83,7 +83,7 @@ async def get_recording_list(stream_key: str) -> List[str]:
recording["start"]
for recording in (
await client.get(
f"http://localhost:9997/v3/recordings/get/{stream_key}"
f"http://{os.environ['MEDIAMTX_IP']}:9997/v3/recordings/get/{stream_key}"
)
).json()["segments"]
]
@ -93,7 +93,7 @@ async def update_active():
global active_stream
global active_streams
async with httpx.AsyncClient() as client:
streams_raw = (await client.get("http://localhost:9997/v3/paths/list")).json()[
streams_raw = (await client.get(f"http://{os.environ['MEDIAMTX_IP']}:9997/v3/paths/list")).json()[
"items"
]
streams = []
@ -124,7 +124,7 @@ async def check_for_new():
global active_stream
global active_streams
async with httpx.AsyncClient() as client:
streams_raw = (await client.get("http://localhost:9997/v3/paths/list")).json()[
streams_raw = (await client.get(f"http://{os.environ['MEDIAMTX_IP']}:9997/v3/paths/list")).json()[
"items"
]
streams_simple = []
@ -161,7 +161,7 @@ async def lifespan(app: FastAPI):
async with httpx.AsyncClient() as client:
for stream in await db.stream.find_many():
await client.post(
"http://127.0.0.1:9997/v3/config/paths/add/" + stream.key,
f"http://{os.environ['MEDIAMTX_IP']}:9997/v3/config/paths/add/" + stream.key,
json={"name": stream.key},
)
yield
@ -494,7 +494,7 @@ async def approve(ack, body):
)
async with httpx.AsyncClient() as client:
await client.post(
"http://127.0.0.1:9997/v3/config/paths/add/" + new_stream.key,
f"http://{os.environ['MEDIAMTX_IP']}:9997/v3/config/paths/add/" + new_stream.key,
json={"name": new_stream.key},
)
await bolt.client.chat_postMessage(

79
backend/requirements.txt Normal file
View file

@ -0,0 +1,79 @@
aiofiles==24.1.0
aiohttp==3.9.5
aiosignal==1.3.1
annotated-types==0.7.0
anyio==4.4.0
APScheduler==3.10.4
attrs==23.2.0
black==24.4.2
build==1.2.1
certifi==2024.7.4
cffi==1.17.0
charset-normalizer==3.3.2
click==8.1.7
cryptography==43.0.0
defusedxml==0.8.0rc2
dnspython==2.6.1
ecdsa==0.19.0
email_validator==2.2.0
fastapi==0.112.0
fastapi-cli==0.0.4
fastapi-oauth2==1.0.0
fastapi-utils==0.7.0
frozenlist==1.4.1
h11==0.14.0
httpcore==1.0.5
httptools==0.6.1
httpx==0.27.0
idna==3.7
Jinja2==3.1.4
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
multidict==6.0.5
mypy==1.11.0
mypy-extensions==1.0.0
nodeenv==1.9.1
numpy==2.1.0
oauthlib==3.2.2
opencv-python==4.10.0.84
packaging==24.1
pathspec==0.12.1
platformdirs==4.2.2
prisma==0.14.0
psutil==5.9.8
pyasn1==0.6.0
pycparser==2.22
pydantic==2.8.2
pydantic_core==2.20.1
Pygments==2.18.0
PyJWT==2.9.0
pyproject_hooks==1.1.0
python-dotenv==1.0.1
python-jose==3.3.0
python-multipart==0.0.9
python3-openid==3.2.0
pytz==2024.1
PyYAML==6.0.1
requests==2.32.3
requests-oauthlib==2.0.0
rich==13.7.1
rsa==4.9
shellingham==1.5.4
six==1.16.0
slack_bolt==1.20.0
slack_sdk==3.31.0
sniffio==1.3.1
social-auth-core==4.5.4
starlette==0.37.2
tomlkit==0.13.0
typer==0.12.3
typing-inspect==0.9.0
typing_extensions==4.12.2
tzlocal==5.2
urllib3==2.2.2
uvicorn==0.30.6
uvloop==0.19.0
watchfiles==0.22.0
websockets==12.0
yarl==1.9.4

View file

@ -5,8 +5,8 @@ generator client {
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
provider = "postgresql"
url = "file:./db/dev.db"
}
model User {

42
docker-compose.yml Normal file
View file

@ -0,0 +1,42 @@
services:
mediamtx:
network_mode: host
build:
context: ./mediamtx
dockerfile: Dockerfile
web-frontend:
build:
context: ./tiling-frontend
dockerfile: Dockerfile
volumes:
- tiling_frontend_build:/usr/src/app/dist
live-stream:
depends_on:
web-frontend:
condition: service_completed_successfully
build:
context: ./live-stream
dockerfile: Dockerfile
volumes:
- tiling_frontend_build:/html
environment:
YT_STREAM_KEY: ${YT_STREAM_KEY}
backend:
env_file: .backend.env
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- ./backend/db:/usr/src/app/db
active-stream-proxy:
build:
context: ./active-stream-proxy
dockerfile: Dockerfile
depends_on:
web-frontend:
condition: service_completed_successfully
mediamtx:
condition: service_started
volumes:
mediamtx_recordings:
tiling_frontend_build:

7
live-stream/Dockerfile Normal file
View file

@ -0,0 +1,7 @@
FROM alpine:3.20
RUN apk add --no-cache gstreamer gst-plugins-bad
RUN apk add --no-cache ffmpeg
ENTRYPOINT [""]

6
live-stream/run.sh Normal file
View file

@ -0,0 +1,6 @@
gst-launch-1.0 -e wpesrc location="https://en.wikipedia.org/wiki/Main_Page" \
! videoconvert ! videoscale ! videorate \
! "video/x-raw, format=BGRA, width=854, height=480, framerate=30/1" \
! videoconvert \
! x264enc speed-preset=1 \
! filesink location=/dev/stdout | ffmpeg -re -y -i - -listen 1 -i rtmp://127.0.0.1:1936/active-input -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 -t 10 -f flv rtmp://x.rtmp.youtube.com/live2/no-way-am-i-doing-that-again

5
mediamtx/Dockerfile Normal file
View file

@ -0,0 +1,5 @@
FROM bluenviron/mediamtx
COPY . /
ENTRYPOINT ["/mediamtx"]

13
mediamtx/mediamtx.yml Normal file
View file

@ -0,0 +1,13 @@
playback: yes
playbackAddress: :9996
playbackTrustedProxies: [ '127.0.0.1' ]
api: yes
pathDefaults:
record: yes
# Path of recording segments.
# Extension is added automatically.
# Available variables are %path (path name), %Y %m %d %H %M %S %f %s (time in strftime format)
recordPath: /recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordDeleteAfter: 0s
webrtcICEServers2:
- url: stun:stun.l.google.com:19302

View file

@ -1,96 +0,0 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "onboard_live_backend"
version = "0.0.1"
authors = [{ name = "Micha Albert", email = "micha@2231puppy.tech" }]
description = "Backend for OnBoard Live, A Hack Club YSWS grant program"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
"aiohttp==3.9.5",
"aiosignal==1.3.1",
"annotated-types==0.7.0",
"anyio==4.4.0",
"APScheduler==3.10.4",
"attrs==23.2.0",
"black==24.4.2",
"certifi==2024.7.4",
"cffi==1.17.0",
"charset-normalizer==3.3.2",
"click==8.1.7",
"cryptography==43.0.0",
"defusedxml==0.8.0rc2",
"dnspython==2.6.1",
"ecdsa==0.19.0",
"email_validator==2.2.0",
"fastapi==0.112.0",
"fastapi-cli==0.0.4",
"fastapi-oauth2==1.0.0",
"fastapi-utils==0.7.0",
"frozenlist==1.4.1",
"h11==0.14.0",
"httpcore==1.0.5",
"httptools==0.6.1",
"httpx==0.27.0",
"idna==3.7",
"Jinja2==3.1.4",
"markdown-it-py==3.0.0",
"MarkupSafe==2.1.5",
"mdurl==0.1.2",
"multidict==6.0.5",
"mypy==1.11.0",
"mypy-extensions==1.0.0",
"nodeenv==1.9.1",
"oauthlib==3.2.2",
"packaging==24.1",
"pathspec==0.12.1",
"platformdirs==4.2.2",
"prisma==0.14.0",
"psutil==5.9.8",
"pyasn1==0.6.0",
"pycparser==2.22",
"pydantic==2.8.2",
"pydantic_core==2.20.1",
"Pygments==2.18.0",
"PyJWT==2.9.0",
"python-dotenv==1.0.1",
"python-jose==3.3.0",
"python-multipart==0.0.9",
"python3-openid==3.2.0",
"pytz==2024.1",
"PyYAML==6.0.1",
"requests==2.32.3",
"requests-oauthlib==2.0.0",
"rich==13.7.1",
"rsa==4.9",
"shellingham==1.5.4",
"six==1.16.0",
"slack_bolt==1.20.0",
"slack_sdk==3.31.0",
"sniffio==1.3.1",
"social-auth-core==4.5.4",
"starlette==0.37.2",
"tomlkit==0.13.0",
"typer==0.12.3",
"typing-inspect==0.9.0",
"typing_extensions==4.12.2",
"tzlocal==5.2",
"urllib3==2.2.2",
"uvicorn[standard]==0.30.6",
"uvloop==0.19.0",
"watchfiles==0.22.0",
"websockets==12.0",
"yarl==1.9.4",
]
[project.urls]
Homepage = "https://github.com/MichaByte/OnBoard-Live"
[tool.hatch.build.targets.wheel]
packages = ["onboard_live_backend"]
[project.scripts]
onboard-live-backend-start = "onboard_live_backend.main:main"

View file

@ -0,0 +1,16 @@
FROM docker.io/oven/bun:slim AS base
WORKDIR /usr/src/app
FROM base AS install
RUN mkdir -p /temp/dev
COPY package.json bun.lockb /temp/dev/
RUN cd /temp/dev && bun install
RUN mkdir -p /temp/prod
COPY package.json bun.lockb /temp/prod/
RUN cd /temp/prod && bun install --production
FROM base AS release
COPY --from=install /temp/dev/node_modules node_modules
COPY . .
RUN bun --bun run build

Binary file not shown.