Haiku BMediaFiles: Registering and Resolving Named Media Resources
Use Haiku BMediaFiles to map media resource names to entry references, enumerate registrations, and handle stale files and audio gain safely.
BMediaFiles is a small registry API for associating a media resource key with an entry_ref. It is useful when an application or media add-on needs to find a named sound or another registered media file without hard-coding a filesystem path. It is not a directory scanner, MIME database, codec registry, or guarantee that the referenced file still exists. The distinction is operationally important: a successful lookup resolves a stored reference, while opening and validating the referenced resource remain separate steps.
The registry has two key components: a type and an item name. The public header exposes BMediaFiles::B_SOUNDS for the "Sounds" type. An item such as an application-defined cue is a name within that type. The API can enumerate types, enumerate item names, fetch or set an entry_ref, and read or write an associated audio gain. Keep these identifiers stable across releases and treat them as keys, not display strings that may be translated.
Resolve an item and validate the referenced entry
The direct lookup workflow starts with a type and item string, then asks for an entry_ref. Check the returned status_t before using the output. A registry result does not establish that the item is readable, is an audio file, or still points to the content your application expects. Resolve the reference to a BEntry or open an appropriate node and handle the result independently.
#include <Entry.h>
#include <MediaFiles.h>
BMediaFiles mediaFiles;
entry_ref soundRef;
status_t status = mediaFiles.GetRefFor(
BMediaFiles::B_SOUNDS, "ExampleCue", &soundRef);
if (status != B_OK)
return status;
BEntry soundEntry(&soundRef, true);
status = soundEntry.InitCheck();
if (status != B_OK)
return status; // Registration exists, but its target may be stale.
The item name here is illustrative. An application should define its own key and document whether the resource is required, optional, or user-configurable. If the target was moved or deleted, do not silently substitute an unrelated file with the same basename. Offer a repair or re-registration path that makes the chosen replacement visible to the user.
Enumerate with explicit cursor state
Enumeration is a rewind-and-next interface. RewindTypes() initializes the type cursor, and GetNextType() returns one type at a time until it reports that the cursor has no next item. For a selected type, call RewindRefs(type) and then GetNextRef() to retrieve item names and, when requested, their references. Handle errors from both rewind and next operations; an empty registry, an exhausted cursor, and an unavailable media service should not be collapsed into one state.
The cursor belongs to the BMediaFiles instance. Do not interleave two enumerations through the same object and assume each has an independent iterator. If a UI needs multiple views, either use separate instances or collect a snapshot into application-owned values. Refresh that snapshot when the user asks to rescan, and expect registrations to change between enumeration and lookup.
Enumeration does not create a durable transaction. A type can disappear or an item can be changed while another process is reading the registry. For each action, use the current lookup result, check its status, then resolve and validate the target. If the application needs a stable session view, retain the already-open resource handle rather than repeatedly trusting a key-to-reference mapping.
Avoid keeping a long-lived BMediaFiles cursor as the application’s only source of truth. A cursor snapshot is useful for populating a menu, but a later click should re-run the direct lookup and handle a missing or changed target. If the menu must remain stable for a session, store the key and display label separately from the current reference, then refresh or invalidate the displayed result when the media service reports a relevant change. This prevents a stale list row from being mistaken for a reservation on the file.
Register and remove without confusing metadata and content
SetRefFor(type, item, ref) changes the reference associated with a key. It does not copy the file, convert its format, or prove that the referenced file remains present. Validate the candidate first, and make the registry update only after the resource is ready. If creation involves a temporary file, finish and close it before publishing the reference. If the registry update fails, keep the old resource recoverable and report the exact failed step.
The implementation uses fixed-length media name fields when preparing requests. Avoid names that would be truncated by the platform limit; reject overlong keys in your own input validation rather than allowing two distinct long names to collapse to the same prefix. Also reject null pointers before calling the API. Use a stable, documented key format such as an application-owned identifier, and keep localization in a separate display label.
Removal APIs have distinct names and signatures. RemoveItem(type, item) removes an item registration; RemoveRefFor(type, item, ref) is an invalidation-oriented operation. Do not infer that the latter deletes the referenced file from disk. Never unlink user data as a side effect of removing a registry entry unless your application separately owns and verifies the file. Check the returned status and refresh any cached enumeration after a mutation.
Treat audio gain as per-resource data
GetAudioGainFor() and SetAudioGainFor() associate a floating-point gain with a type and item. This value is not the same thing as system output volume, a mixer control, or a guarantee that every consumer applies the value. Treat it as registry data for a named media item. Validate values against the application’s range before writing them, and check the status before updating the UI to show the new value.
When gain is user-editable, distinguish a missing value from a value that is explicitly zero if the API’s status behavior permits that distinction. Avoid replacing a lookup failure with an arbitrary default and then persisting that default. Keep a clear fallback policy in the calling component, and present whether the gain came from the registry or from a local default.
Failure-oriented verification
Test a known registration, a missing item, a stale reference, an unavailable media service, a read-only or moved target, an overlong key, and a registry mutation while a UI snapshot is displayed. Verify that lookup status is checked before the out parameter is used, that stale resources produce a repair action, and that removing a registration does not remove the underlying user file. Test gain read/write separately from media playback, because successful registry access does not prove the output path works.
For support diagnostics, record the type, item key, operation, status code, and whether the reference resolved. Avoid logging private path components by default. A report that says only “sound missing” cannot distinguish a missing registration from a dead reference, unreadable file, unsupported format, or downstream playback failure.
Include an explicit rollback plan for configuration UIs that let users choose a resource. Keep the previous key-to-reference association until the new file has been validated and the registry write succeeds. If the resource is later removed, offer a relink action rather than silently falling back to a different similarly named item. This keeps user intent separate from incidental filesystem ordering and makes a configuration repair reproducible.
Acceptance criteria
Accept a BMediaFiles integration when identifiers are stable and bounded, the API status is checked at each cursor and lookup step, every returned entry is resolved and validated before use, mutations preserve the original file unless explicitly owned, and audio gain is not confused with global output volume. Exercise stale-reference recovery and independent playback validation.
BMediaFiles provides a registry boundary, not a resource lifecycle manager. The application still owns file validation, user consent, content compatibility, cache invalidation, and recovery.
Related:
- Haiku BSoundPlayer: Callback Playback, Timing, and Shutdown
- Haiku BMediaFormats: Format Mapping and Encoder Discovery
Sources: