authorizeAbility($request, 'meetings.view'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $recordings = Recording::owned($owner) ->whereHas('session.room', fn ($q) => $q->where('organization_id', $organization->id)) ->with(['session.room']) ->orderByDesc('created_at') ->paginate(20); return view('meet.recordings.index', compact('recordings')); } public function show(Request $request, Recording $recording): View { $this->authorizeAbility($request, 'meetings.view'); $this->authorizeOwner($request, $recording); $recording->load(['session.room', 'session.aiSummaries', 'session.participants']); $recording = $this->recordings->ensureStorageValid($recording); $canManage = app(\App\Services\Meet\MeetPermissions::class) ->can($this->member($request), 'meetings.manage'); return view('meet.recordings.show', compact('recording', 'canManage')); } public function download(Request $request, Recording $recording): StreamedResponse { $this->authorizeAbility($request, 'meetings.view'); $this->authorizeOwner($request, $recording); $recording = $this->recordings->ensureStorageValid($recording); abort_unless($recording->hasPlayableFile(), 404, 'Recording file is not available.'); abort_unless(app(\App\Services\Meet\MeetBillingService::class)->storageIsAccessible($recording), 402, 'Recording storage billing is overdue. Top up your Ladill wallet to download this recording.'); $disk = Storage::disk(config('meet.recordings.disk', 'local')); $extension = strtolower(pathinfo($recording->storage_path, PATHINFO_EXTENSION) ?: 'webm'); $mime = match ($extension) { 'webm' => 'video/webm', 'mp4' => 'video/mp4', 'mkv' => 'video/x-matroska', default => 'application/octet-stream', }; $filename = \Illuminate\Support\Str::slug($recording->session->room->title).'.'.$extension; return response()->streamDownload(function () use ($disk, $recording) { echo $disk->get($recording->storage_path); }, $filename, ['Content-Type' => $mime]); } public function destroy(Request $request, Recording $recording): RedirectResponse { $this->authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $recording); $this->recordings->delete($recording, $this->ownerRef($request)); return redirect()->route('meet.recordings.index')->with('success', 'Recording deleted.'); } }