Updated project identity/configs to match Nyone
This commit is contained in:
@@ -2,7 +2,7 @@ APP_NAME=Nyone
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
APP_URL=https://nyone.net
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
@@ -64,8 +64,8 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://localhost:1935
|
||||
STREAMING_HLS_PUBLIC_URL=http://localhost:8888
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://nyone.net:19935
|
||||
STREAMING_HLS_PUBLIC_URL=https://nyone-hls.net
|
||||
STREAMING_VOD_RETENTION_DAYS=30
|
||||
STREAMING_RECORDINGS_PATH=storage/app/private/recordings
|
||||
MEDIAMTX_SHARED_SECRET=change-this-secret
|
||||
|
||||
51
README.md
51
README.md
@@ -1,6 +1,13 @@
|
||||
# Nyone
|
||||
|
||||
Nyone is a Laravel/Inertia live streaming platform scaffold. The first implementation supports one creator channel per user, OBS publishing through MediaMTX RTMP, HLS playback, channel follows, live chat, creator-selected VOD recording, and basic admin moderation.
|
||||
Nyone is a Laravel/Inertia live streaming platform. The current implementation supports one creator channel per user, OBS publishing through MediaMTX RTMP, HLS playback, channel follows, live chat, creator-selected VOD recording, and basic admin moderation.
|
||||
|
||||
## Stack
|
||||
|
||||
- Laravel 13, Fortify auth, Inertia.
|
||||
- React 19, TypeScript, Tailwind CSS 4, Radix UI primitives.
|
||||
- MediaMTX for RTMP ingest, HLS playback, stream auth hooks, lifecycle hooks, and recordings.
|
||||
- PostgreSQL is the production target; SQLite is fine for local development.
|
||||
|
||||
## Local Setup
|
||||
|
||||
@@ -14,11 +21,45 @@ npm run dev
|
||||
php artisan serve
|
||||
```
|
||||
|
||||
Configure MediaMTX from `deploy/mediamtx.yml.example`, replacing `change-this-secret` with `MEDIAMTX_SHARED_SECRET`.
|
||||
For local development, override these values in `.env` if you are not using the production domains:
|
||||
|
||||
```env
|
||||
APP_URL=http://127.0.0.1:8000
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://127.0.0.1:19935
|
||||
STREAMING_HLS_PUBLIC_URL=http://127.0.0.1:19988
|
||||
```
|
||||
|
||||
## Production Values
|
||||
|
||||
The project config is aligned to these production-style domains:
|
||||
|
||||
```env
|
||||
APP_NAME=Nyone
|
||||
APP_URL=https://nyone.net
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://nyone.net:19935
|
||||
STREAMING_HLS_PUBLIC_URL=https://nyone-hls.net
|
||||
MEDIAMTX_SHARED_SECRET=change-this-secret
|
||||
```
|
||||
|
||||
Configure MediaMTX from `deploy/mediamtx.yml`, replacing `change-this-secret` with the same value as `MEDIAMTX_SHARED_SECRET`.
|
||||
|
||||
Creators use:
|
||||
|
||||
- Server: `STREAMING_RTMP_INGEST_URL`
|
||||
- Stream key: `<channel-slug>?token=<generated-stream-key>`
|
||||
- OBS server: `STREAMING_RTMP_INGEST_URL`
|
||||
- OBS stream key: `<channel-slug>?token=<generated-stream-key>`
|
||||
|
||||
Viewer playback uses `STREAMING_HLS_PUBLIC_URL/<channel-slug>/index.m3u8`.
|
||||
Viewer playback uses:
|
||||
|
||||
```text
|
||||
STREAMING_HLS_PUBLIC_URL/<channel-slug>/index.m3u8
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
php artisan test
|
||||
npm run format:check
|
||||
npm run lint:check
|
||||
npm run types:check
|
||||
npm run build
|
||||
```
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
{
|
||||
"$schema": "https://getcomposer.org/schema.json",
|
||||
"name": "laravel/react-starter-kit",
|
||||
"name": "nyone/streaming-platform",
|
||||
"type": "project",
|
||||
"description": "The skeleton application for the Laravel framework.",
|
||||
"description": "Nyone live streaming platform built with Laravel, Inertia React, and MediaMTX.",
|
||||
"keywords": [
|
||||
"nyone",
|
||||
"streaming",
|
||||
"live-streaming",
|
||||
"mediamtx",
|
||||
"inertia",
|
||||
"laravel",
|
||||
"framework"
|
||||
"react"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
@@ -103,4 +108,4 @@
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable"
|
||||
}
|
||||
}
|
||||
|
||||
2
composer.lock
generated
2
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "88c7fcd5b77421cdc2de93c2514309dc",
|
||||
"content-hash": "1d4e9648391a072a961dcab64a9324f9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
|
||||
@@ -13,7 +13,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Laravel'),
|
||||
'name' => env('APP_NAME', 'Nyone'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -52,7 +52,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
'url' => env('APP_URL', 'https://nyone.net'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -112,7 +112,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'),
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'nyone')).'-cache-'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -149,7 +149,7 @@ return [
|
||||
|
||||
'options' => [
|
||||
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
||||
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
|
||||
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'nyone')).'-database-'),
|
||||
'persistent' => env('REDIS_PERSISTENT', false),
|
||||
],
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ return [
|
||||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => rtrim(env('APP_URL', 'http://localhost'), '/').'/storage',
|
||||
'url' => rtrim(env('APP_URL', 'https://nyone.net'), '/').'/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
|
||||
@@ -76,7 +76,7 @@ return [
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
'username' => env('LOG_SLACK_USERNAME', env('APP_NAME', 'Laravel')),
|
||||
'username' => env('LOG_SLACK_USERNAME', env('APP_NAME', 'Nyone')),
|
||||
'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
|
||||
'level' => env('LOG_LEVEL', 'critical'),
|
||||
'replace_placeholders' => true,
|
||||
|
||||
@@ -46,7 +46,7 @@ return [
|
||||
'username' => env('MAIL_USERNAME'),
|
||||
'password' => env('MAIL_PASSWORD'),
|
||||
'timeout' => null,
|
||||
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)),
|
||||
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'https://nyone.net'), PHP_URL_HOST)),
|
||||
],
|
||||
|
||||
'ses' => [
|
||||
@@ -112,7 +112,7 @@ return [
|
||||
|
||||
'from' => [
|
||||
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||
'name' => env('MAIL_FROM_NAME', env('APP_NAME', 'Laravel')),
|
||||
'name' => env('MAIL_FROM_NAME', env('APP_NAME', 'Nyone')),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -129,7 +129,7 @@ return [
|
||||
|
||||
'cookie' => env(
|
||||
'SESSION_COOKIE',
|
||||
Str::slug((string) env('APP_NAME', 'laravel')).'-session',
|
||||
Str::slug((string) env('APP_NAME', 'nyone')).'-session',
|
||||
),
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'rtmp_ingest_url' => env('STREAMING_RTMP_INGEST_URL', 'rtmp://localhost:1935'),
|
||||
'hls_public_url' => env('STREAMING_HLS_PUBLIC_URL', 'http://localhost:8888'),
|
||||
'rtmp_ingest_url' => env('STREAMING_RTMP_INGEST_URL', 'rtmp://nyone.net:19935'),
|
||||
'hls_public_url' => env('STREAMING_HLS_PUBLIC_URL', 'https://nyone-hls.net'),
|
||||
'mediamtx_shared_secret' => env('MEDIAMTX_SHARED_SECRET', 'local-dev-secret'),
|
||||
'vod_retention_days' => (int) env('STREAMING_VOD_RETENTION_DAYS', 30),
|
||||
'recordings_path' => env('STREAMING_RECORDINGS_PATH', storage_path('app/private/recordings')),
|
||||
|
||||
@@ -4,12 +4,12 @@ These configs match the current project domains:
|
||||
|
||||
- App: `https://nyone.net`
|
||||
- HLS playback: `https://nyone-hls.net`
|
||||
- OBS ingest: `rtmp://nyone.net:1935`
|
||||
- OBS ingest: `rtmp://nyone.net:19935`
|
||||
|
||||
MediaMTX stays private on local ports:
|
||||
|
||||
- RTMP ingest: `127.0.0.1:1935`
|
||||
- HLS: `127.0.0.1:1988`
|
||||
- RTMP ingest: `0.0.0.0:19935` directly through MediaMTX
|
||||
- HLS: `127.0.0.1:19988`
|
||||
|
||||
Install layout on Ubuntu/Debian:
|
||||
|
||||
@@ -27,7 +27,7 @@ sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
Make sure DNS points all three hostnames to the server:
|
||||
Make sure DNS points both hostnames to the server:
|
||||
|
||||
- `nyone.net`
|
||||
- `nyone-hls.net`
|
||||
@@ -36,7 +36,9 @@ The Laravel `.env` should use:
|
||||
|
||||
```env
|
||||
APP_URL=https://nyone.net
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://nyone.net:1935
|
||||
STREAMING_RTMP_INGEST_URL=rtmp://nyone.net:19935
|
||||
STREAMING_HLS_PUBLIC_URL=https://nyone-hls.net
|
||||
MEDIAMTX_SHARED_SECRET=change-this-secret
|
||||
```
|
||||
|
||||
Open TCP `19935` on the server firewall for OBS ingest. Nginx is only proxying the Laravel app and HLS HTTPS playback in this setup.
|
||||
|
||||
@@ -168,11 +168,6 @@ MediaMTX current files:
|
||||
- `deploy/mediamtx.yml`: currently points auth/hooks to `https://nyone.net`.
|
||||
- `deploy/mediamtx.home.yml`: points auth/hooks to `https://nyone.net`.
|
||||
|
||||
Known mismatch:
|
||||
|
||||
- `.env` currently points the app at `nyone.net`, while `deploy/mediamtx.yml` points MediaMTX hooks at `nyone.net`.
|
||||
- Before live testing, decide which domain is active and align `.env`, `deploy/mediamtx.yml`, and Nginx config.
|
||||
|
||||
MediaMTX ports currently configured:
|
||||
|
||||
- RTMP: `:19935`
|
||||
@@ -212,4 +207,3 @@ Last known successful verification from previous implementation:
|
||||
```text
|
||||
Read AGENTS.md and docs/ui-ux-handoff.md. Focus only on improving Nyone's UI/UX. Start with the channel watch page and creator studio, keep backend changes minimal, and verify with tests/typecheck/build.
|
||||
```
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"$schema": "https://www.schemastore.org/package.json",
|
||||
"name": "nyone",
|
||||
"description": "Nyone live streaming platform frontend.",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -6,7 +6,7 @@ import AppLayout from '@/layouts/app-layout';
|
||||
import AuthLayout from '@/layouts/auth-layout';
|
||||
import SettingsLayout from '@/layouts/settings/layout';
|
||||
|
||||
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
|
||||
const appName = import.meta.env.VITE_APP_NAME || 'Nyone';
|
||||
|
||||
createInertiaApp({
|
||||
title: (title) => (title ? `${title} - ${appName}` : appName),
|
||||
|
||||
@@ -296,7 +296,7 @@ export default function Dashboard({
|
||||
event.target.value,
|
||||
)
|
||||
}
|
||||
placeholder="Building live with Laravel"
|
||||
placeholder="Building Nyone live"
|
||||
/>
|
||||
</Field>
|
||||
<label className="mt-6 flex h-9 items-center gap-2 rounded-md border px-3 text-sm">
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
@viteReactRefresh
|
||||
@vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"])
|
||||
<x-inertia::head>
|
||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||
<title>{{ config('app.name', 'Nyone') }}</title>
|
||||
</x-inertia::head>
|
||||
</head>
|
||||
<body class="font-sans antialiased">
|
||||
|
||||
Reference in New Issue
Block a user