Beam now reads foobar2000 through the Beefweb HTTP API instead of the legacy COM automation path.
If you are upgrading from an older Beam setup, note that this fork no longer supports the previous deprecated foobar2000 plugin path. Existing users should install Beefweb before moving to v0.7.0.
Check officiaal documentation and foobar componet at: https://www.foobar2000.org/components/view/foo_beefweb
https://github.com/hyperblast/beefweb/blob/master/README.md
What It Does
The adapter lives in bin/modules/win/foobar2kmodule.py. Beam calls run(max_tanda_length) from bin/nowplayingdata.py and expects two values back:
- a playlist of
SongObjectitems - a Beam playback status string such as
Playing,Paused,Stopped, orPlayerNotRunning
The rest of Beam stays unchanged. That is the key design constraint.
Runtime Flow
- Beam calls
run(max_tanda_length). - The module checks whether
foobar2000.exeis running. - The module calls Beefweb
GET /playerwith a list of title-format expressions to fetch player state and the current item. - If Beefweb returns an active playlist and item index, the module calls
GET /playlists/{playlistId}/items/{offset}:{count}to fetch the currently playing song plus the next items. - The module converts each returned Beefweb item into Beam’s
SongObject. - Beam applies its normal rules, cortina logic, and display rendering.
API Endpoints Used
GET /playerReturnsplaybackStateandactiveItem.GET /playlists/{playlistId}/items/{offset}:{count}Returns a slice of the active playlist beginning at the current song.
The implementation requests these columns in order:
[%artist%][%album%][%title%][%genre%][%comment%][%composer%][%date%][%album artist%][%performer%][%path%]
That list maps directly onto Beam’s SongObject fields.
Configuration
Beam now supports saved Foobar2000 Beefweb settings in the main Preferences UI when Foobar2000 is the selected media player.
Open Settings, choose Foobar2000 as the media player, and Beam will show the Foobar2000 Beefweb section directly below the media-player selector.
Beefweb URLDefault:http://localhost:8880/api/Beefweb UsernameOptional username if Beefweb authentication is enabled.Beefweb PasswordOptional password if Beefweb authentication is enabled.Run testRuns the current Foobar2000 integration immediately and shows the detected status, Beefweb target, and current metadata.
These settings are stored in Beam configuration as:
"Foobar2000": {
"BeefwebUrl": "http://localhost:8880/api/",
"BeefwebUser": "",
"BeefwebPassword": ""
}
These values are stored in Beam configuration and used by the foobar module at runtime.
Multiple foobar2000 instances
Beam connects to one Beefweb server URL. It does not detect or manage multiple foobar2000 instances separately.
If you run a second foobar2000 instance for preview or prelisten, Beam can only follow the instance exposed through the configured Beefweb URL.
For a reliable setup, expose Beefweb only on the foobar2000 instance you want Beam to follow. If your preview instance also has Beefweb enabled, disable it there or move it to a different port that Beam is not using.
Beam first reads the saved Preferences values. Environment variables are only used as a fallback for older setups that have not moved to the saved settings yet.
Environment variables are still accepted as a fallback for older setups:
BEAM_BEEFWEB_URLDefault fallback:http://localhost:8880/api/BEAM_BEEFWEB_USEROptional username if Beefweb authentication is enabled.BEAM_BEEFWEB_PASSWORDOptional password if Beefweb authentication is enabled.BEAM_BEEFWEB_TIMEOUTOptional request timeout in seconds. Default:2.0
Example PowerShell session:
$env:BEAM_BEEFWEB_URL = "http://localhost:8880/api/"
$env:BEAM_BEEFWEB_USER = ""
$env:BEAM_BEEFWEB_PASSWORD = ""
python .\beam.py
Important note:
- Beam expects the Beefweb API base URL, not just the web UI root.
- For a default local install, use
http://localhost:8880/api/. - Beam then calls endpoints such as
GET /playerandGET /playlists/...relative to that API base.
How The Playlist Logic Works
Beam’s tanda logic is already implemented outside the foobar module. The only thing the foobar module needs to do is return enough songs in playback order.
The Beefweb implementation therefore returns:
- current song at index
activeItem.index - next items up to
max_tanda_length
That is enough for Beam to populate:
- current song tags
- next song tags
- next tanda tags
No changes are required in the display pipeline for that part.
Failure Behavior
- If foobar2000 is not running, Beam returns
PlayerNotRunning. - If playback is paused, Beam keeps the last song and active mood on screen.
- If playback is stopped, Beam clears the current song display and falls back to the default or not-playing mood.
- If Beefweb is unreachable or misconfigured, Beam returns
BeefwebUnavailableunless it already managed to recover current-song data. - If playlist slicing fails but the player response contains current track columns, Beam can still project the current song.
Diagnostics
- Beam writes a debug log line for each Foobar2000 poll showing the route, status, Beefweb base URL, authentication mode, and active playlist position when available.
- The
Run testbutton in theFoobar2000 Beefwebpreferences section executes the current integration without waiting for the next poll and shows the detected status and song metadata.
How To Extend It
Add more metadata:
- Add another Beefweb column expression in
BEAM_BEEFWEB_COLUMNS. - Map the returned column to a
SongObjectfield. - If it is a brand new Beam field, also update
bin/songclass.py,bin/nowplayingdata.py, and the layout editor tags.
Improve configuration:
- Add Beefweb URL, username, password, and timeout to Beam config.
- Expose those settings in the preferences UI.
- Replace the environment-variable reads in the foobar module with Beam settings accessors.
Support artwork:
- Call
GET /artwork/currentorGET /artwork/{playlistId}/{index}. - Convert the returned bytes into an image object Beam can render.
- Keep this logic in the foobar module or a small helper to avoid leaking Beefweb details into the UI layer.