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

Video Api Laravel Package

sseffa/video-api

sseffa/video-api is a Laravel/PHP package that provides a clean integration layer for video APIs. Configure credentials, call video service endpoints through a simple, testable interface, and keep API logic out of your controllers while building video features faster.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer:

composer require sseffa/video-api

This package was released in early 2017, so on any Laravel after 5.5 you may need to register the service provider and facade manually in config/app.php:

// config/app.php
'providers' => [
    // ...
    Sseffa\VideoApi\VideoApiServiceProvider::class,
],

'aliases' => [
    // ...
    'VideoApi' => Sseffa\VideoApi\Facades\VideoApi::class,
],

Publish the config so you can hold the API credentials:

php artisan vendor:publish --provider="Sseffa\VideoApi\VideoApiServiceProvider"

Add the keys to .env (check the generated config/videoapi.php for exact names — usually YOUTUBE_API_KEY and VIMEO_API_KEY) and then reference them via env() only inside the config file, never in application code.

Where to look first: the facade (Sseffa\VideoApi\Facades\VideoApi) — that's the entire public surface. Then the published config/videoapi.php for key names. The src/ directory contains the provider-specific drivers (Youtube.php, Vimeo.php or similar); read these before relying on the shape of the returned object, because the package does not document its DTO thoroughly.

First use case — resolve a video ID to metadata for a listing/card view:

use Sseffa\VideoApi\Facades\VideoApi;

$video = VideoApi::getVideo('youtube', 'dQw4w9WgXcQ');

// Depending on the driver, these are typically exposed as properties or array keys:
$video->title;
$video->thumbnail;
$video->duration; // ISO 8601 (PT3M33S) — parse before display
$video->description;

If that call returns null, the video is private, deleted, region-locked, or the API key is wrong — always branch on null.

Implementation Patterns

Wrap the facade behind your own service. The package is a thin HTTP wrapper with a static facade; that makes it fragile to swap. Isolate it behind an interface so you can move to the YouTube Data API client directly, emedia/laravel-embeds, or oEmbed later without touching call sites:

class VideoMetaFetcher
{
    public function fetch(string $provider, string $id): ?array
    {
        return Cache::remember("video:{$provider}:{$id}", now()->addHours(6), function () use ($provider, $id) {
            try {
                $video = VideoApi::getVideo($provider, $id);
                return $video ? (array) $video : null;
            } catch (\Throwable $e) {
                report($e);
                return null;
            }
        });
    }
}

Cache aggressively. YouTube's Data API has a daily quota (10,000 units by default). videos.list is cheap (1 unit) but every uncached call still costs, and the package does not cache for you. A cached wrapper that returns the same payload for 6–24 hours is the single biggest reliability win.

Persist metadata, not videos. A common pattern is a videos table keyed by (provider, external_id) populated by a queued job or an artisan command, then rendered from the DB. This decouples page renders from external API latency and lets you fall back gracefully:

Schema::create('videos', function (Blueprint $table) {
    $table->id();
    $table->string('provider');       // 'youtube' | 'vimeo'
    $table->string('external_id');
    $table->string('title')->nullable();
    $table->text('description')->nullable();
    $table->string('thumbnail')->nullable();
    $table->unsignedInteger('duration')->nullable(); // seconds, normalized
    $table->json('raw')->nullable();                 // keep original for future fields
    $table->timestamps();
    $table->unique(['provider', 'external_id']);
});

Normalize durations. YouTube returns PT1H2M3S style ISO-8601 durations; Vimeo returns seconds. Parse YouTube's with new \DateInterval($duration) (or a small regex) and store seconds so Blade views don't have to know the source.

Dispatch fetches from queued jobs for anything in a loop (bulk import, sitemap generation) so a slow/blocked external API cannot hang a request. Use retry(3, 1000) and let failures land in failed_jobs rather than the page.

Blade integration stays trivial if you have a persisted record:

@if ($video)
    <a href="{{ $video->url }}">
        <img src="{{ $video->thumbnail }}" alt="{{ $video->title }}">
        <span>{{ gmdate('i:s', $video->duration) }}</span>
    </a>
@endif

Gotchas and Tips

  • Age and framework compatibility. The last commit is from 2017. On Laravel 9+, PHP 8.1+, or with newer Guzzle versions you may hit method-signature or return-type errors. Budget time to fork (or vendor the src/ directory) and patch the provider's Guzzle call if needed. Don't assume "composer require" is enough on a modern stack — verify with a smoke test.
  • No auto-discovery guarantee. If the package predates Laravel 5.5's package discovery it won't register itself. If VideoApi resolves as "class not found", add the provider and alias manually rather than assuming Composer is broken.
  • YouTube quota errors look like null. When the daily quota is exhausted the API returns a 403 which the package may swallow into a falsy return. Log the raw response on failure — otherwise you'll spend an afternoon debugging "private video" that's actually a quota issue.
  • Vimeo API drift. Vimeo has changed its private-token requirements and deprecated endpoint versions since 2017. If Vimeo returns nothing, test the endpoint in curl first; if the package is hitting a deprecated URL, edit the driver in place rather than trying to work around it.
  • Never read env() outside config. Standard Laravel rule, but especially relevant here because the package may call env('YOUTUBE_API_KEY') internally — after php artisan config:cache, that returns null. If you see intermittent null responses only in production, this is your culprit. Publish and fix the config file.
  • Thumbnail URLs expire. YouTube's mqdefault/hqdefault thumbnails can return 404 after a video goes private or is removed. Cache the image locally (or proxy it) if you're rendering a public listing.
  • Return-type fragility. The result is likely a plain stdClass (or associative array, depending on the driver). Never assume a field exists; use optional($video)->title or $video->title ?? null so a schema change in the upstream API doesn't break a page.
  • Null-return is the only "not found" signal. There is no exception on unknown IDs. Treat null as "video unavailable", not as a bug, and design the UI for it.
  • Extension point is the config file. Adding a provider means writing a new driver class and wiring it in config/videoapi.php; there's no plugin registry. If you need Instagram, TikTok, or Dailymotion, plan to write your own adapter alongside this package rather than extend it.
  • Better alternatives for new work. For greenfield projects, prefer emedia/laravel-embeds or oEmbed (which needs no API key and has fewer quota concerns) for simple embed metadata. Reserve this package for cases where you genuinely need the YouTube Data API fields (stats, tags, category). In either case, the wrapper-plus-cache pattern above is what keeps the integration maintainable when you eventually swap it out.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle