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

Getid3 Laravel Package

james-heinrich/getid3

getID3 is a PHP library for reading and parsing metadata from audio and video files. It extracts ID3, APE and Lyrics3 tags and analyzes formats like MP3, FLAC, Ogg, AAC, MP4, WAV, AVI and Matroska.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit getID3 is a self-contained, pure-PHP media metadata parser with zero runtime dependencies beyond the standard PHP build. For a Laravel monolith that accepts user-uploaded audio, video, and image assets, it fills a real gap: extracting duration, bitrate, codec, dimensions, and embedded tags (ID3v1/v2, APE, VorbisComment, QuickTime/MP4 atoms, EXIF-adjacent image headers) without provisioning ffmpeg, ffprobe, or exiftool on every app/worker container. That is the strongest argument for it: it removes a binary/system-package dependency from the deploy surface and works identically on FPM, Octane, and queue workers. Architectural caveat — it is not Laravel-aware: no service provider, no facade, no config, and it exposes a global getID3 class plus a GETID3_INCLUDEPATH define convention. It must be wrapped behind our own contract (MediaMetadataExtractor) so the rest of the domain never touches the global class or the raw $fileinfo array shape. Treat it as a low-level adapter, not an application service. It is also file-path based only — remote/streamed sources must be copied to a local temp file first, which forces a deliberate decision about where parsing runs (worker with local scratch disk, not the web tier).

Integration feasibility Low-to-moderate. composer require james-heinrich/getid3 is the documented install path and works cleanly; no PHP extension requirements beyond standard file functions. The work is not "install it," it is the wrapper: a contract, an adapter that normalizes the deeply nested and format-dependent $fileinfo array into our own typed DTO, a config file (size caps, allowed formats, module allowlist, full-scan toggle), and a mapper from getID3's ['error']/['warning'] keys to domain exceptions and structured logs. Key integration realities:

  • Return shape varies per file format — you cannot type against it; you must defensively read optional keys and version the normalized DTO.
  • 1.x signals failure via $fileinfo['error'] array entries rather than exceptions; 2.x throws. Pin the major and code to one contract, or the error handling drifts.
  • Namespace collision risk is non-zero: a root-namespace getID3 class in a large codebase (and with classmap-authoritative optimized autoloading) needs an explicit smoke test in CI.
  • S3/remote disks require tempnam() + stream_copy_to_stream with an enforced byte cap before handing a path to the analyzer.

Estimated effort for a production-grade integration: roughly one to two sprints for composer wiring, wrapper + DTO + config, queued job with timeout/memory guardrails, fixture corpus and Pest coverage, and a backfill command — excluding any tag-writing work.

Technical risk Medium overall, concentrated in four areas:

  1. Licensing (highest process risk, lowest technical risk). The package surfaces as NOASSERTION in composer/SCA metadata, which will fail default license policy gates and SBOM review. The README is actually clear — dual/triple-licensed GPLv1/v2/v3, LGPLv3, MPLv2, plus a retired commercial license — so the resolution is to elect MPL 2.0 and record that election in the license policy, include the notice, and avoid modifying library files (or publish only modified files if we do). The FAQ's "commercial license needed if selling a closed-source program that integrates getID3" is exactly the ambiguity legal must adjudicate for any on-prem/white-label distribution; for a hosted SaaS it is materially lower risk (no AGPL, no network-copyleft), but do not let that nuance go unrecorded. Blocking gate: legal sign-off before the first production deploy.
  2. Maintainer and support model. Effectively a single-maintainer project with a forum-based support channel and SourceForge release notifications, not a modern GitHub-issue workflow. Bus factor of one, no vendor SLA. The reported last-release date (2026-10-30) is inconsistent with the current date and should be verified directly against Packagist/GitHub before we rely on release recency as a health signal. Release cadence is slow; PHP 8.4 deprecation drift (dynamic properties, implicit nullable params) is a live concern — pin the exact version and add a CI job on the PHP minor we intend to adopt next.
  3. Untrusted-input parsing. This is a PHP reimplementation of dozens of binary format parsers running over attacker-controllable bytes. Failure modes include PHP notices/warnings promoted to exceptions under strict error handlers, memory spikes (12MB+ with all modules, more on full-scan mode which walks the entire file), and CPU-time blowups on oversized or adversarial files. Mitigation is architectural, not optional: hard upload size caps, module allowlist, set_time_limit/job timeout, memory_limit headroom on the media queue, and never parsing in the request cycle for anything above a small threshold. Run composer audit and pin; review any advisories before each upgrade.
  4. Write/tagging operations. Tag writing is explicitly caveated by the maintainer as potentially corrupting files. Do not enable writing in the initial release; if a tagging feature is ever greenlit, operate on a copy and treat the original as authoritative.

Key questions

  • Do we actually need multi-format breadth (video/MKV/AVI/ASF), or just audio tags + image dimensions? If it is mostly audio, getID3 is the right tool; if we need reliable video streams/transcode-grade metadata, ffprobe is the correct primitive and getID3 becomes a fallback.
  • Is any part of the product distributed as closed-source binaries or on-prem to customers? If yes, licensing moves from "record the election" to "legal blocker."
  • Where does parsing execute — sync request, dedicated media queue, or a separate service? That determines the guardrail design.
  • What is our tolerance for a single-maintainer dependency with slow releases, and do we have an exit path (the wrapper contract) if it stalls?
  • Is getID3 in the global namespace already present transitively via any other dependency? Any collision would be a silent, hard-to-diagnose failure.

Integration Approach

Stack fit Good fit for a standard Laravel stack (PHP 8.x, Composer 2, MySQL/Postgres, Redis queue, S3-compatible object storage). Pure PHP means no Dockerfile changes, no .so extensions, no system packages — it deploys with the application image and behaves identically in local, CI, and production. It is not a Laravel package, so fit is achieved through our own adapter layer, not through first-party framework integration. The natural boundary:

  • App\Contracts\MediaMetadataExtractor (interface)
  • App\Services\Media\GetId3MetadataExtractor (adapter; owns the getID3 instance, error/warning mapping, DTO hydration)
  • App\Data\MediaMetadata (readonly DTO: duration_ms, bitrate, sample_rate, channels, width, height, codec, container, tags[], error/warning flags)
  • config/media.php (max bytes, allowed extensions, module allowlist, full-scan flag, temp disk)
  • Binding in AppServiceProvider (or a small MediaServiceProvider)

This keeps the global class isolated to one file and makes an FfprobeMetadataExtractor a drop-in later. Do not expose a facade — facades encourage calling it from controllers.

Migration path Greenfield: adopt directly behind the contract with no legacy to unwind. Brownfield (existing getimagesize, id3_get_tag, ad-hoc ffprobe shell-outs, or a hand-rolled MP4 atom reader): replace one call site at a time through the same interface, keeping the old implementation as a shadow comparator in tests until parity on the fixture corpus is demonstrated. If a competing wrapper package is already installed, remove it in the same PR that introduces ours — two packages both defining or aliasing getID3 is the collision scenario to avoid.

Compatibility

  • Verify PHP version support empirically against 8.2/8.3/8.4 on the target minor; README's stated floor (5.3) is not evidence of 8.4 readiness. Add a CI matrix job.
  • Pin an exact version (not a caret range) at first adoption; loosen only after the deprecation surface is understood.
  • Test under classmap-authoritative optimized autoloading and under Octane to confirm the root-namespace class resolves and no static state persists between requests.
  • Confirm behavior under strict error handlers (set_error_handler promoting notices) — wrap analyze() with a scoped handler if needed.
  • Multi-GB files: 64-bit PHP required; even then, end-of-file tags (ID3v1, APE, Lyrics3) are the documented weak spot. Enforce a size cap well below the pain threshold for the initial release.

Sequencing

  1. Spike (2–3 days): composer install, run demos/demo.browse.php against a representative corpus of our real uploads (not sample files), record actual return shapes and any PHP 8.x notices. This de-risks everything downstream.
  2. Legal + license policy: elect MPL 2.0, update SCA allowlist, document the election. Gate before production.
  3. Wrapper + DTO + config + tests: build the adapter, normalize the top-N formats we actually accept, and lock behavior with a committed fixture corpus.
  4. Async execution: AnalyzeMediaMetadata job on a dedicated queue with timeout, memory ceiling, size cap, and WithoutOverlapping; persist normalized fields to typed columns plus a raw JSON blob for forensics.
  5. UI/API surfacing off the persisted columns only — never parse on read.
  6. Backfill command for existing assets, chunked and idempotent, keyed on content hash to skip re-parsing.
  7. Tag writing deferred indefinitely; if required, separate epic with copy-then-write semantics.

Operational Impact

Maintenance Low steady-state code maintenance (the wrapper is thin and stable once the DTO is locked), but non-zero dependency maintenance: pinned version, periodic review of release notes and security advisories, and a recurring PHP-minor compatibility check. Budget roughly a day per quarter for version review plus the CI matrix job. The real maintenance cost is the fixture corpus — every new file type we accept needs a representative sample committed to tests, otherwise the "varies per format" return shape quietly breaks the normalizer. Assign clear ownership: one named engineer as the adapter's owner, since the upstream project will not answer framework-level questions.

Support Upstream support is a community forum and SourceForge release notifications — no SLA, no vendor escalation, no guarantee of response. Our own first-line support must therefore never be "ask getID3." Define the internal runbook: parse failures are classified as caller error (unsupported/corrupt file → user-facing message) vs library error (PHP notice, exception in adapter → engineering ticket with the raw JSON blob attached). The raw $fileinfo payload persisted alongside normalized fields is the single most valuable operational artifact; keep it, with a retention window, and never log full tag contents (PII risk in user-supplied metadata).

Scaling Parsing is CPU- and IO-bound and scales horizontally by adding queue workers — a clean story. Practical constraints:

  • Full-scan mode walks entire files and can dominate cost; disable it globally and enable per-format only where duration accuracy demands it.
  • Memory per parse with all modules is meaningful; a worker handling N concurrent parses multiplies it. Run a dedicated small-concurrency media queue rather than sharing the default worker pool, so a pathological file cannot starve transactional jobs.
  • S3 retrieval adds egress and latency; copy to local scratch with a byte cap, and dedupe by content hash so the same file is parsed once.
  • At high volume, cache aggressively — metadata for a given hash is immutable, so parsed results should be reused indefinitely.

Failure modes

  • Corrupt/adversarial file → ['error'] populated, partial or absent metadata; must degrade gracefully to "unknown," not throw a 500.
  • Oversized file → memory exhaustion or timeout in the worker; enforce the cap before invoking the analyzer, and set explicit job timeout + memory headroom.
  • PHP notice promoted to exception under strict handlers → adapter-level scoped error handling required.
  • Namespace collision on the global getID3 class → fatal on autoload; caught only by an explicit CI smoke test.
  • Long-lived worker state leakage under Octane/queue daemons → instantiate per job, unset() afterwards, never bind as a singleton.
  • Tag-writing corruption (if ever enabled) → irreversible data loss; requires copy-then-write and backups.
  • License-policy failure at build/release → SCA blocks the artifact; prevented by the documented MPL election, but will recur if unrecorded.
  • Upstream abandonment → mitigated by the adapter contract; swap to an ffprobe-backed implementation with no domain-code changes.

Ramp-up Shallow for any Laravel engineer. The API is essentially new getID3; ->analyze($path), so the learning curve is not the library — it is the return-shape variance and the guardrail discipline. Expect half a day of onboarding for an engineer plus the wrapper and fixture corpus as living documentation. The one genuinely specialized skill is knowing which keys are reliably present per format; capture that in the DTO hydration code and in a short internal "media parsing" note rather than tribal knowledge. The upstream README and structure.txt are adequate for the basics; they will not tell you which fields our specific customer files actually populate — only the fixture corpus will.

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.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json