Updated project identity/configs to match Nyone

This commit is contained in:
2026-05-15 17:49:00 +03:30
parent 3a2bd57f23
commit 205e2af253
18 changed files with 82 additions and 38 deletions

View File

@@ -2,7 +2,7 @@ APP_NAME=Nyone
APP_ENV=local APP_ENV=local
APP_KEY= APP_KEY=
APP_DEBUG=true APP_DEBUG=true
APP_URL=http://localhost APP_URL=https://nyone.net
APP_LOCALE=en APP_LOCALE=en
APP_FALLBACK_LOCALE=en APP_FALLBACK_LOCALE=en
@@ -64,8 +64,8 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}" VITE_APP_NAME="${APP_NAME}"
STREAMING_RTMP_INGEST_URL=rtmp://localhost:1935 STREAMING_RTMP_INGEST_URL=rtmp://nyone.net:19935
STREAMING_HLS_PUBLIC_URL=http://localhost:8888 STREAMING_HLS_PUBLIC_URL=https://nyone-hls.net
STREAMING_VOD_RETENTION_DAYS=30 STREAMING_VOD_RETENTION_DAYS=30
STREAMING_RECORDINGS_PATH=storage/app/private/recordings STREAMING_RECORDINGS_PATH=storage/app/private/recordings
MEDIAMTX_SHARED_SECRET=change-this-secret MEDIAMTX_SHARED_SECRET=change-this-secret

View File

@@ -1,6 +1,13 @@
# Nyone # 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 ## Local Setup
@@ -14,11 +21,45 @@ npm run dev
php artisan serve 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: Creators use:
- Server: `STREAMING_RTMP_INGEST_URL` - OBS server: `STREAMING_RTMP_INGEST_URL`
- Stream key: `<channel-slug>?token=<generated-stream-key>` - 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
```

View File

@@ -1,11 +1,16 @@
{ {
"$schema": "https://getcomposer.org/schema.json", "$schema": "https://getcomposer.org/schema.json",
"name": "laravel/react-starter-kit", "name": "nyone/streaming-platform",
"type": "project", "type": "project",
"description": "The skeleton application for the Laravel framework.", "description": "Nyone live streaming platform built with Laravel, Inertia React, and MediaMTX.",
"keywords": [ "keywords": [
"nyone",
"streaming",
"live-streaming",
"mediamtx",
"inertia",
"laravel", "laravel",
"framework" "react"
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
@@ -103,4 +108,4 @@
} }
}, },
"minimum-stability": "stable" "minimum-stability": "stable"
} }

2
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "88c7fcd5b77421cdc2de93c2514309dc", "content-hash": "1d4e9648391a072a961dcab64a9324f9",
"packages": [ "packages": [
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",

View File

@@ -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'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@@ -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-'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@@ -149,7 +149,7 @@ return [
'options' => [ 'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'), '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), 'persistent' => env('REDIS_PERSISTENT', false),
], ],

View File

@@ -41,7 +41,7 @@ return [
'public' => [ 'public' => [
'driver' => 'local', 'driver' => 'local',
'root' => storage_path('app/public'), 'root' => storage_path('app/public'),
'url' => rtrim(env('APP_URL', 'http://localhost'), '/').'/storage', 'url' => rtrim(env('APP_URL', 'https://nyone.net'), '/').'/storage',
'visibility' => 'public', 'visibility' => 'public',
'throw' => false, 'throw' => false,
'report' => false, 'report' => false,

View File

@@ -76,7 +76,7 @@ return [
'slack' => [ 'slack' => [
'driver' => 'slack', 'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'), '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:'), 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
'level' => env('LOG_LEVEL', 'critical'), 'level' => env('LOG_LEVEL', 'critical'),
'replace_placeholders' => true, 'replace_placeholders' => true,

View File

@@ -46,7 +46,7 @@ return [
'username' => env('MAIL_USERNAME'), 'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'), 'password' => env('MAIL_PASSWORD'),
'timeout' => null, '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' => [ 'ses' => [
@@ -112,7 +112,7 @@ return [
'from' => [ 'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), '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')),
], ],
]; ];

View File

@@ -129,7 +129,7 @@ return [
'cookie' => env( 'cookie' => env(
'SESSION_COOKIE', 'SESSION_COOKIE',
Str::slug((string) env('APP_NAME', 'laravel')).'-session', Str::slug((string) env('APP_NAME', 'nyone')).'-session',
), ),
/* /*

View File

@@ -1,8 +1,8 @@
<?php <?php
return [ return [
'rtmp_ingest_url' => env('STREAMING_RTMP_INGEST_URL', 'rtmp://localhost:1935'), 'rtmp_ingest_url' => env('STREAMING_RTMP_INGEST_URL', 'rtmp://nyone.net:19935'),
'hls_public_url' => env('STREAMING_HLS_PUBLIC_URL', 'http://localhost:8888'), 'hls_public_url' => env('STREAMING_HLS_PUBLIC_URL', 'https://nyone-hls.net'),
'mediamtx_shared_secret' => env('MEDIAMTX_SHARED_SECRET', 'local-dev-secret'), 'mediamtx_shared_secret' => env('MEDIAMTX_SHARED_SECRET', 'local-dev-secret'),
'vod_retention_days' => (int) env('STREAMING_VOD_RETENTION_DAYS', 30), 'vod_retention_days' => (int) env('STREAMING_VOD_RETENTION_DAYS', 30),
'recordings_path' => env('STREAMING_RECORDINGS_PATH', storage_path('app/private/recordings')), 'recordings_path' => env('STREAMING_RECORDINGS_PATH', storage_path('app/private/recordings')),

View File

@@ -4,12 +4,12 @@ These configs match the current project domains:
- App: `https://nyone.net` - App: `https://nyone.net`
- HLS playback: `https://nyone-hls.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: MediaMTX stays private on local ports:
- RTMP ingest: `127.0.0.1:1935` - RTMP ingest: `0.0.0.0:19935` directly through MediaMTX
- HLS: `127.0.0.1:1988` - HLS: `127.0.0.1:19988`
Install layout on Ubuntu/Debian: Install layout on Ubuntu/Debian:
@@ -27,7 +27,7 @@ sudo nginx -t
sudo systemctl reload nginx 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.net`
- `nyone-hls.net` - `nyone-hls.net`
@@ -36,7 +36,9 @@ The Laravel `.env` should use:
```env ```env
APP_URL=https://nyone.net 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 STREAMING_HLS_PUBLIC_URL=https://nyone-hls.net
MEDIAMTX_SHARED_SECRET=change-this-secret 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.

View File

@@ -168,11 +168,6 @@ MediaMTX current files:
- `deploy/mediamtx.yml`: currently points auth/hooks to `https://nyone.net`. - `deploy/mediamtx.yml`: currently points auth/hooks to `https://nyone.net`.
- `deploy/mediamtx.home.yml`: 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: MediaMTX ports currently configured:
- RTMP: `:19935` - RTMP: `:19935`
@@ -212,4 +207,3 @@ Last known successful verification from previous implementation:
```text ```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. 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.
``` ```

View File

@@ -1,5 +1,7 @@
{ {
"$schema": "https://www.schemastore.org/package.json", "$schema": "https://www.schemastore.org/package.json",
"name": "nyone",
"description": "Nyone live streaming platform frontend.",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -6,7 +6,7 @@ import AppLayout from '@/layouts/app-layout';
import AuthLayout from '@/layouts/auth-layout'; import AuthLayout from '@/layouts/auth-layout';
import SettingsLayout from '@/layouts/settings/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({ createInertiaApp({
title: (title) => (title ? `${title} - ${appName}` : appName), title: (title) => (title ? `${title} - ${appName}` : appName),

View File

@@ -296,7 +296,7 @@ export default function Dashboard({
event.target.value, event.target.value,
) )
} }
placeholder="Building live with Laravel" placeholder="Building Nyone live"
/> />
</Field> </Field>
<label className="mt-6 flex h-9 items-center gap-2 rounded-md border px-3 text-sm"> <label className="mt-6 flex h-9 items-center gap-2 rounded-md border px-3 text-sm">

View File

@@ -39,7 +39,7 @@
@viteReactRefresh @viteReactRefresh
@vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"]) @vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"])
<x-inertia::head> <x-inertia::head>
<title>{{ config('app.name', 'Laravel') }}</title> <title>{{ config('app.name', 'Nyone') }}</title>
</x-inertia::head> </x-inertia::head>
</head> </head>
<body class="font-sans antialiased"> <body class="font-sans antialiased">