# tuna: song information inside OBS Studio

> tuna is a C++ OBS Studio plugin that puts the currently playing track, artist and album on screen, reading from Spotify, MPD, MPRIS, Windows Media Control, a VLC source or a browser script. It fits streamers who want a now playing overlay without building a media integration themselves, and it does not fit a setup that needs audio analysis, since it reports metadata rather than reacting to the signal.

**univrsal/tuna** — Song information plugin for obs-studio

- Repository: https://github.com/univrsal/tuna
- Stars: 928 · Forks: 76
- Language: C++
- License: GPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/univrsal-tuna

## Metadata on screen, not audio analysis

tuna is described as a song information plugin for OBS Studio, and the repository preview shows it running on Linux. The scope is narrow and worth stating plainly: it displays what is playing, it does not listen to the audio.

For a streamer that means the overlay updates when the track changes, with the title, artist and album coming from whichever source reports them. There is no beat detection, no spectrum analysis and no automatic visual reaction to sound. If the goal is a visual that pulses with the music, this plugin does not provide it, and a different category of tool is needed.

What it does provide is the part that is tedious to build: a stable, configurable source of now playing text that sits in an OBS scene. The repository is C++ with GPL-2.0 licensing, the default branch is master, and the recent releases are v1.9.11 from 2025-08-24, v1.9.10 from 2025-03-29 and v1.9.9 from 2024-05-15. The repository is not archived and the last push was on 2026-08-09.

The project is maintained by a single author, with translations contributed by a named list of translators covering Spanish, Russian, Simplified and Traditional Chinese, Brazilian Portuguese, French and Danish. That translation roster is a reasonable proxy for how much of the user base the plugin actually serves.

## One plugin, many ways to learn what is playing

The source list is the substance of the project, and it is where the design decisions live.

Native players are covered through MPRIS, the freedesktop media player interface specification, which catches most Linux players, and through Windows Media Control for Windows. Both of those were taken from an existing OBS plugin, obs_media_info_plugin, and the credits section says so explicitly. The VLC case is separate again and is handled as an OBS VLC source rather than through the operating system.

MPD is supported through libmpdclient, and metadata extraction from local files goes through Taglib, which is how the plugin reads tags off a file rather than from a player session.

Then there are the service integrations: Spotify, YouTube Music through the youtube-music project, and last.fm scrobbling. Spotify here is the desktop application, which is a distinction that matters, because the browser player is handled separately.

Finally there is the catch-all of any window title, which covers whatever the operating system reports as the focused window. That is the least precise source and the most forgiving one, and it is a sensible fallback when a player exposes no machine-readable interface at all.

The point of supporting all of these is that a streamer changes players. The cost of this design is a plugin with several third-party integrations to keep working, and each one is a place where a platform update can break the metadata.

## The browser route relies on a userscript

Web players are handled outside the plugin, through a tampermonkey script that the repository ships at deps/tuna_browser.user.js. With that script installed, the plugin can read the currently playing track from Soundcloud, the Spotify Web Player, Deezer, Yandex Music and Pretzel.rocks.

This is a design decision with real consequences for deployment. A userscript manager is an extra moving part on the machine of the person streaming, and the script has to be kept up to date in step with the plugin. If the browser extension is not installed, or the script is not updated after a plugin upgrade, the web players simply stop reporting and the overlay goes quiet without an obvious error.

The mechanism is a reasonable one for the use case. The browser already knows what is playing in the web player, and the script relays that to the local webserver the plugin runs. But it means the plugin has two deployment models, one where everything is inside the OBS process and one where part of the data path is a browser extension, and the second requires the person in front of the camera to have done something before going live.

For an operator running a studio where several people take turns streaming, that is a checklist item, not a configuration detail.

## Lyrics come from a hosted service

The lyrics HTML overlay is not served locally. Lyrics are fetched through lrclib, the project by tranxuanthang, and the hosting used by tuna is lyrics.vrsal.cc. The overlay is HTML, which fits the OBS model of browser sources.

There are two things to weigh here. The first is availability: a hosted endpoint is a dependency outside your machine, and an overlay that depends on a third-party service responding is an overlay that can fail in front of an audience. The second is correctness of attribution: lyrics are looked up by track metadata, and a lookup service matching on title and artist can return the wrong words for similarly named tracks.

Neither of these is a reason to reject the feature. It is a reason to know that the lyrics path is the least self-contained part of the plugin, and that a broadcaster who cannot have their overlay depend on a remote server should test it in that environment before relying on it.

The release notes for v1.9.10 mention fixes for WMC and for the lyrics overlay along with an updated locale, which tells you both of those paths have needed attention, and that the plugin does keep them working.

## Building from the CMake tree

The README does not contain an installation section, so there is no documented install command to copy and no statement of which directories the plugin files belong in. What the repository does give you is the build system, and it is a complete one.

The top level carries CMakeLists.txt and CMakePresets.json, a cmake/ directory, a build-aux/ directory, a deps/ directory, and a buildspec.json. There is a .clang-format file and a .cmake-format.json for formatting rules, plus a format.sh script at the root, which tells you the project keeps both the C++ sources and the CMake files formatted to a defined style. The .github directory holds a workflow named push.yaml with a badge for pushes to master.

Dependencies are vendored or fetched through the deps/ directory rather than installed by the user, since the repository lists deps/tuna_browser.user.js as a shipped artefact. The credited third-party libraries are Taglib for metadata extraction, libmpdclient for MPD, cpp-httplib for the local webserver and cURL for fetching remote content and API interactions.

So the realistic path to a working plugin is a CMake build with the dependencies present, then loading the resulting binary into OBS the way OBS loads plugins. The specifics of that second step are not written down in this repository, which is a genuine gap for anyone who wants to install rather than develop.

## GPL-2.0 and the cost of shipping a plugin

The licence is GPL-2.0, which matters here in a way it does not for a typical command line tool. A plugin is a binary that gets distributed with somebody else's software, and if you bundle tuna into a streaming setup or hand the binary to another streamer, the copyleft terms attach to that distribution.

For a single streamer building their own setup this is rarely a problem. For a studio that maintains a packaged OBS build, or a project that wants to redistribute the plugin alongside other tooling, it is a decision to make early rather than at release time. The repository states the licence plainly and includes a LICENSE file, so the terms are clear; the point is that the distribution model has to account for them.

The project also leans on several external services and specifications, which is worth a separate look from the licence. The lyrics lookup is hosted by a third party, the web player path depends on a userscript distributed separately from the plugin, and the MPRIS and Windows Media Control implementations come from another plugin that has to be kept in step. A static binary is therefore not the whole system, and an upgrade plan has to cover more than the version number.

The repository is not archived and the last push was on 2026-08-09, with the most recent tagged release from 2025-08-24, so commits are landing more often than releases are cut. That is a normal pattern for a plugin tied to the pace of its upstream platforms, and it means the branch is a better source of fixes than the last tag for anyone willing to build from source.

## Conclusion

Adopt tuna when you run OBS Studio and want a now playing overlay that follows whatever player the host happens to be using, including web players through the bundled tampermonkey script. Skip it if you need audio-reactive visuals, because the plugin reports metadata rather than analysing the stream, and skip it if you cannot ship a GPL-2.0 binary in your distribution. Verify first that your player exposes one of the supported sources, MPRIS on Linux, Windows Media Control on Windows or MPD, before you build, because the browser script route depends on a userscript manager rather than on the plugin alone.

## FAQ

### What sources can the tuna OBS plugin read song information from?

Spotify, MPD, any window title, last.fm scrobbling, the OBS VLC source and YouTube Music, plus most music players through MPRIS and Windows Media Control. With the bundled tampermonkey script it can also read Soundcloud, the Spotify Web Player, Deezer, Yandex Music and Pretzel.rocks.

### How does tuna get lyrics for its overlay?

Lyrics for the lyrics HTML overlay are served through lrclib, hosted at lyrics.vrsal.cc. The overlay is therefore an HTML browser source that depends on a hosted lookup service rather than on local files.

### What does tuna use to read metadata from local files and to talk to MPD?

Metadata extraction via local files goes through Taglib, and the MPD connection uses libmpdclient. The local webserver is implemented with cpp-httplib, and cURL handles fetching remote content and API interactions.

### Is tuna actively maintained and how is it built?

The repository is not archived and the last push was on 2026-08-09, with the most recent release v1.9.11 published on 2025-08-24. The project is C++ and uses CMake, with CMakeLists.txt, CMakePresets.json, a cmake/ directory, build-aux/ and deps/ at the top level.

## Sources

- [Issues](https://github.com/univrsal/tuna/issues)
- [License: GPL-2.0](https://github.com/univrsal/tuna/blob/master/LICENSE)
- [README](https://github.com/univrsal/tuna/blob/master/README.md)
- [Releases](https://github.com/univrsal/tuna/releases)
- [univrsal/tuna on GitHub](https://github.com/univrsal/tuna)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/univrsal-tuna
