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

Devtube Laravel Package

devswebdev/devtube

DevTube is a Laravel wrapper around the yt-dlp binary for downloading videos and extracting audio from any URL. Pass a link, pick a format like mp4 or mp3, and get back a collection of MediaFile objects. Requires PHP 8.3+, Laravel 12/13, and yt-dlp.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. DevTube is a deliberately thin Laravel adapter — a service provider, a DevTube facade, a Download class, a MediaFile DTO, one DownloadException, a publishable config, and an Artisan command. That is idiomatic Laravel packaging and it slots cleanly into an existing app: no manual provider registration, no bespoke bootstrapping. The important architectural fact is that this package does not download anything itself. It shells out to the yt-dlp binary through norkunas/youtube-dl-php. So the architecture decision is not "adopt a PHP library," it is "adopt a subprocess invocation of an external, frequently-changing binary into our application tier." Treat the binary and ffmpeg as first-class deployment dependencies, not incidental prerequisites.

Integration feasibility. PHP-side effort is genuinely small: composer require, publish config, set two env values (DEVTUBE_YT_DLP_PATH, DEVTUBE_DOWNLOAD_PATH), smoke-test with php artisan devtube:download. The real feasibility work is environmental: installing and pinning yt-dlp in the image or host, pinning an absolute binary path (php-fpm, queue workers, and interactive shells routinely resolve PATH differently), ensuring ffmpeg only if audio extraction is in scope, and guaranteeing a writable storage path. None of that is hard, but all of it is owned by us, not the package.

Technical risk. Ranked:

  1. Extractor rot. yt-dlp is only as good as its extractors; YouTube and other sites break old versions on a short cycle. Our maintenance cadence on the binary becomes a product-visible reliability characteristic.
  2. Single-maintainer dependency. 36 stars, 0 dependents, one maintainer. That is low ecosystem validation and a thin bus factor. There is no community backstop if the package stalls.
  3. Breaking-change history. v3.0 was a genuinely breaking release (arrays → objects, config keys rewritten, engines and internal classes removed). Assume that pattern repeats.
  4. Blocking subprocess, no async surface. download() is synchronous with no progress, cancellation, or job abstraction. Any use in a request cycle is a worker-exhaustion and timeout incident waiting to happen.
  5. Content, legal, and abuse posture. Arbitrary-URL fetching exposes SSRF-adjacent and disk-exhaustion risks if user-supplied; downloading third-party video carries ToS and rights exposure. This is a policy decision the package cannot make for us.

Key questions.

  • Is this an internal/admin tool or an end-user feature? The answer changes almost everything downstream (rate limiting, abuse controls, retention, legal review).
  • Where does the yt-dlp binary come from in the deploy artifact, and who owns bumping it on a schedule?
  • What are the expected volume and concurrency, and therefore the worker pool and disk budget?
  • What is the fallback when extraction fails — user-facing error, retry, or manual escalation?
  • Has legal/security signed off on arbitrary-URL fetching and content retention?

Integration Approach

Stack fit. Hard gate: PHP 8.3+, Laravel 12 or 13. Verify the application's current versions before any planning. If we are on Laravel 11 or PHP 8.2, this package is unavailable until an unrelated platform upgrade lands — that sequencing dependency should be surfaced immediately, not discovered mid-sprint. Pin the package version explicitly rather than floating, because the package tracks the newest Laravel release line and will move with it.

Migration path. If adopting fresh, there is nothing to migrate — skip to sequencing. If upgrading an existing v2 install, treat it as a real project: re-publish the config with --force and manually re-apply every setting (bin_path, download_path, default_format, output_template, formats replace all old keys); replace every array-style access with MediaFile object access ($media->path() instead of $media['file']->getPathname()); and rewrite any code touching MediaDownload, DownloadConfig, or HelperTrait, which no longer exist. The config rewrite is the sneaky part — a stale config file will not fail loudly, it will just behave differently.

Compatibility and sequencing. Recommended order:

  1. Prove the environment, not the PHP: run php artisan devtube:download <url> --format=mp4 as the web/worker user inside the target image. This isolates binary-vs-package failure before a single line of application code is written.
  2. Wrap the facade behind our own MediaDownloader interface and bind the DevTube implementation in a service provider. Twenty lines, and it converts a package swap into a one-file change — essential given the maintainer risk and the v3.0 precedent.
  3. Introduce a queue job around the call with a generous timeout, bounded retries, and a per-job absolute download directory as the third argument. The default flat storage_path folder plus %(title)s.%(ext)s collides on duplicate titles and makes cleanup awkward.
  4. Express format policy as config presets (extend config('devtube.formats') with our own keys) rather than building yt-dlp flags at call sites — reviewable in a PR, no code change to add a format.
  5. Ship to an admin-only surface first, with retention and observability, before considering broader exposure.

Operational Impact

Maintenance. The PHP-side surface is small and stable-looking; the operational side is not. Binary currency is the recurring cost: a rebuild or patch cadence for yt-dlp (and ffmpeg if audio is in scope), plus a way to detect staleness. Budget this as ongoing ownership, not a one-time setup task. The package's own release cadence is coupled to Laravel majors, so our upgrade calendar inherits that coupling.

Support. With one maintainer, 36 stars, and zero dependents, we should assume no upstream support channel. MIT licensing means the credible contingency is a fork — which is only cheap if we kept the interface wrapper. Document the fork path while the integration is fresh, not during an incident.

Scaling. Scaling is bounded by subprocess concurrency, not by PHP. Each download consumes a worker, CPU, network, and disk for the duration; a long video can occupy a worker for many minutes. Scale horizontally with dedicated queue workers and an explicit concurrency cap, keep downloads off the web tier entirely, and set a disk lifecycle (per-job directory plus scheduled Storage::deleteDirectory()) so storage does not grow monotonically. Egress bandwidth is a real, occasionally surprising cost line at volume.

Failure modes. Two distinct classes, and they must be handled differently:

  • Hard failures (DownloadException): missing or misresolved binary, unwritable directory, failed process. Often transient or environmental — retry-worthy, but the first-line fix is a runbook, because the most common cause is a PATH mismatch between shell and php-fpm/worker.
  • Soft failures (MediaFile with non-null error): removed, geo-blocked, private, or unsupported content. Usually permanent — retrying burns queue capacity for an identical result.

Additional modes to plan for: request timeouts, disk exhaustion, partially written files, silent format fallback when a preset is unsatisfiable, and silent misconfiguration of the published config. The devtube:download command's non-zero exit on failure makes it a good heartbeat probe and a clean cron/backfill entry point.

Ramp-up. Engineering learning curve is low — the public API is a facade, a constructor, and a DTO. The real ramp is operational and should be documented as a runbook in the same order as the debugging path: config/devtube.php → which yt-dlp as the runtime user → storage/logs/laravel.log for the thrown exception → reproduce the URL via the Artisan command to separate package from environment. Get that runbook written before the feature goes live; it is the highest-leverage artifact for reducing support load on a dependency we cannot escalate upstream.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console