implement powerful viewer count system

This commit is contained in:
2026-05-16 23:38:35 +03:30
parent 95d14f2cec
commit 799581ee52
19 changed files with 762 additions and 17 deletions

View File

@@ -5,6 +5,8 @@ namespace App\Http\Controllers;
use App\Models\Channel;
use App\Models\ChatMessage;
use App\Models\Vod;
use App\Services\Streaming\PlaybackViewerSigner;
use App\Services\Streaming\ViewerCountStore;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Inertia\Inertia;
@@ -12,8 +14,12 @@ use Inertia\Response;
class ChannelController extends Controller
{
public function show(Request $request, Channel $channel): Response
{
public function show(
Request $request,
Channel $channel,
ViewerCountStore $viewerCounts,
PlaybackViewerSigner $playbackViewers,
): Response {
abort_if($channel->isSuspended(), 404);
$channel->load(['category', 'liveBroadcast', 'user']);
@@ -22,7 +28,7 @@ class ChannelController extends Controller
$currentBroadcast = $channel->liveBroadcast;
return Inertia::render('channels/show', [
'channel' => [
'channel' => fn () => [
'id' => $channel->id,
'slug' => $channel->slug,
'display_name' => $channel->display_name,
@@ -31,7 +37,7 @@ class ChannelController extends Controller
'banner_url' => $this->mediaUrl($channel->banner_path),
'thumbnail_url' => $this->mediaUrl($channel->thumbnail_path),
'is_live' => $channel->is_live,
'viewer_count' => $channel->viewer_count,
'viewer_count' => $channel->is_live ? $viewerCounts->current($channel) : 0,
'followers_count' => $channel->follows_count,
'category' => $channel->category ? [
'id' => $channel->category->id,
@@ -43,14 +49,23 @@ class ChannelController extends Controller
'name' => $channel->user->name,
],
],
'currentBroadcast' => $currentBroadcast ? [
'currentBroadcast' => fn () => $currentBroadcast ? [
'id' => $currentBroadcast->id,
'title' => $currentBroadcast->title,
'hls_url' => $currentBroadcast->hls_url,
'hls_url' => $currentBroadcast->hls_url
? $playbackViewers->signedPlaybackUrl($currentBroadcast->hls_url, $channel, $currentBroadcast, $request)
: null,
'recording_enabled' => $currentBroadcast->recording_enabled,
'started_at' => $currentBroadcast->started_at?->toIso8601String(),
] : null,
'vods' => $channel->vods()
'viewerStats' => fn () => [
'current' => $channel->is_live ? $viewerCounts->current($channel) : 0,
'peak' => $currentBroadcast && $channel->is_live
? max($currentBroadcast->viewer_peak, $viewerCounts->current($channel))
: 0,
'refresh_interval_ms' => max(5000, (int) config('streaming.viewer_stats_poll_interval', 30000)),
],
'vods' => fn () => $channel->vods()
->where(function ($query) {
$query->whereNull('expires_at')->orWhere('expires_at', '>', now());
})
@@ -65,7 +80,7 @@ class ChannelController extends Controller
'published_at' => $vod->published_at?->toIso8601String(),
'expires_at' => $vod->expires_at?->toIso8601String(),
]),
'chatMessages' => ChatMessage::query()
'chatMessages' => fn () => ChatMessage::query()
->where('channel_id', $channel->id)
->when($currentBroadcast, fn ($query) => $query->where('broadcast_id', $currentBroadcast->id))
->with('user')
@@ -84,9 +99,7 @@ class ChannelController extends Controller
'avatar_url' => $message->user->avatar,
],
]),
'isFollowing' => $request->user()
? $channel->follows()->where('user_id', $request->user()->id)->exists()
: false,
'isFollowing' => fn () => $request->user() && $channel->follows()->where('user_id', $request->user()->id)->exists(),
]);
}