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

Nova Audio Laravel Package

davidpiesse/nova-audio

A Laravel Nova field for working with audio files. It provides an easy way to upload, store, and preview audio in Nova resources, with a built-in player for listening to uploaded tracks directly from the admin panel. Ideal for podcasts, music, voice notes, and other audio content.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is not infrastructure — it is a Nova field, a presentation-layer extension to a paid, closed-source admin panel. Its entire contract is: upload a file to a configured disk, write the resulting path into a normal Eloquent string attribute, render a native <audio> element on forms and detail views. That is an extremely small architectural footprint, which cuts both ways. On the positive side, because the audio is stored as a plain filename column, the field imposes no ownership over the asset — the same column can be read by Storage::disk($disk)->url($model->track) from a Blade view, a queue job, an export, or a future API. There is no proprietary storage layer, no schema coupling beyond one string column, and no runtime service to operate. On the negative side, "small" also means "thin": no transcoding, no duration extraction, no waveform, no signed-URL handling, no orphan cleanup, and no accessibility layer beyond whatever the native <audio> element provides. Every one of those gaps becomes our code.

Integration feasibility. Mechanically trivial on the right stack: composer require, then Audio::make('Track', 'track')->disk('public')->path('audio/tracks') in a resource, plus a string column and php artisan storage:link. The unknown is not the API — it is whether a 2020-vintage Vue 2 component mounts at all. Last release is April 2020, which places it squarely in the Nova 2/3 era. Nova 4 (2021) reworked the field and frontend layer; Nova 5 (2024) moved further. On Nova 4/5 the realistic path is a port or a rebuild, not an integration. This is the single gating question in the evaluation, and it must be answered by a timeboxed spike — not by reading the README. Zero dependents means no third party has validated any compatibility claim.

Technical risk. Four concrete risks, in priority order:

  1. Nova version incompatibility (high likelihood, high impact). The classic failure mode is silent: a Nova upgrade breaks the field's JS, admins see a blank input, uploads stop, and nobody notices for a week. Mitigation is a CI job that boots Nova with the field registered so the break fails loudly.
  2. URL strategy unknown for private audio (high impact if applicable). Does the field build a plain Storage::url() or a temporary/signed URL? If the former, any file on a private disk 403s in the player. This must be verified in source before we plan any non-public audio use case.
  3. No upstream (certain). One maintainer, 22 stars, no release in five years, no security-response surface. Adopting it as a dependency is adopting an unowned fork whether we say so or not.
  4. Validation is ours, not theirs. The package will not reliably enforce MIME or size. Extension/MIME allowlisting via ->rules() and deliberate upload_max_filesize / post_max_size / Nginx client_max_body_size tuning are mandatory hardening, not optional polish.

Key questions. Which Nova major are we on today, and which will we be on in twelve months? Is the audio ever non-public, and if so does the field produce signed URLs? Is one-file-per-record genuinely the requirement, or is multi-file/waveform/duration already on the product backlog? Who owns this fork on the roadmap, by name? Is the admin UI ever shown to a client, or is the audio regulated (health, education, call recording)? And: does audio preview become the wedge for a broader media strategy, in which case three single-purpose fields is the wrong abstraction?

Integration Approach

Stack fit. Only viable on Laravel Nova 1–3 with roughly PHP 7.2–7.4. Outside Nova the package is meaningless — it is not a general Laravel audio library and should not be evaluated as one. If we are on Nova 4/5 or Laravel 9+, the correct framing is a rewrite, not an integration.

Migration path. Vendor the source rather than depend on it. Copy into nova-components/ or an internal namespace, pin the commit, own the tests. The dependency route has no support safety net and will float on composer require with no constraint — pin exactly if we ignore this advice, but forking is the honest posture. Adopt the approach, not the dependency.

Compatibility. Two layers to verify separately. PHP/Composer compatibility is cheap to confirm. The Vue component mounting cleanly on our Nova major is the real test and can only be proven by an end-to-end spike: register the field on a throwaway branch, upload a real MP3 through the UI, confirm the column holds the filename, and confirm the player renders on form, detail, and index views. Fifteen minutes of that beats any amount of source reading.

Sequencing. Do it in this order to avoid sunk cost:

  1. Spike (timeboxed, throwaway branch). Confirm Nova version mount, inspect the Vue component and PHP Field class for three things: which file it uploads and to what column, whether it builds a public or signed URL, and what validation it does (probably none).
  2. Storage ADR before resource code. Decide public disk vs. private disk with signed URLs, CDN-fronted vs. proxied, size ceilings at Nginx/PHP. Audio files are large and become a dominant storage and egress cost — this is a billing and infrastructure decision that this field merely inherits. It also sets the precedent for image and video fields that follow.
  3. Dedicated field class per model. Fix project defaults in one subclass so disk and path layout live in config/media.php, not sprinkled across resources.
  4. Hardening. MIME allowlist via ->rules(), explicit size ceiling surfaced as field help text, orphan-file observer or scheduled sweep.
  5. Pilot on one simple resource (PodcastEpisode, LessonAudio, VoicePrompt) before broadening.

If the spike fails on Nova 4/5, fall back to a native File field plus a small bespoke player component scaffolded with nova:field — two to three engineer-days and it removes the third-party surface entirely.

Operational Impact

Maintenance. There is no upstream to lean on. Budget roughly one day per Nova major upgrade for the fork, plus the original port, and give it a named owner on the roadmap. If that stewardship cost is unattractive, the in-house alternative is two to three engineer-days once and no ongoing external surface — a defensible trade.

Support. None. Zero dependents, 22 stars, one maintainer, no release since April 2020, no issue triage, no security-patch surface. Any bug is our bug on day one. This is tolerable for internal tooling and not tolerable the moment a client sees the screen or the audio is regulated — "internal" stops being a defence at that boundary.

Scaling. Fine for one file per record on modest volume. It does not scale into multi-file, ordering, waveforms, duration extraction, transcoding, or HLS streaming — if any of those appear, stop and reach for Spatie Media Library plus an ffmpeg job wrapped in a custom Nova field. Do not bend this one. The dominant scaling cost is not the field, it is storage and egress; keep the disk a config value so switching from public to a CDN-fronted S3 bucket with signed URLs is a config change plus a path re-point, and never hardcode Storage::disk('public') elsewhere.

Failure modes. (1) Silent JS break after a Nova upgrade — blank input, uploads stop, discovered a week late; mitigate with a CI boot test. (2) 403 in the player on private disks if the URL strategy is plain Storage::url(); verify in source before committing to private audio. (3) Opaque 413s when audio exceeds upload_max_filesize / post_max_size / client_max_body_size; set all three deliberately, document the ceiling, and surface it as field help text so an editor does not discover the limit by losing an upload. (4) Orphaned files on record deletion — nothing in the package handles it, and audio is expensive. (5) Codec mismatch — OGG is spotty on Safari, WAV plays but is huge; restrict accepted input to a format we know plays everywhere we care about, or normalise to MP3/AAC on upload. (6) Extension spoofing, if we skip the server-side MIME allowlist.

Ramp-up. Low for any engineer who already knows Nova: the whole loop is one make() call, a string column, and a storage link. The ramp-up risk is not learning the package, it is assuming the package covers validation, orphan cleanup, signed URLs, or accessibility. It does not. Documentation should state plainly what the field does and what we own, so the next engineer does not rediscover it in production.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log