diff --git a/apps/web/src/app/(ui)/(protected)/api/mediamtx/publish/route.ts b/apps/web/src/app/(ui)/(protected)/api/mediamtx/publish/route.ts new file mode 100644 index 0000000..7ceaa8e --- /dev/null +++ b/apps/web/src/app/(ui)/(protected)/api/mediamtx/publish/route.ts @@ -0,0 +1,48 @@ +import { prisma } from '@hctv/db'; +import { NextRequest } from 'next/server'; +import { z } from 'zod'; + +export async function POST(request: NextRequest) { + const body = await request.json(); + + const parsed = schema.safeParse(body); + + if (!parsed.success) { + console.log('Parsing error:', parsed.error); + return new Response('Invalid request', { status: 400 }); + } + console.log('Parsed data:', parsed.data); + const { action, protocol, path, password } = parsed.data; + + // if (action !== 'publish') return new Response('Action not allowed', { status: 403 }); + if (action === 'publish' && protocol !== 'srt') { + const key = await prisma.streamKey.findFirst({ + where: { + key: password, + }, + include: { + channel: true, + }, + }); + + if (!key) { + return new Response('Invalid stream key', { status: 403 }); + } + console.log('Stream key valid for channel:', key.channel.name); + } + + return new Response('Request processed', { status: 200 }); + +} + +const schema = z.object({ + user: z.string(), + password: z.string(), + token: z.string(), + ip: z.string(), + action: z.enum(['publish', 'read', 'playback', 'api', 'metrics', 'pprof']), + path: z.string(), + protocol: z.enum(['rtsp', 'rtmp', 'hls', 'webrtc', 'srt']), + id: z.string().nullable(), + query: z.string(), +}); diff --git a/apps/web/src/components/app/Livestream/Livestream.tsx b/apps/web/src/components/app/Livestream/Livestream.tsx index bd6a491..2e7bd99 100644 --- a/apps/web/src/components/app/Livestream/Livestream.tsx +++ b/apps/web/src/components/app/Livestream/Livestream.tsx @@ -3,7 +3,7 @@ import StreamPlayer from '../StreamPlayer/StreamPlayer'; import UserInfoCard from '../UserInfoCard/UserInfoCard'; import ChatPanel from '../ChatPanel/ChatPanel'; -import type { StreamInfo, User, Channel } from '@hctv/db'; +import type { StreamInfo, Channel } from '@hctv/db'; import { useIsMobile } from '@/lib/hooks/useMobile'; export default function LiveStream(props: Props) { diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml index 0d27fa9..a908bb9 100644 --- a/dev/docker-compose.yml +++ b/dev/docker-compose.yml @@ -49,4 +49,11 @@ services: echo "testing nginx config..." /usr/local/nginx/sbin/nginx -t - /usr/local/nginx/sbin/nginx -g 'daemon off;' \ No newline at end of file + /usr/local/nginx/sbin/nginx -g 'daemon off;' + mediamtx: + image: bluenviron/mediamtx:latest + ports: + - 8890:8890/udp + - 8891:8888 + volumes: + - ./mediamtx.yml:/mediamtx.yml \ No newline at end of file diff --git a/dev/mediamtx.yml b/dev/mediamtx.yml new file mode 100644 index 0000000..933a37e --- /dev/null +++ b/dev/mediamtx.yml @@ -0,0 +1,11 @@ +paths: + all: + source: publisher + +srt: yes +srtAddress: :8890 + +hls: yes + +authMethod: http +authHTTPAddress: http://192.168.1.47:3000/api/mediamtx/publish \ No newline at end of file