takeone-youtube-clone/app/Console/Commands/RenderMatchOgImage.php
ghassan 3e18bd2150 Match videos: composed VS-card OG preview + richer share metadata
Sports match share links now show the full VS composition (fighters,
flags, event, weight class, referee/court/match chips) in WhatsApp /
Telegram / Facebook / Twitter previews instead of the raw video frame.

- Browsershot + puppeteer-bundled Chromium screenshots a dedicated
  1200x675 (true 16:9) render of the vs-mini composition. Chrome runs
  through a small wrapper (bin/browsershot-node.sh) that raises the fd
  limit and reads its full env, since PHP-FPM's stripped env otherwise
  makes Chromium fail to launch.
- Render is JPEG @ q85 (~100 KB) instead of PNG (~700 KB) — WhatsApp
  silently drops OG images above roughly 300 KB, which is why music
  thumbnails always showed and match cards didn't.
- SportsMatchController@store/update renders synchronously so the
  picture is guaranteed to exist before the user copies the share URL;
  edits regenerate and old stamped variants are cleaned. The og:image
  URL carries a ?v={updated_at} stamp so scrapers recache on edit.
- accessShare() (/s/{token}) now detects scraper user agents and serves
  the video page HTML inline instead of a 302 — some crawlers don't
  follow redirects when building link previews.
- og:description / twitter:description built from headerData(): flag
  emoji + fighter names (blue vs red), event, weight, match#, court,
  referee, view count, upload date.
- Fixed 3-dot menu on video cards being hidden behind the next card
  (:has(.dropdown-menu.show) promotes the active card above siblings
  and lifts the overflow:hidden clip on .yt-video-info).
- vs-mini: skip the entrance animation on touch devices and expose a
  .vs-mini-static class so the OG render always captures the final
  frame instead of a random mid-animation moment.

Also adds an admin gallery at /admin/og-previews for spot-checking the
generated preview JPEGs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-08-11 12:34:40 +03:00

48 lines
1.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use App\Http\Controllers\VideoController;
use App\Models\Video;
use Illuminate\Console\Command;
/**
* Renders the 1200×630 VS composition PNG for a match video's social-share
* preview. Runs the same helper used by VideoController@ogImage but from a
* CLI process context, because Chromium reliably fails to launch under
* PHP-FPM ("Failed to launch the browser process: Code: null") on this
* host. Invoke detached via `nohup` from either the ogImage endpoint (on
* cache miss) or SportsMatchController on save.
*/
class RenderMatchOgImage extends Command
{
protected $signature = 'og:render-match {video}';
protected $description = 'Render the OG social-share PNG for a match video';
public function handle(): int
{
$video = Video::find($this->argument('video'));
if (! $video) {
$this->error("Video {$this->argument('video')} not found.");
return 1;
}
if ($video->type !== 'match' || ! $video->sportsMatch) {
$this->error("Video {$video->id} is not a match with a sports record.");
return 1;
}
$controller = new VideoController();
$r = new \ReflectionMethod($controller, 'renderMatchOgImage');
$r->setAccessible(true);
$png = $r->invoke($controller, $video);
if ($png === null) {
$this->error("Render failed. See laravel.log.");
return 1;
}
$this->info("Rendered " . strlen($png) . " bytes for video {$video->id}.");
return 0;
}
}