Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Youtube Utils Bundle Laravel Package

aldaflux/youtube-utils-bundle

Symfony bundle for YouTube API v3 integration, offering services to fetch video, channel, and playlist data, extract video IDs from URLs, a form type for YouTube links, and profiler integration for API requests.

View on GitHub
Deep Wiki
Context7

Getting Started

First, verify what you actually have. Before writing any code, inspect the tarball. The published README.md describes a different package (confirmation-window-bundle — a JS confirmation-dialog helper) than the metadata and repo slug suggest. Run:

composer require aldaflux/youtube-utils-bundle
ls vendor/aldaflux/youtube-utils-bundle/
cat vendor/aldaflux/youtube-utils-bundle/composer.json

Confirm that src/Utils/ApiYoutubeService.php and src/Form/Type/YoutubeUrlCodeType.php actually exist. If they don't, stop — you have a documentation/release mismatch and there is nothing to integrate.

Assume Symfony, not Laravel. This is a Symfony bundle. There is no service provider, no facade, no config/youtube.php, no package discovery, no Blade views, no Eloquent models. If you are in a Laravel codebase, treat this as a reference implementation to read, not a dependency to require. If you are genuinely in a Symfony 6/7 app, the install path below applies.

Configuration (Symfony only). Register the bundle in config/bundles.php, then create config/packages/aldaflux_youtube_utils.yaml:

aldaflux_youtube_utils:
    youtube_api_key: '%env(YOUTUBE_API_KEY)%'

Add YOUTUBE_API_KEY="..." to .env.local. Verify config is picked up with php bin/console debug:config aldaflux_youtube_utils. You will need a YouTube Data API v3 key from Google Cloud Console (enable "YouTube Data API v3" on the project, restrict the key by IP/referrer for server-side use).

First use case. The lowest-risk, highest-value starting point is read-only public video metadata by ID. In a controller:

public function show(ApiYoutubeService $yt, string $videoId): Response
{
    $video = $yt->getVideo($videoId); // array or null on failure
    return $this->render('video/show.html.twig', ['video' => $video]);
}

If that single call works and returns a snippet block, the bundle is doing its job and you can expand. If it 500s or throws a class-not-found, the release contains the other package and you should treat the README's API surface as specification only and build the equivalent in-house (or on google/apiclient).

Implementation Patterns

Service injection as the seam. ApiYoutubeService is auto-wired in Symfony; inject it by type-hint into controllers, commands, Twig extensions, or message handlers. Do not new it — the API key comes from container config. Wrap it in your own thin YoutubeGatewayInterface if you want to be able to swap the implementation later without touching call sites — highly recommended given the maturity of this dependency.

ID normalization at the boundary. The getYoutubeIdFromUrl() helper is the piece most likely to justify the package on its own, because URL-format handling is fiddly and repetitive. Patterns it handles day-to-day:

  • youtube.com/watch?v=ID
  • youtu.be/ID
  • youtube.com/embed/ID
  • youtube.com/shorts/ID
  • bare 11-char IDs

Call it explicitly in your own code rather than relying on the form type:

$id = $yt->getYoutubeIdFromUrl($userInput);
if ($id === null) {
    // reject / show validation error
}

Normalize before persisting. Store the 11-character ID, not the URL — that keeps your schema clean and lets you swap the render format later (embed vs. short link vs. thumbnail) without a migration.

Form type as an input transformer. YoutubeUrlCodeType bundles a DataTransformer that takes "full URL or bare ID" from the user and stores only the ID. Use it as the ->add() type for any "YouTube link" field:

$builder->add('youtubeVideoId', YoutubeUrlCodeType::class, [
    'label' => 'YouTube Video (URL or ID)',
    'required' => false,
]);

Do not put getYoutubeIdFromUrl in a controller and use the form type on the same field — you get double-normalization and a confusing failure mode when an invalid link silently becomes null. Pick one seam: form type for user input, service helper for programmatic input (imports, API, console).

Profiler-driven debugging. In APP_ENV=dev the bundle registers a DataCollector. During development, keep a tab open on the Profiler's YouTube panel; it shows each request and any error response verbatim. This is the fastest way to distinguish the three common failures:

  1. Empty response → API key not loaded (check debug:config)
  2. 403 with quotaExceeded → daily quota burned
  3. 400 with keyInvalid / ipRefererBlocked → key restriction mismatch

Batch/cache around the service. The service is a thin HTTP wrapper — it does no caching. In any route that renders multiple videos (a gallery, a watchlist page), wrap the calls:

$videos = $cache->get('yt.gallery.'.$page, function () use ($yt, $ids) {
    return array_map(fn($id) => $yt->getVideo($id), $ids);
});

Set a TTL matching your content churn (video titles/thumbnails rarely change — 6–24h is reasonable). This is not optional at scale: videos.list is cheap (~1 unit), but if you later add searchVideos it costs ~100 units per call and will exhaust the 10,000/day default in ~100 searches.

Laravel translation. If you are porting rather than depending: re-home getVideo / getChannel / getPlaylist into a YoutubeService class using Http::get('https://www.googleapis.com/youtube/v3/videos', [...]), bind it as a singleton in a service provider, expose a facade if you want parity with Youtube::video($id), and copy the URL-extraction regexes verbatim — they have the most battle-tested edge cases and are the least interesting thing to re-derive.

Gotchas and Tips

The docs are a lie; the code might not be. The README on the published release describes a confirmation-dialog package, not YouTube. This is the single highest-severity issue: you cannot trust the installation steps, the config file name (aldaflux_youtube_utils.yaml per the metadata vs aldaflux_confirmation_window.yaml per the README), or the class names. Every file path and namespace in this guide is drawn from the secondary metadata, not the README. Verify each one against vendor/ before committing to it. If the tarball contains only confirmation-window code, this assessment is moot and you should reject the package outright.

Framework mismatch is not "wrappable." This is a Symfony bundle: it expects config/bundles.php, YAML config under config/packages/, Twig's AbstractExtension, and Symfony's DataCollector API. In Laravel there is no clean shim — you would be porting the class bodies, not installing a package. Do not plan on "just using the service class"; the service likely depends on Symfony's container-injected API key and an HTTP client abstraction that you would have to replace anyway. Plan for a port, budget a day for it, and expect to drop the DataCollector entirely.

License is GPL-3.0-or-later. This is copyleft. Linking it into a proprietary SaaS triggers a distribution question most legal teams will not accept, especially for a package that saves a few days. If this matters to your org, the official google/apiclient (Apache-2.0) or spatie/laravel-youtube (MIT) is a materially safer choice for the same capability.

Maturity signals are red. Zero stars, zero dependents, no issue history, and a "last release" dated 2026-08-06 — in the future. That is a placeholder or a clock artifact, not a shipping cadence. There is no named maintainer visible from the metadata. Assume no one will fix a bug you file. Budget for a fork-and-own if you depend on it: vendor it via path repository or a private fork so upstream disappearance does not break your build.

Quota is the day-to-day operational constraint. The YouTube Data API v3 defaults to 10,000 units/day. Rough costs:

  • videos.list — 1 unit
  • channels.list — 1 unit
  • playlists.list / playlistItems.list — 1 unit
  • search.list — ~100 units

Practical rules: (a) never call search.list on every page render, always through cache with a long TTL; (b) prefer playlistItems.list over search when you control which videos are shown; (c) log quota failures distinctly so you can alert on them rather than discovering them as blank thumbnails; (d) one key per environment (dev/staging/prod) so a staging loop cannot burn the production budget.

API key handling. Restrict the key in Google Cloud Console by IP (server-side only) or, if you must expose it client-side for embeds/IFrame API, by HTTP referrer. Never commit it, never echo it in exception messages — the profiler panel makes it easy to accidentally dump a request URL containing the key into a bug report; check the profiler's redaction behavior before sharing screenshots. Verify php bin/console debug:container aldaflux.youtube.api_key (or the equivalent) has a value after config:cache in production; misconfigured %env()% in YAML is the most common silent failure.

Response shape is array, not object. The service returns decoded arrays (based on the README's $video['snippet']['title'] style usage), not DTOs. Expect: items[0].snippet.{title,description,thumbnails}, items[0].contentDetails.duration (ISO 8601 — parse it, PT4M13S is not a number), items[0].statistics.{viewCount,likeCount} (these are strings, cast before arithmetic). A not-found or deleted video returns items: [], not an exception — always check empty($result['items']) before indexing [0].

Extension points are minimal. There is no documented event, no cache decorator, no retry policy, no HTTP client override hook. If you need any of those (you will, in production), you are adding them yourself around the service, not extending it. Do not plan to "configure retries"; plan to wrap calls in your own try/catch with exponential backoff for 429/5xx.

Invalid URL handling silently returns null in some paths. The form type's transformer may map an unparseable URL to null rather than failing validation, letting '' slip into a NOT NULL column or silently clearing an existing video on edit. If a user edits an article with a valid video and types garbage into the field, you may lose the association without an error message. Add a Callback constraint to the form alongside the type:

->add('youtubeVideoId', YoutubeUrlCodeType::class, [
    'constraints' => [new Assert\Callback(function ($value, $ctx) {
        if ($value === null && originalInputIsNonEmpty()) {
            $ctx->buildViolation('Not a valid YouTube URL or ID.')->addViolation();
        }
    })],
])

Testing. There is no documented test harness or fixture set. If you depend on it, write your own integration tests against a known-good video ID (and expect them to break if that video goes private — pick a stable, public, very old video). Mock the service in unit tests via a YoutubeGatewayInterface, never by hitting the real API in CI; one test run that exhausts the daily search quota will fail the whole team's afternoon.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log