WatchFoobar (Monitor what foobar2000 is playing)

WatchFoobar lets you monitor and display what foobar2000 is playing. The script retrieves the information from Foobar and turns it into a variable that can be used everywhere in Opus. For instance in a button:

How to set up and use

:one:

Download and install foobar2000 or run

winget install --silent --id PeterPawlowski.foobar2000

from a command line.

:two:

Download and install foo_nowplaying2 from GitHub. This component does the heavy lifting for us.

:three:

Configure foo_nowplaying2 in foobar2000:

Paste

%temp%\foobar2000NowPlaying.dop

into the file open dialog (the environment variable needs to expand).

If you want to replicate the demo from above, paste

%artist% - %title% - %playback_time%

into the Format space.

Now Playing 2 offers a gazillion more options - your choice!

:four:

Save CommandWatchFoobar.js.txt to   

%appdata%\GPSoftware\Directory Opus\Script AddIns

:five:

Use WatchFoobarStart and WatchFoobarStop to start and stop the monitoring. The variable

$glob:foobar2000Monitor

will be on or off.

:six:

Use the variable

$glob:foobar2000NowPlaying

to retrieve the current information.

:seven:

This button from the demo combines everything:

// For reference only. Get the fully functional button from below

@evalalways:fb2000mon = Val("$glob:foobar2000Monitor")=="on"
@label:fb2000mon ? Val("$glob:foobar2000NowPlaying") : "<not monitoring>"
@toggle:update

=return fb2000mon ? "WatchFoobarStop" : "WatchFoobarStart"
XML
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>foobar2000NowPlaying</label>
	<icon1>{apppath|foobar2000}foobar2000.exe,-105</icon1>
	<function type="normal">
		<instruction>@evalalways:fb2000mon = Val(&quot;$glob:foobar2000Monitor&quot;)==&quot;on&quot;</instruction>
		<instruction>@label:fb2000mon ? Val(&quot;$glob:foobar2000NowPlaying&quot;) : &quot;&lt;not monitoring&gt;&quot;</instruction>
		<instruction>@toggle:update</instruction>
		<instruction />
		<instruction>=return fb2000mon ? &quot;WatchFoobarStop&quot; : &quot;WatchFoobarStart&quot;</instruction>
		<instruction />
		<instruction>// https://resource.dopus.com/t/watchfoobar-monitor-what-foobar2000-is-playing/51286</instruction>
	</function>
</button>

Things you might enjoy reading

How to use buttons and scripts from this forum

The script's inner workings

JScript
function OnInit(initData) {
    initData.name = 'WatchFoobar';
    initData.version = '2024-06-14';
    initData.url = 'https://resource.dopus.com/t/watchfoobar-monitor-what-foobar2000-is-playing/51286';
    initData.desc = 'WatchFoobar';
    initData.default_enable = true;
    initData.min_version = '13.0';
}

function OnAddCommands(addCmdData) {
    var cmd = addCmdData.AddCommand();
    cmd.name = 'WatchFoobarStart';
    cmd.method = 'OnWatchFoobarStart';
    cmd.desc = 'WatchFoobarStart';
    cmd.label = 'WatchFoobarStart';
    cmd.template = '';
    cmd.hide = false;
    cmd.icon = 'script';

    var cmd = addCmdData.AddCommand();
    cmd.name = 'WatchFoobarStop';
    cmd.method = 'OnWatchFoobarStop';
    cmd.desc = 'WatchFoobarStop';
    cmd.label = 'WatchFoobarStop';
    cmd.template = '';
    cmd.hide = false;
    cmd.icon = 'script';
}

function OnWatchFoobarStart(scriptCmdData) {
    var fsu = DOpus.FSUtil();
    var item = fsu.Resolve('%temp%\\foobar2000NowPlaying.dop');
    var itemID = 'foobar2000NowPlaying';
    fsu.WatchChanges(itemID, item, 'fisw');
    DOpus.vars.Set('foobar2000Monitor', 'on');
}

function OnWatchFoobarStop(scriptCmdData) {
    var fsu = DOpus.FSUtil();
    var itemID = 'foobar2000NowPlaying';
    fsu.CancelWatchChanges(itemID);
    DOpus.vars.Set('foobar2000Monitor', 'off');
}

function OnFilesystemChange(FilesystemChangeData) {
    var itemID = 'foobar2000NowPlaying';
    if (FilesystemChangeData.id != itemID) return;

    var cmd = DOpus.Create().Command();
    var fsu = DOpus.FSUtil();
    var stt = DOpus.Create().StringTools();

    var item = fsu.GetItem(fsu.Resolve('%temp%\\foobar2000NowPlaying.dop'));

    if (fsu.Exists(item)) {
        var tmpFile = item.Open();
        var tmp = stt.Decode(tmpFile.Read(), 'utf8');
        tmpFile.Close();
        var nowPlaying = tmp ? tmp : '<none>';
    } else {
        var nowPlaying = '<none>';
    }

    DOpus.vars.Set(itemID, nowPlaying);
    cmd.UpdateToggle();
}

// reference as
// Val("$glob:foobar2000NowPlaying")
// Val("$glob:foobar2000Monitor")
6 Likes

Thanks!
I already had Foobar2000 and the rest was straightforward.
The premade button worked great once I watched the video.
This makes a nice addition to my titlebar just left of my search window.
The only thing I changed was the Title Format.
I used %artist% - %album% - %title% - %playback_time% - %playback_time_remaining% , but I may change my mind and use something else.

Edit: It's fun the watch several listers in sync with this, for a couple of minutes ...

1 Like

I had another variable foobar2000NextUp lined up and wanted to turn it into a "Starting in %playback_time_remaining%" button or tooltip but that feature seems broken.

Yeah that would be good, but reality is you have it ! Great work !
Here's what it looks like as of tonight.


Naturally, other people implement this differently, but I thought this was a good start.

This is really cool!

Perhaps it could even be expanded so that clicking the button globally pauses/unpauses the playback.

Nice. I wonder if this could be turned into a column with a text (or unicode symbol) next to file name for files that are currently played (if the lister happens to display the same folder the song is in).

The FooBar2000 Command Line Guide is here.
https://wiki.hydrogenaud.io/index.php?title=Foobar2000:Commandline_Guide

It shouldn't be very difficult to write Dopus User Commands to make this even better.

I have made a toolbar of some Foobar2000 command line commands.
I haven't attempted to implement any of these in @lxp's button yet.


The Foobar2000 icon is from @galaxyhub's Express Icon Set

The toolbar buttons use one folder alias.
A folder alias named Foobar2000 points to the folder that contains foobar2000.exe .
In my case it was C:\Program Files\foobar2000 .

The toolbar buttons also use three user commands.
Foobar_Playback.ouc (412 Bytes)
Foobar_Add.ouc (322 Bytes)
Foobar_Window.ouc (371 Bytes)

And here is the toolbar.
Foobar2000.dop (3.0 KB)

Edit: I don't know why this works, but I have found that /Foobar2000\foobar2000.exe /playing_command:Remove {filepath$} adds selected files to the playlist, playing the first one, and removes all other files from the playlist. However, /Foobar2000\foobar2000.exe /playing_command:Remove desn't seem to do anything at all.