What it doesThe purpose of this component is to allow other programs to control some aspects of foobar2000.
What it does not doThe component
does not enable you to implement foobar2000 components in languages other than C++.
It does not enable you to control or launch more than one instance of foobar2000, be it from the same or different (installation) locations.
FeaturesThe features implemented in 0.7 alpha 2 are:
- querying information about the foobar2000 instance
- querying and modifying playback state and settings
- receiving notifications about changes in the playback state and settings
- querying and modifying the list of open playlists
- receiving notifications about changes in the list of open playlists
- querying the contents of open playlists
- querying the contents of the media libary
- performing the default action on a playlist entry (i.e. the equivalent of double-clicking a playlist entry)
- querying information about tracks through titleformatting
More features are planned for the final version.
DocumentationThere is not much documentation yet. The existing documentation as well as the test and demo scripts/applications are included in the installer (except for the proof-of-concept web panel which is to be announced in a separate post).
CompatibilityThe component requires foobar2000 0.9 or compatible.
The current release is targeted primarily at Visual Basic 6 and scripting clients. It should be useable with clients written in C++, but it has not been tuned yet for this situation.
The component has been tested successfully with clients written in the following languages:
- Visual Basic 6
- VBScript
- Lua 5.0.2 with LuaCOM (some problems with event callbacks)
- Python 2.3 with Pythonwin (no event support AFAIK)
- C# and VB.Net (.Net 1.1)
Known installer issuesThe uninstallation function fails to remove some information from the registry. The following batch file can be used to remove the entries in question from the registry:
reg delete HKCR\TypeLib\{CB8F14D8-736E-4BB7-ADCF-BE26C39B576B} /f
reg delete HKCR\CLSID\{1bffc1e4-21a6-45af-8831-5ee045281633} /f
reg delete HKCR\Foobar2000.Application.0.7 /f
The file is also available for download (see below). Windows NT4 users have to install reg.exe from the Windows NT4 Resource Kit; reg.exe is a native command on Windows 2000 and XP, I suspect it is present on later versions as well.
You have to close foobar2000 and all programs that use the installed type library to run this successfully.
DisclaimerThis is the last section between you and the download links, but please read this carefully!
This component is a work in progress. It is currently labeled as an alpha version, which is primarily due to the incomplete functionality; I try to make sure there are no bugs in the released versions, but I cannot guarantee it. The (COM) interfaces currently exposed by the component are not the ones that the will be in the final version.
While the exposed functionality is quite limited, it may be sufficient for some people. For example the access to playback controls is rather complete; on the other hand, you only get read access to the open playlists and the media library.
There is no scheduled release date for the final version. I will try to advance this component as time permits.
DownloadInstaller (http://foosion.foobar2000.org/0.9/foo_comserver2-0.7-setup.exe)
Registry cleaner tool (http://foosion.foobar2000.org/beta/foo_comserver2-0.7-regclean.bat) (not necessary for latest versions, see below)
Hi,
First, THX for this wonderful, usefull plugin!! I'm working on it for a few times on vb6, and I can do all I want, execpt one thing : I can't find a fonction wich would able me to know which tracknumber is playing in the playlist, or wich is selected. Or this will be pretty good for the program I code.... Is this planned for future version, or am I just a blind man??
THX
PS : I know you didn't schedule any release dates, but do you know if the next version (even beta like this one) will be come soon? Because I'm so hungry of a new version
Version 0.7 only has rudimentary playlist support, a later version will add more functionality in that area, though a release date is completely unknown.
ok, Thanks
great work foosion. is there any delphi example too? i remember seeing it in older version ...
i know that this is of much more use to the community, though you can guess what i would prefer . i'm afraid i would have to abandon my lua scripts when 0.9 final comes. not willing to do so, however ...
foosion, I tried messing with it in mIRC's com scripts, couldnt get alot to work, but the no-argument functions worked fine, like the media library count. Poke me on irc if you know how to use mIRC's com $idents to control foobar further (i couldnt get it to work exactly right after a few hours of fiddling).
Is there a C# example aswell? seeing as you commented it was tested successfully with it.
Why some formattgin string won't wotk with COMServer, %isplaying% for example every return a "?", but if I put it in foobar2000, it works fine....
foosion, I tried messing with it in mIRC's com scripts, couldnt get alot to work, but the no-argument functions worked fine, like the media library count. Poke me on irc if you know how to use mIRC's com $idents to control foobar further (i couldnt get it to work exactly right after a few hours of fiddling).[a href="index.php?act=findpost&pid=355318"][{POST_SNAPBACK}][/a]
Sorry, I have no experience what-so-ever with mIRC scripting. Perhaps you can get some help about COM scripting in general from the mIRC people. I'll see what I can do, if the problem can be traced to my implementation in foo_comserver.
Is there a C# example aswell? seeing as you commented it was tested successfully with it.[a href="index.php?act=findpost&pid=355318"][{POST_SNAPBACK}][/a]
The C# code for the latest version needs to be cleaned up, before I will include it in the installer.
Why some formattgin string won't wotk with COMServer, %isplaying% for example every return a "?", but if I put it in foobar2000, it works fine....[a href="index.php?act=findpost&pid=355505"][{POST_SNAPBACK}][/a]
There are several possible reasons for this. A Track (or Tracks) object does not remember where it originated from, so even if you retrieve the tracks contained in a playlist, you will not be able to access any playlist specific information on the returned object.
On the other hand, the FormatTitle method on the Playback object is hardcoded to use a "display level" that does not include all dynamic information. You can use FormatTitleEx to explicitly set a display level. The possible values for the display level come from the fbDisplayLevel enumeration in the type library. The numeric values for the enumeration members are 0 to 3, where 0 corresponds only to basic static information and 3 means all dynamic information including the current bitrate and the like.
OK, thanks for helping us
foosion, Thanks for the reply. I'll try to mess with the mIRC Scripting side some more and wait for the C# example aswell.
There is a bug in the Volume property: if you retrieve the value, it is scaled down by a factor of 0.01; setting the volume works normally.
Please redownload the installer to get a fixed version (no other changes for now).
Thanks for the heads up.
Hey, this is really cool.
Thanks for writing this foosion, a friendly foobar2k event sender to other applications is exactly what I needed.
However, I'm running into a strange bug(?).
I have referenced the foobar COM component in my C# project, and have added the following (pseudo)code:
private void connectFoobar()
{
// Connect to foobar
foobar = new Application07Class();
foobar.Playback.PositionChanged += new _IVBPlaybackEvents_PositionChangedEventHandler(Playback_PositionChanged);
}
private void Playback_PositionChanged(double dSecondsFromStart, bool bSeekFlag)
{
info.Position = (int)dSecondsFromStart;
// Draw track information to Logitech G15 LCD.
}
This works for 5 or 6 events, then I stop recieving events.
(.. after many edits of this post..)
Aha, it appears calling the garbage collector (GC.Collect()) stops me from recieving COM events. This is why I stop recieving events after 5 or 6 memory-intensive operations. After a couple hundred k's of memory have been moved the GC is called.
I could try to fix this or use a timer instead. I'm glad to have found the cause anyways.
Short version:
You should store a reference to the Playback object somewhere; then you can safely invoke the GC.
Long version:
There is only a single Playback object on the COM side. This COM object is wrapped into a CLR object of type Playback07Class when you access it in C#. Similarly the delegates you create translate between the COM event mechanism and that of the CLR. After you create and register a delegate, it is only referenced in the wrapper class instance (Playback07Class). So unless you keep a reference to the wrapper object, this object and all the delegates can be finalized by the GC anytime, causing them to clean up things on the COM side, i.e. releasing the reference to the wrapped COM object and removing the event subscriptions.
foo_comserver2 v0.7 alpha 4Changes:
- Added helper COM object to detect if server is running (also supports start and exit events)
- Updated example for Visual Basic 6
- Added test script for the helper object for VBScript
- Added example for C#
- Uninstaller now cleans registry (self-unregistration of foo_comserver2.dll is still broken)
The helper object can be used to detect when the server is starting or exiting. However proper error handling does not become unncessary because of this: 1) you receive the exit notification
after the server has exited, and 2) the notification is only sent if the server terminates gracefully (in other words: when foobar2000 does not crash).
The C# example implements rigorous error checking by protecting every access to the server (the Foobar2000.Application.0.7 object and all objects reachable through it) with a try-catch block.
The helper object is implemented in a separate EXE (COMServer2Helper.exe). This EXE starts when a client accesses the Foobar2000.ApplicationHelper.0.7 object and - assuming all clients behave correctly - exits when it is no longer needed. At the moment the server also keeps a reference to the helper as long as it is running, so in effect the helper always runs when foobar2000 is running. This may change in future versions so that the helper is only running when it is indeed used by clients.
If you do not want to use the helper, you can unregister it running the following command on the command line:
COMServer2Helper.exe /UnregServer
To reenable the helper, use:
COMServer2Helper.exe /RegServer
(The commands are actually not case-sensitive... )
Disabling the helper has no negative effects on the server.
Short version:
You should store a reference to the Playback object somewhere; then you can safely invoke the GC.
Yay, this and the new C# example have allowed me to finish my code.
I now have a very efficient application which shows Foobar2000 information on a Logitech G15 LCD. Thanks for making it possible.
(http://www.orfu.net/pics/lglcd05t.jpg) (http://www.orfu.net/pics/lglcd05.jpg)
We'll be working on a foobar2000 display in GTSdll v2 (for mIRC spamming and such).
I was just wondering how much functionality this plugin would eventually provide. It would be very cool to be able to script repetitive stuff using this plugin. For example, when I (legally) download an album in the format of an APE cd image and a cue file, within a zip file, I have to:
1. Extract the file
2. Reencode APE to FLAC
3. Embed cue-sheet in FLAC usign CUESHEET tag
4. Move .flac to D:\music\artist\album
5. Add it to foobar's database
6. Delete all the original files.
Almost all of this can be done through foobar and its components, so if I could access this functionality from COM, it would be very easy to make a JScript or similar completely automating this.
I'm not sure how easy it would be for you to provide the functionality of other components that might/might not be installed, perhaps this could be done within the plugins themselves, eg. foo_comserver would provide a QueryComponents function through which a script can discover, if, for example "diskwriter" is available, and retrieve an interface through which its functionality can be accessed.
I have no idea on how this would best be done, but it would be very very cool if it was possible
And of course using COM instead of some sort of internal scripting makes many other cool things possible, eg. in the example above, the resultant file could also be added to iTunes's library using it's COM interface, and even transcoded and loaded onto an iPod. The ultimate in laziness.
The functionality available through foo_comserver2 will always be a subset of what can be done programmatically on the foobar2000 side. So for the most part this will be things that every component could do using just the SDK. This will include access to the playback engine (mostly complete already), the playlist, the media library (not much there right now, but not much to add either) and perhaps tagging (haven't decided yet).
As for access to other (third-pary) components, well, many of those (including masstagger and converter) cannot be controlled from other components anyway, so binding them to COM is not possible without extra work (by the author of the specific component).
In short, automating what you sketched out above will stay a dream for the foreseeable future.
Error: "This application has failed to start because shared.dll was nout fid. Re-installing the application may fix this problem."
ERROR (CORE) : Failed to load DLL: foo_comserver2.dll, reason: Unable to load DLL.
sad i wanted to try this out, too...
oh, heh, i'm sorry, i found the problem... it installed to the wrong foobar installation on my system. (thats what i get for having billions of test installs of every app imaginable)...
however, now that COM stuff is wokring, LuaCOM isnt. it just keep crashing. oh well. i'll look into it more a bit later.
It seems the Playback.Back and Playback.Forward commands do not work.
I've tried recompiling my program.
I've installed foobar2000 and the COM Automation Server on a clean copy of Windows XP.
It seems the Playback.Back and Playback.Forward commands do not work.[a href="index.php?act=findpost&pid=367249"][{POST_SNAPBACK}][/a]
Well, they simply do not exist. There are only Playback.Previous() and Playback.Next().
It seems the Playback.Back and Playback.Forward commands do not work.[a href="index.php?act=findpost&pid=367249"][{POST_SNAPBACK}][/a]
Well, they simply do not exist. There are only Playback.Previous() and Playback.Next().
[a href="index.php?act=findpost&pid=367262"][{POST_SNAPBACK}][/a]
Sorry, that is what I meant. I should clarify by saying that when I use the Previous() and Next() commands, they don't move to the next or previous item in the playlist.
Thanks for reporting. This was due to a bug in the SDK. Fixed version of COM server should be up tomorrow.
Thanks foosion... I don't know what I'd do without you and the COM Automation Server...
Pull out your hair from the frustration of writing a COM server plugin?
lol
Thanks for reporting. This was due to a bug in the SDK. Fixed version of COM server should be up tomorrow.
[a href="index.php?act=findpost&pid=367306"][{POST_SNAPBACK}][/a]
I just downloaded the current version available and still have the problem... Did you fix this bug yet? Thanks for your help.
It seems the fixed versions was not uploaded correctly. The correct version is now available for download.
Thanks foosion!!!
EDIT:
I received this error after un-installing the older version of the plugin, then downloading the new version and installing it. I even tried re-downloading the latest 0.9 beta and installing that too.
Failed to load DLL: foo_comserver2.dll
Reason: Wrong version number; this component appears to have been built with newer version of foobar2000 SDK, please download latest version of foobar2000 in order to use it.
That's what happens, when you don't check twice. My development machine already has the latest internal version and matching SDK installed. Sorry for that. I'm not sure what will happen first: me recompiling the component with an older SDK (provided I can still find it here), or Peter releasing a new RC. We'll see.
OK. I know how crazy it can get developing with an ever changing SDK/API...
Luckily, the SDK will be stable, once 0.9 goes final, so that's another good reason not to release it before that.
By the way, the version of foo_comserver2 on my page should work with the now current RC (2006-03-11).
Thanks foosion!
So next weekend, if we have the chance to see developement of COM server advanced again? Thx foosion and all the foobar stuuf for the wonderful job you do I'll continue my remote control of foobar soft with all the media library and playlist display on a LCD screen and the ability to manage it with remote (like remote wonder)... THX
foosian,
I really like this and it works great.
One addition, when appropriate would be a method supporting the enqueue function in 0.9 - so that we could remotely add an item to the playback queue.
That would be perfect!
Thanks again,
R
This existed in the previous 0.8.3 version... Foosion will include this later he told me
Here's a simple now playing COM Client i made for mIRC. Just put all the files in one place and load the .mrc file inside mirc. The script should then register the DLL (I wonder if there's a way to automatethe registering better) and the F1\Ctrl+F1 keys handle displaying the info.
Have a look in the script and source files if you wanna know more. Basically used foosion's C# example and another "C# dlls in mirc howto" document, Nothing fancy.
http://rapidshare.de/files/15719603/NowPlaying.rar.html (http://rapidshare.de/files/15719603/NowPlaying.rar.html)
Foosion, you said on your page that the components should work with Final, but the link for COM automation server is dead on the first post
The download link on my components page works though.
Great to see an example for VB6. I really (!) like to see that. Will play with it soon.
One annotation: You could update the license.rtf (2005 is over).
Servus
Chaser
Does a new version planned soon? I can't wait this plugin advanced, so wonderful
Regards
I wonder how easy to do will be a c++ example. Since COM is atriciouly hard to do right in cpp.
Any news about this plugin developpement foosion?
Regards
I wrote a simple COM client in Ruby (http://www.ruby-lang.org/), mainly to use for fetching album art for songs in the media library. Since I (or someone smarter than me) will probably come up with better uses for it in the future, I set up a project page (http://ruby-fb2k.rubyforge.org/) at RubyForge (http://rubyforge.org/).
The simplest use of the script can be summed up in:
require "fetch_album_art"
fetch = FetchAlbumArt.new
fetch.fetch_now_playing # searches for the album art on Amazon for the currently playing track in foobar2000
fetch.download # downloads the album art using titleformat script "$crc32(%artist% - %album%).jpg"
The documentation (http://ruby-fb2k.rubyforge.org/doc/) should explain a lot on how everything works. As of now, the source files (http://rubyforge.org/scm/?group_id=1630) are only on SVN. Once I clean them up a little more, I'll probably package it into a nice installer (so you won't have to mess with the actual code as much).
To incorporate this back into foobar2000, I have the foo_uie_albumart search for album art in "E:\Art\$crc32(%artist% - %album%)".
Excellent plugin foosion.
Foosion, Do you know what basic steps are needed for writing a very simple C++ client?
I've tried including the interface definitions and header files, but couldn't get any of the instances to work properly. My experience with COM is mainly COM+ .NET style, and not much at 'old world COM', sadly.
Anything to help would be appriciated (Right now, as a very ugly workaround, i have a C++ DLL calling a .NET DLL that communicates with foobar's COM Server - i wanna get rid of the .NET dll for compabiltiy with other software).
I could post the very simple c# code im using - more or less get a playback instance, grabs the title format for the current playing track along with some other minor details (foobar version, active playlist index and length) and thats about it.
Again, Any help by anyone with knowledge in COM would be appriciated, Thanks in advance.
Here is a very simple C++ console application that writes some information about the currently playing song to stdout. Note that it requires ATL which does not work all that well with Visual C++ 2005 Express Edition, though the code can be converted to plain COM code. On the other hand, it compiles under VS2003 or even VC6 (untested). You also have to link foobar2000_i.c from the comserver2/include directory with your code.
stdafx.h:
#pragma once
#include <iostream>
#include <tchar.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors are explicit
#include <atlbase.h>
#include <foobar2000_h.h> // add comserver2/include to your project's include directories
cpptest.cpp:
// cpptest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
static void g_report_error(HRESULT hRes, LPCTSTR pszInfo) {
HLOCAL hBuffer = NULL;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, hRes, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPTSTR)(LPVOID)&hBuffer, 0, NULL) > 0) {
LPCTSTR pszMessage = (LPCTSTR)::LocalLock(hBuffer);
if (pszMessage != NULL) {
_tprintf(_T("%s: %s"), pszInfo, pszMessage);
::LocalUnlock(hBuffer);
}
} else {
_tprintf(_T("%s: 0x%08X"), pszInfo, hRes);
}
if (hBuffer != NULL)
::LocalFree(hBuffer);
}
static void g_test() {
CComPtr<IVBApplication> pApp;
HRESULT hRes = pApp.CoCreateInstance(CLSID_Application07);
if (FAILED(hRes)) {
g_report_error(hRes, _T("Object could not be created"));
return;
}
CComPtr<IVBPlayback> pPlayback;
hRes = pApp->get_Playback(&pPlayback);
if (FAILED(hRes)) {
g_report_error(hRes, _T("Playback control could not be accessed"));
return;
}
CComBSTR strFormat;
strFormat = L"%artist% - %title%";
CComBSTR strResult;
hRes = pPlayback->FormatTitle(strFormat, &strResult);
if (FAILED(hRes)) {
g_report_error(hRes, _T("Title formatting failed"));
return;
}
#ifdef _UNICODE
_tprintf(strResult);
#else
#error port me!
#endif
}
int _tmain(int argc, _TCHAR* argv[]) {
::CoInitialize(NULL);
// TODO parse arguments
g_test();
::CoUninitialize();
return 0;
}
Most of that makes sense to me, I'll give it a shot tommorow night or the night after when I'm home.
I have the professional version of 2005 at home, Lets hope ATL works decently with that, or with 2005 at all.
I've seem some mentioning in MSDN docs about ATL and 2005, but they were more refering to the fact that some things wouldn't compile on 2005 anymore (like BSTR concatnation, needs to be wrapped with some other type of class, CString\CStringW).
Anyway, thanks for the example, appriciated.
Foosion, please, I don't want you answer me "Yes, a new version is coming at the %date% ^^". I would know if this plugin is sill under developpement or not (or still under developement, but paused at the moment), because I need it for my project, and if it's not under developpement yet, then I'll search an other way to do what I want to...Not a problem
Regards
LTourist
I would say it is still struggling for development time with all my other components.
Ok thanks Good luck
can anyone tell me how to get this working with the G15?
Well if you using windows API you can use GetAsyncKeyState one
You just have to put a number as an argument wich correspond to a key on your keyboard, when the return value is different from 0, that's mean the key had been pressed since you check GetAsyncKeyState before This is really a simple API to use
In wich language do you need to use foo_comserver?
I'm having a problem when I try to format a track with "%disc%" and the track doesn't have any disc tag.
In this case, I'm getting a OutOfMemoryException (if using with .NET) or an OutOfMemory Error (if using with vbs)
here's a vbs to show this (based on test-medialibrary.vbs from foosion's examples). See comments inside.
option explicit
dim fb2k, ml
dim t1, t2
SetupTest
'Get all tracks in media library
set t1 = ml.GetTracks()
'CHANGE
'Get a track with no disc tag. Change the index appropriately
set t2 = t1(93)
'OK, return the title
WScript.Echo t2.FormatTitle("%title%")
'OK, the track doesn't have a tag named %blabla%, so it returns '?'
WScript.Echo t2.FormatTitle("%blabla%")
'ERROR, the track doesn't have a %disc% tag, and an OutOfMemory error
'(OutOfMemoryException in .NET) is raised
WScript.Echo t2.FormatTitle("%disc%")
CleanupTest
WScript.Echo "Done"
WScript.Quit
rem *********************************************************
rem * helpers functions
rem *********************************************************
sub SetupTest()
dim ProgID
ProgID = "Foobar2000.Application.0.7"
rem WScript.Echo "Looking for existing instance..."
set fb2k = WScript.GetObject("", ProgID)
if isnull(fb2k) then
rem WScript.Echo "Creating new instance..."
set fb2k = WScript.CreateObject(ProgID)
if isnull(fb2k) then
WScript.Echo "Failed to get foobar2000 application object."
WScript.Quit
end if
end if
set ml = fb2k.MediaLibrary
if isnull(ml) then
WScript.Echo "Failed to get foobar2000 media library object."
WScript.Quit
end if
rem save settings
end sub
sub CleanupTest()
rem restore settings
end sub
Anyone else having this problem?
Same here.
First, thanks for this foobar2000 components, it's really helpful
Second, I'm developping a foobar2000 remote control for Yahoo! Widget Engine (YWE) using the COM server. YWE use javascript language, I also used JScript to test the component. So I can provide a JScript test script if you want.
Third, it seems that there are issues with the getters of the component. Here are two examples.
foobarObj.Playback.SeekRelative(10.0);
This code doesn't seem to work well in YWE, maybe it's just a YWE bug. I have a microsoft error report window. I had also an issue with JScript but I'm unable to reproduce the bug.
Also, consider this code:
// ...
// CONNECT/DISCONNECT
// connect to Foobar2000
function connect() {
try {
foobarObj = WScript.createObject(foobarID); // connect to Foobar2000
fooPlayback = foobarObj.Playback;
fooSettings = fooPlayback.Settings;
foobarObj.Minimized = true; // start minimized
WScript.connectObject( fooPlayback, "Playback_"); // playback event sink
WScript.connectObject( fooSettings, "Playback_"); // playback event sink
}
catch(ex) {
WScript.echo("COM createObject failed: '"+ex+"', "+ex.name + ": " + ex.message);
}
};
// disconnect Foobar2000 event sink
function disconnect() {
WScript.disconnectObject(fooSettings);
WScript.disconnectObject(fooPlayback);
};
// EVENT HANDLERS
function Playback_Started( bPaused ) {
// this line is ok
//WScript.echo("foobar started with volume " + fooSettings.Volume + " dB");
// this line does not work
WScript.echo("foobar started with volume " + fooPlayback.Settings.Volume + " dB");
};
In the event handler, the first line is ok, the second one lead to an exception. And, in fact, I had a number of problems whenever I used the XXX.YYY.ZZZ syntax. I was excepting all objects were singletons but it does not seem to be true at all. Is this normal?
Edit: another remark, titleformat support is incomplete in the FormatTitle method, will it be improved?
foobarObj.Playback.SeekRelative(10.0);
This code doesn't seem to work well in YWE, maybe it's just a YWE bug. I have a microsoft error report window. I had also an issue with JScript but I'm unable to reproduce the bug.
This works fine for me when run in csript.exe.
Also, consider this code:
<snip>
In the event handler, the first line is ok, the second one lead to an exception. And, in fact, I had a number of problems whenever I used the XXX.YYY.ZZZ syntax. I was excepting all objects were singletons but it does not seem to be true at all. Is this normal?
I can reproduce this problem with cscript.exe, though I'm currently not sure what's causing it. I'll post more information once I've had time to investigate this further.
Edit: another remark, titleformat support is incomplete in the FormatTitle method, will it be improved?
I'm not sure what you are referring to. If this is about track objects not supporting playlist specific or dynamic information, well, that is intended. If you want dynamic information, you should use the titleformatting method on the Playback object and specify the desired display level.
Also, consider this code:
<snip>
In the event handler, the first line is ok, the second one lead to an exception. And, in fact, I had a number of problems whenever I used the XXX.YYY.ZZZ syntax. I was excepting all objects were singletons but it does not seem to be true at all. Is this normal?
I can reproduce this problem with cscript.exe, though I'm currently not sure what's causing it. I'll post more information once I've had time to investigate this further.
In fact, I use wscript that way: wscript //E:Jscript FooTest.js . The problems appear in wscript, I never tried cscript.
Edit: another remark, titleformat support is incomplete in the FormatTitle method, will it be improved?
I'm not sure what you are referring to. If this is about track objects not supporting playlist specific or dynamic information, well, that is intended. If you want dynamic information, you should use the titleformatting method on the Playback object and specify the desired display level.
Can you tell me a bit more about display levels? I may have missed something since I can't figure what it is for? In fact, I tried to use %playback_time% in Playback.FormatTitle() and a question mark appeared.
Can you tell me a bit more about display levels? I may have missed something since I can't figure what it is for? In fact, I tried to use %playback_time% in Playback.FormatTitle() and a question mark appeared.
From foobar2000.idl:
/**
* Display level codes. Controls level of playback related information that is visible.
*/
[
helpstring("fbDisplayLevel Enumeration")
]
enum fbDisplayLevel
{
/** No playback-related info */
fbDisplayLevelNone = 0,
/** Static info and is_playing/is_paused stats */
fbDisplayLevelBasic = 1,
/** Like fbDisplayLevelBasic plus dynamic track titles on e.g. live streams */
fbDisplayLevelTitles = 2,
/** Like fbDisplayLevelTitles plus timing and VBR bitrate display etc */
fbDisplayLevelAll = 3,
};
You use this with the FormatTitleEx() method on the Playback object.
Oops, sorry, I got my IDL file from Microsoft OLE/COM object browser instead of looking at the one distributed with the component, so there was no comment. Me dumb
I found the problem with the getter for the Settings property. The key points are as follows:
- Some of the COM objects are not singletons and are only created when needed. This is to avoid having (foobar2000) event handlers registered when no (COM) listeners are registered for those.
- Creating a Settings object causes it to register an event handler for volume changes. However, registering event handlers inside event handlers is not allowed (foobar2000 0.9.3 actively checks for this).
I'm working on a fix now that does not break the current COM API, since that would require too much time right now. For the next version, I plan to make event sources separate (non-singleton) objects. The main ideas are that you can access the API without fear of accidentally registering an event handler on the foobar2000 side, and that you will be able to specify which events you are interested in. Right now, the server makes a (blocking) IPC even for events that you do not handle.
I found the problem with the getter for the Settings property. The key points are as follows:- Some of the COM objects are not singletons and are only created when needed. This is to avoid having (foobar2000) event handlers registered when no (COM) listeners are registered for those.
- Creating a Settings object causes it to register an event handler for volume changes. However, registering event handlers inside event handlers is not allowed (foobar2000 0.9.3 actively checks for this).
I'm working on a fix now that does not break the current COM API, since that would require too much time right now. For the next version, I plan to make event sources separate (non-singleton) objects. The main ideas are that you can access the API without fear of accidentally registering an event handler on the foobar2000 side, and that you will be able to specify which events you are interested in. Right now, the server makes a (blocking) IPC even for events that you do not handle.
Ok, thanks for your tech support
Version 0.7 alpha 6 of foo_comserver2 is available on my components page now.
It should fix problems with using playback related interfaces from callbacks. It also checks whether it is properly registered on startup. (This is meant for the situation where you have multiple foobar2000 with foo_comserver2 for some reason.) There is now a preferences page where you can view the registration and running state of the server and helper objects (Tools/COM Automation server).
Note that this version requires foobar2000 0.9.3.
That's a great news!!!! Can we hope see more news like that in future? Thanks
I still have the same SeekRelative problem with the new version but the bug may come from Yahoo! Widget Engine, so I'll tell you more about this issue when the next version of YWE is out!
Nice to see more updates to this. Good work, foosion
I've been attempting to get this to work using PHP 5, using the following code...
<?php
$foobar2000 = new COM("Foobar2000.Application.0.7");
$foobar2000->Playback->FormatTitle("%artist% - %title%");
?>
Obviously very simple. But the script just hangs for a minute or two and then responds with:
Fatal error: Uncaught exception 'com_exception' with message 'Failed to create COM object `Foobar2000.Application.0.7': Server execution failed ' in D:\Server\www\nightiguana\com.php:5 Stack trace: #0 D:\Server\www\nightiguana\com.php(5): com->com('Foobar2000.Appl...') #1 {main} thrown in D:\Server\www\nightiguana\com.php on line 5
My guess is that PHP 5's com support is messed up, since I can't really access any COM objects, or that I have something setup wrong.
EDIT: I've tested PHP 5's COM support and it created a word document for me, so COM seems to be working.
I just installed a fresh copy of PHP 5.1.5. The above script works flawlessly, when I invoke the PHP interpreter from the command line ("php.exe -f test.php"). Do any of the included examples work for you?
As I've re-wrote my code, I no longer use the PHP COM to do my bidding, I have written a VB app which works as a proxy between the web server and foobar by using XMLHTTPRequest to send song updates to the server, which the server then generates the now playing image.
Foosion, attempt to install the latest Apache server, and try running the script as a php file from the web browser. I may just have Apache/PHP set up wrong, but it doesn't apply anymore as I'm using a different approach.
Hi,
I'm currently writing a c# client to control foobar from a remote pc. Are you planning to implement these features:
- Play track at playlist index
- Select track at playlist index
- Add / enqueue tracks to playlist
Would be great!
Sebastian
Good plugin, saves trying to work with the foobar SDK. Thank you.
Hi,
I'm currently writing a c# client to control foobar from a remote pc. Are you planning to implement these features:
- Play track at playlist index
- Select track at playlist index
- Add / enqueue tracks to playlist
Would be great!
Sebastian
Like Sebastian, I am also looking for the object model to be updated to include add and remove a track from the active playlist. If you could consider this update for your next release it would be appreciated.
Regards,
Dean
As I've re-wrote my code, I no longer use the PHP COM to do my bidding, I have written a VB app which works as a proxy between the web server and foobar by using XMLHTTPRequest to send song updates to the server, which the server then generates the now playing image.
Foosion, attempt to install the latest Apache server, and try running the script as a php file from the web browser. I may just have Apache/PHP set up wrong, but it doesn't apply anymore as I'm using a different approach.
Is your Apache running as a service, and if so, is it configured to run as the same user account as foobar2000? I think the default Apache service is configured to run as a network service, and it's possible that this COM server does not work across user accounts.
Nice work.
I have a question: Is it possible or planned to modify the contents of a playlist, or retrieve the currently playing index (if any), and so on?
Unless I'm wrong IVBTracks/IVBTrack allow to enumerate/query various info, but not what I need here.
I believe foosion is working on that part, I'm not exactly sure though.
It is great component, but some functions, like AddTrackBefore(index), AddTrackAfter(index), RemoveTrack(index), MoveTrackTo(old_index, new_index), GetPlaybackIndex() are very usefull, but not exists
As I've re-wrote my code, I no longer use the PHP COM to do my bidding, I have written a VB app which works as a proxy between the web server and foobar by using XMLHTTPRequest to send song updates to the server, which the server then generates the now playing image.
Foosion, attempt to install the latest Apache server, and try running the script as a php file from the web browser. I may just have Apache/PHP set up wrong, but it doesn't apply anymore as I'm using a different approach.
Is your Apache running as a service, and if so, is it configured to run as the same user account as foobar2000? I think the default Apache service is configured to run as a network service, and it's possible that this COM server does not work across user accounts.
Wow, I never thought of that... When I get some time I'll play around and create a separate Apache service just for it
It is great component, but some functions, like ::snip:: GetPlaybackIndex() are very usefull, but not exists
Another vote for this one.
tried comserver2 on vista with foobar 0.9.4.2 and it doesn't seem to register, has anyone else tried it?
Yup, seems to work fine here on RC1, 5728, RC2 and RTM (all build i remember trying it on).
Yup, seems to work fine here on RC1, 5728, RC2 and RTM (all build i remember trying it on).
strange... i'm on RTM and ive tried to register it. But when i look at Preferences > Tools > Com Automation server it says the server is " Not Running: Operation unavailable" and all three paths are " Not available".
thanks for the reply btw
Odd. Both the automated registration during install and manual calls work.. the /regsvr:comserver2 switch.
Keep in mind that the registration procedure needs administrator rights to work.
Keep in mind that the registration procedure needs administrator rights to work.
Ah.. thats what i needed Thanks
That might have been it
Though i'm not running any special account and UAC is turned on.. Maybe i ran the COM Server install as admin (probably, all MSI ask for permissions).
Another question
Is it possible to get coverart through comserver2?
I'm using VBscript
Since when does foobar itself support coverart? Or do you mean a tag-embedded image?
Since when does foobar itself support coverart? Or do you mean a tag-embedded image?
Yeah, I was actually talking about coverart. You're right, It's not possible.
I just read this:
As for access to other (third-pary) components, well, many of those (including masstagger and converter) cannot be controlled from other components anyway, so binding them to COM is not possible without extra work (by the author of the specific component).
this sounds really, really weird, but for some reason, in vb.net 2k5 (.net 2.0), I can't do anything that references to my own form within any of the events. For example, I have this relatively simple code here:
Private Sub fooPlayback_TrackChanged(ByVal bLocationChanged As Boolean) Handles fooPlayback.TrackChanged
Me.Hide()
MsgBox("blah@!")
End Sub
When I try debugging it, the program quite literally goes to Me.Hide(), fails without any error, and skips any subsequent lines altogether. I've been trying to figure out if I'd done something retarted for quite a while now, and I can't think of anything.
By the way, if I omit the Me. Hide() command or try to get, say, the track name from foobar, it'll work fine; it's just whenever I reference to something on my own form, it dies.
EDIT: It's probably something weird with the threading or something, because after creating my own thread-safe routines and some threading hackery, I got it to work. I suspect it's because the event routine is pretty much another thread, and .net usually can do the thread-safe stuff for you properly. There's probably something weird with this COM component which prevented it from happening. .net doesn't seem to like COM stuff much; it's done a lot of weird things before when I tried to get it to work with old COM components
EDIT AGAIN: seems like I can get some events to work, like trackchanged(?) but volumechanged just doesn't call at all
I'm using VB2005, and all works fine here
I'm sorry to asking this again foosion, but....Any news of the development status???
LTourist
I'm re-writing my InfoBar application, and coming up with some cool stuff for my Media Player Control module. Gotta love what you can do with COM Server...
Below is a screen shot of work in progress... Click for full size version:
(http://www.nightiguana.com/software/infobar/files/image1thumb.jpg) (http://www.nightiguana.com/software/infobar/files/image1.jpg)
Link to your infobar application?
I haven't released a build yet, but when one is available I'll let everyone know.
I just installed this but the COM server does not seem to be running.
I want to play with this in PHP because that would be pretty good fun.
Do I need to restart or something? I have admin rights etc.
Just make sure its registered right, Look at the foobar options page for the COM Server status. Works right after installing for me, as long as the regsvr command went ok.
foosion:
Any updates on development? What I'd really love is the ability to get the current playing song and edit a tag.
Specifically, my InfoBar app has a track rating dropdown button just waiting for some code on your end...
jimbo11883 is right. We NEED tag editing!
Hi, I have a question about this component. Well, lots of questions actually, as I don't really know much about using languages like C++, but I really want to make use this component, specifically I am hoping to get buttons in RocketDock (http://rocketdock.com/) that can control foobar, but I don't even know if this is possible! That seems to be the kind of thing this component is designed to do, and it would be awesome to have playback buttons in RocketDock, so... can anyone tell me where to start? What programs do I need, where can I learn what code I will need to write etc. Do I even need this component? I have been looking into things and it seems you can design "docklets", which might do the trick. Hmm, I'll keep looking.
Cheers!
I do not know RocketDock or how to extend it, but you generally do not need the COM Server plugin unless you want to get data from foobar2000. If you merely want to trigger certain playback functions, you can use the command line interface for foobar2000 (run foobar2000.exe with the /? parameter to get a list of supported commands).
I do not know RocketDock or how to extend it, but you generally do not need the COM Server plugin unless you want to get data from foobar2000. If you merely want to trigger certain playback functions, you can use the command line interface for foobar2000 (run foobar2000.exe with the /? parameter to get a list of supported commands).
Thanks for the info, although I just tried making shortcuts with those commands, but they didn't work when I moved them onto the dock. I guess it's a RocketDock issue, I should probably go and ask on their forums, if they have any.
OK I've managed to make some basic controls for RocketDock using the /playpause and /stop arguments (I made icons in RocketDock itself rather than trying to move shortcuts from the desktop), but I am trying to get Stop after Current, and it's not working. I have tried /command:<stopaftercurrent>, /command:<Stop after Current> (but that returned errors saying it didn't know what "after" and "Current" meant) and /playing_command:<stopaftercurrent>, but nothing has worked.
Also, I would like to have the title of the currently playing track in RocketDock, am I able to add commands that this COM automation component can use in either the target (So C:\...\foobar.exe) or the argument (like /play)? I realize you don't know how RocketDock works foosion, (there may be some other stuff I can try) so can you tell me how to send out the information in general, and I'll see if I can get it into RocketDock myself?
Thanks!
Try:
foobar2000 /command:"Stop After Current"
Note that foo_comserver cannot 'send' information, it merely allows external scripts and programs to access information. You would need to write a script of some sort, and I have no idea if that is possible with 'RocketDock' or even what RocketDock is.
Try:
foobar2000 /command:"Stop After Current"
Note that foo_comserver cannot 'send' information, it merely allows external scripts and programs to access information. You would need to write a script of some sort, and I have no idea if that is possible with 'RocketDock' or even what RocketDock is.
Thank you! I got Stop after Current to work. As for the second thing, am I right in thinking that you have to write the script with the program you want to access this information, or do you have to make this program access the script? Or both? I really know very little about COM automation!
What I'm looking for is some general idea of how to write a script that accesses this information, then I'll try and get RocketDock to use it. RocketDock is pretty win though, it's like the dock you get on Macs but better. And you can control Foobar from it!
The COM server comes with some script examples in various languages, If you want to take a look. They are intended for people with scripting\coding\programming experience though.
Yup, seems to work fine here on RC1, 5728, RC2 and RTM (all build i remember trying it on).
strange... i'm on RTM and ive tried to register it. But when i look at Preferences > Tools > Com Automation server it says the server is " Not Running: Operation unavailable" and all three paths are " Not available".
thanks for the reply btw
This is exactly what I get too, XP Home SP2, running admin.
I had comserver installed before (dunno which version), and uninstalled both COM and foobar x.x.x.3 and then installed foobar x.x.x.5
I installed comserver (latest version), and it shows up in my component list for foobar but it says what I quoted above.
I dont have foobar installed in D:\program files\foobar2000 (D:\ is the main hdd) but instead C:\foobar
How do I reregister it?
As the readme says, You launch foobar's main executable with the /regsvr:comserver2 argument.
Again, In every Vista version i tried, and currently on SP1 RC1, I've not experienced that issue at all. Try re-registering and see what you come up with.
can i use vbscript to display fb2k's current volume level?
nvm
The features says that it can perform the default action on a playlist entry, how do you inplement that? It wasn't in any of the example
Playlist objects have a DoDefaultAction(index) method. The index parameter specifies the item in the playlist on which you want to perform the default action.
Awesome
As the readme says, You launch foobar's main executable with the /regsvr:comserver2 argument.
Hi,
can someone please tell me what this means and how I do it ?. I'd like to get Foobar to work with an old Creative remote control connected to the Com port...
Thanks
Alex
The physical COM port isn't the COM this plugin is talking about.
http://en.wikipedia.org/wiki/COM_(hardware_interface) (http://en.wikipedia.org/wiki/COM_(hardware_interface))
http://en.wikipedia.org/wiki/Component_Object_Model (http://en.wikipedia.org/wiki/Component_Object_Model)
This component has nothing to do with COM ports and remote controls. The "COM" in its name refers to Microsoft's Component Object Model.
This component has nothing to do with COM ports and remote controls. The "COM" in its name refers to Microsoft's Component Object Model.
Ah, I see.
Thank you nevertheless.
Alex
jimbo11883 is right. We NEED tag editing!
I want to write tag change batch processing by script languages other than TF.
I wrote a simple mIRC "now playing" script using the COM Automation server. I only tested it with mIRC 6.31.
Feel free to include the script in the distribution and to edit the comments at the top as appropriate.
; Basic interface to the foobar2000 COM Automation Server component
; Only works with the 0.7 series of the fb2k COM Automation Server
;
; Currently only allows getting title formatted strings, but can be extended
; Mostly useful for now-playing scripts
;
; Script written by Niels Hansen (jfs) and may be freely distributed without limitations
alias -l fb2k_ensure_open {
if ($com(fb2kPlayback) != fb2kPlayback) {
if ($com(fb2k) != fb2k) {
echo -a * foobar2000 COM object not open, opening...
.comopen fb2k Foobar2000.Application.0.7
if ($comerr == 0) {
echo -a * Opened foobar2000 COM object
}
else {
echo -a * Failed opening foobar2000 COM object
halt
}
}
echo -a * foobar200 Playback COM object not open, opening...
if ($com(fb2k,Playback,3,dispatch* fb2kPlayback) == 0) {
echo -a * Failed opening fooobar2000 Playback COM object
halt
}
else {
echo -a *Opened foobar2000 Playback COM object
}
}
}
alias fb2k_get_current_format {
fb2k_ensure_open
var %res = $com(fb2kPlayback,FormatTitle,1,bstr,$1-)
if (%res) {
return $com(fb2kPlayback).result
}
else {
echo -a * Failed getting title data from foobar2000
halt
}
}
alias fb2k_get_current {
if (!%fb2k_default_format) {
set %fb2k_default_format $chr(37) $+ artist $+ $chr(37) - $chr(37) $+ title $+ $chr(37)
}
return $fb2k_get_current_format(%fb2k_default_format)
}
alias fb2k {
say fb2k: $fb2k_get_current
}
If you want to use the script as-is and aren't much into mIRC scripting:
You need to insert the script as a
Remote script, not on the Aliases tab in the script editor but in the Remote tab.
Then use the command
/fb2k to display what you're listening to in foobar2000
You can go to the Variables tab in the script editor and change the
%fb2k_default_format variable to a different title formatting string to make the script show something else.
I want to access foobar2000 in a PHP script running on my local Apache. This line seems to work:
$foobar2000 = new COM("Foobar2000.Application.0.7");
But var_dump() only outputs this:
object(com)#1 (0) { }
What could be wrong?
Edit: Never mind. It works. I just didn't know that COM objects have invisible methods and values.
Is it possible to know if a certain track in a playlist is the one that's currently playing? %isplaying% and %list_index% don't seem to work. They are returned as a question mark for every track.
P.S.: Here's a list of all fields and methods of the COM object I found so far (PHP syntax, sub-objects are bold):
$Application->Name
$Application->ApplicationPath
$Application->ProfilePath
$Application->Minimized
$Application->Playback
$Application->Playlists
$Application->MediaLibrary
$Application->Playback->IsPlaying
$Application->Playback->IsPaused
$Application->Playback->Length
$Application->Playback->CanSeek
$Application->Playback->Position
$Application->Playback->Settings
$Application->Playback->Replaygain
$Application->Playback->Play($bPaused)
$Application->Playback->Stop()
$Application->Playback->Pause()
$Application->Playback->Next()
$Application->Playback->Previous()
$Application->Playback->Random()
$Application->Playback->Seek($dSecondsFromStart)
$Application->Playback->SeekRelative($dSecondsFromCurrentPosition)
$Application->Playback->FormatTitle($strFormat)
$Application->Playback->FormatTitleEx($strFormat, $lDisplayLevel)
$Application->Playback->Settings->Volume
$Application->Playback->Settings->PlaybackFollowsCursor
$Application->Playback->Settings->CursorFollowsPlayback
$Application->Playback->Settings->StopAfterCurrent
$Application->Playback->Settings->ActivePlaybackOrder
$Application->Playback->Settings->PlaybackOrders
$Application->Playback->Settings->PlaybackOrders->Count
$Application->Playback->Settings->PlaybackOrders->GuidFromName($strName)
$Application->Playback->Settings->PlaybackOrders->NameFromGuid($strGuid)
$Application->Playback->Replaygain->Mode
$Application->Playback->Replaygain->ApplyGain
$Application->Playback->Replaygain->PreventClipping
$Application->Playback->Replaygain->PreampWithRGInfo
$Application->Playback->Replaygain->PreampWithoutRGInfo
$Application->Playlists->Count
$Application->Playlists->ActivePlaylist
$Application->Playlists->Add($strName, $bActivate)
$Application->Playlists->Remove(&$oPlaylist)
$Application->Playlists->Move(&$oPlaylist, $lPosition, $oReferencePlaylist)
$Application->Playlists->Load($strName, $strFilename, $bActivate)
$Application->Playlists->Save(&$oPlaylist, $strFilename)
$Application->Playlists->GetTracks($strQuery)
$Application->Playlists->GetSortedTracks($strSortFormat, $strQuery)
$Application->Playlists->ActivePlaylist->Name
$Application->Playlists->ActivePlaylist->Index
$Application->Playlists->ActivePlaylist->GetTracks($strQuery)
$Application->Playlists->ActivePlaylist->GetSortedTracks($strSortFormat, $strQuery)
$Application->Playlists->ActivePlaylist->DoDefaultAction($lItemIndex)
$Application->MediaLibrary->Rescan()
$Application->MediaLibrary->GetTracks($strQuery)
$Application->MediaLibrary->GetSortedTracks($strSortFormat, $strQuery)
Is it possible to know if a certain track in a playlist is the one that's currently playing? %isplaying% and %list_index% don't seem to work. They are returned as a question mark for every track.
No, that isn't possible.
P.S.: Here's a list of all fields and methods of the COM object I found so far (PHP syntax, sub-objects are bold):
...snip...
All of that information can also be found in the foobar2000.idl file that comes with foo_comserver2. If I remember correctly, you have to install the development files. Of course it is not in Python syntax.
Fantastic plugin -- looks like just what I need.
I'm using VBA (Visual Basic for Applications), and having trouble understanding how to get playlist save to work.
I see that the command format is:
foo.playlists.save(oPlaylist as Playlist07, strFilename as string)
What structure do I need to use for oPlaylist?
Thanks!
You can retrieve a playlist object from the playlists collection.
You can retrieve a playlist object from the playlists collection.
Are there any examples of how to do this? I'm trying to save the activeplaylist as an M3U file, and just can't figure it out...
Thanks,
John
Just a small question:
Are the methods playlists.load and playlists.save implemented?
I'am getting "NOT IMPLEMENTED" return code on these functions.
Thanks
Tommy
You can retrieve a playlist object from the playlists collection.
Are there any examples of how to do this? I'm trying to save the activeplaylist as an M3U file, and just can't figure it out...
Thanks,
John
I have recently found Foobar2000 and love the sound that it produces. My CDs are mainly classical and I have an Access database from which I select what to play. I want to automate this process so have installed this COM Automation Server using VBA. It works fine and I can create & juggle with playlists and also select specific tracks from the media library.
Sadly I cannot work out how to drop those selected tracks into a playlist, nor find any other way to actually play them.
Since I retired I seem to be losing the little grey cells faster than my hair, so I would really appreciate some guidance so that I can actually hear my music.
Thanks
i'm trying to develop some sort of foo_facets but for a web browser
so i need to get all the tracks in the library at first (to cache them in a web application)
the following code (C#)
Tracks07 foundTracks = foobarApplication.MediaLibrary.GetTracks("a");
for (int i = 0; i < foundTracks.Count; i++)
{
foundTracks.FormatTitle("%genre%");
}
almost always ends with System.OutOfMemoryException
if i replace %genre% with %album% or %artist% it actually never fails (but works a bit slow - ~25 sec)
foundTracks.Count ~ 19000
any thoughts?
Does anyone have a working example for php? I've been playing around a little but havn't had alot of success. Not surprising really as this is the first time i have connected a COM object. I've tried a few things that have not given the results i expected, one is;
<?php
echo 'Script Started';
echo ('<br><br>');
$foo = new COM('Foobar2000.Application.0.7') or die('cannot connect to fb2k');
echo $foo->Name;
echo '<br>';
echo $foo->ApplicationPath;
echo '<br>';
$lib = $foo->MediaLibrary;
$trks = $lib->GetTracks();
$numtrks = $trks->Count;
echo ($numtrks);
echo (' tracks in library');
echo '<br>';
echo ('<br>');
echo 'Script Finished';
?>
which outputs
Script Started
foobar2000 v0.9.5.3
C:\Program Files\foobar2000\foobar2000.exe
0 tracks in library
Script Finished
When i use the included vbs example i get a value of 7545 tracks in the library.
Am i doing something wrong here? any help or advice would be appreciated.
I realize this plugin is not your top-priority but is there any chance you could implement something like playback->GetFFT(channel) or at least playback->GetAudioLevel(channel)? It would be pure awesomeness to be able to make standalone visualizations.
Anyways, thanks for this great plugin and as others also mentioned, tag editing wouldn't hurt
Does anyone have a working example for php? I've been playing around a little but havn't had alot of success. Not surprising really as this is the first time i have connected a COM object. I've tried a few things that have not given the results i expected, one is;<snip>
To answer my own question...
The problem here was one related to user accounts, the comserver plugin apparently looks for an instance of foobar2000 running as the same user as the one connecting to it, if it doesn't find it it spawns a new instance. So i was running fb2k as the local user and apache was connecting to the com server as SYSTEM, to complicate matters i had fb2k configured to look for config files in the local user profile so the instance spawned as SYSTEM had no library loaded and a default empty playlist.
I changed my apache config to run as the local user and fb2k to look in the application folder for config and now i get the results i expect.
I have only 1 small problem now and that is apache wont connect if fb2k is already running, the comserver seems to like to start its own instance, not in itself a problem but the instance it starts is invisible on the desktop so the only way i can shut it down is via the task manager (end process). If anyone knows how i can sort this out, some input would be great.
Thanks to Hancoque for guiding me with this problem, you saved what little hair i have left :]
I have only 1 small problem now and that is apache wont connect if fb2k is already running, the comserver seems to like to start its own instance, not in itself a problem but the instance it starts is invisible on the desktop so the only way i can shut it down is via the task manager (end process). If anyone knows how i can sort this out, some input would be great.
i have just stumbled onto the solution to this issue, http://au2.php.net/manual/en/book.exec.php (http://au2.php.net/manual/en/book.exec.php) . i will copy and paste the text that solved it for me for anyone who doesnt want to follow the link.
If you try to launch GUI apps from a service in Vista, you'll have lots of trouble. As a security feature, Vista mediates the interaction of services with the desktop using 'Interactive Services Detection'.
That means, if you are running PHP as a module of an Apache service, you won't be able to launch GUI apps using any method. This kind of thing just won't work:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("notepad.exe", 7, false);
So, if you want to use Apache/PHP as a proxy for launching GUI apps, you'll need to run Apache as a console application.
First, if Apache is already installed as a service, you'll need to set it's startup type to "manual" using the services snap-in. (%SystemRoot%\system32\services.msc) Search for Services in the start menu search box.
Then add a shortcut to C:\apache\bin\httpd.exe (or wherever Apache is installed) to your Startup folder, and set that shortcut to start minimized. You can use an app like TrayIt! to force Apache down into the system tray.
Then use any of the methods outlined on the PHP website and you will be able to open a Windows application from PHP and see it's GUI.
the text mentions Vista but it solved this problem for me with XP sp3
strange... i'm on RTM and ive tried to register it. But when i look at Preferences > Tools > Com Automation server it says the server is " Not Running: Operation unavailable" and all three paths are " Not available".
I had the same problem. I noticed on installation that it closed my active Foobar2000. So I wondered if something in the installation went wrong because I had Foobar2000 open. So I tried installation again with the Preferences > Tools > Com Automation server dialog open, and it gave me some kind of error about a .dll file not available. Finally, I ran the installation a third time with Foobar2000 not open and now it looks like the server is running.
The installer should definately tell the user to close Foobar2000 before proceeding, since you may cause errors if they have the config open; and especially if you will forcibly close Foobar2000 and the user is in the middle of ripping a CD or something.
Yes, all right. I need it just for a QIP plug-in. But when I install the COM Server, my foobar2000 crashes... Do you happen to know what I am doing wrong...? Thanks a lot!
Moderation: Removed useless full quote of the first post.
Just made this for the mIRC users out there. It basically is a alias that fetches the song playing and echoes it out.
/np {
.comopen fb2k Foobar2000.Application.0.7
if ($comerr) { echo comopen failed | halt }
if ($com(fb2k, Playback, 3, dispatch* pb)) {
$com(pb, FormatTitle, 3, bstr, foobar2000 now playing: % $+ artist% - % $+ title% ['[' % $+ album% ']'])
echo $com(pb).result
}
.comclose pb
.comclose fb2k
}
You can edit the format string as long as you make sure to escape percent signs (%) as these have a special meaning in mIRC scripts (variables).
just concatenate using the $+ operator as shown above.
@splint3r:
Services can interact with the desktop via the means of window station API. I used this once when I had to interact with Winamp from a service once.
bool GetCurWinampSong(string &s)
{
#define WM_WA_IPC WM_USER
#define IPC_GETLISTPOS 125
#define IPC_GETPLAYLISTTITLE 212
s="<not playing>";
/* -- Open user's window station "WinSta0". -- */
HWINSTA hWinStaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
/* -- Set process window station to "WinSta0", this enables the process to
access objects in the window station such as desktops. -- */
if (SetProcessWindowStation(hWinStaUser)) {
/* -- Open user's desktop "Default". -- */
HDESK hDeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
/* -- Set thread desktop to "Default". -- */
if (SetThreadDesktop(hDeskUser)) {
// Now as we are locked on to user's desktop, we can access users's windows.
HWND hwnd_winamp;
hwnd_winamp = FindWindow("Winamp v1.x", 0);
if (IsWindow(hwnd_winamp))
{
s="<other error>";
DWORD dwPid;
GetWindowThreadProcessId(hwnd_winamp, &dwPid);
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwPid);
if (!hProcess)
{
s = "<Can not open winamp process>";
return false;
}
int plpos = SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_GETLISTPOS);
char *szTitle, *pTitle;
pTitle = (char*)SendMessage(hwnd_winamp, WM_WA_IPC, plpos, IPC_GETPLAYLISTTITLE);
SIZE_T read, datalen;
datalen = 1024;
szTitle = (char*)GlobalAlloc(GPTR, datalen+1);
if (ReadProcessMemory(hProcess, pTitle, szTitle, datalen, &read))
{
s = szTitle;
}
else
{
s = "<Could not get winamp title!>";
}
GlobalFree((HGLOBAL)szTitle);
CloseHandle(hProcess);
}
}
if (hDeskUser) {
CloseDesktop(hDeskUser);
}
}
if (hWinStaUser) {
CloseWindowStation(hWinStaUser);
}
return true;
}
This mIRC alias searches the Media Library.
usage: /fbsearch QUERY
example: /fbsearch artist HAS beatles
/fbsearch {
.comopen fb2k Foobar2000.Application.0.7
if ($comerr) { echo comopen failed | halt }
if ($com(fb2k, MediaLibrary, 3, dispatch* ml)) {
if ($com(ml, GetTracks, 3, bstr, $1-, dispatch* tracks)) {
if ( $com(tracks, Count, 2) ) {
echo Count: $com(tracks).result results
var %n = $com(tracks).result
var %m = 0
while (%m < %n) {
; works if you only want paths> echo Track %m $+ : $comval(tracks, %m, Path)
$com(tracks, Item, 3, integer, %m, dispatch* track)
$com(track, FormatTitle, 3, bstr, % $+ artist% - % $+ title%)
echo $+($chr(20), $com(track).result)
.comclose track
inc %m
}
}
}
}
.comclose tracks
.comclose ml
.comclose fb2k
}
Any chance this could be updated for 1.0.x versions?
Any chance this could be updated for 1.0.x versions?
Works for me in 1.0. I used it with an album cover art plugin(that requires it) and was able to download the covers for all my albums.
Any chance this could be updated for 1.0.x versions?
Works for me in 1.0. I used it with an album cover art plugin(that requires it) and was able to download the covers for all my albums.
Are you using Album Art Download XUI?
If so, could you let me know how to run that within Foobar2000?
If not, which cover art plugin are you using?
Thanks!
Album-art:
http://sourceforge.net/projects/album-art/ (http://sourceforge.net/projects/album-art/)
Make sure you follow the Com Automation server install instructions.
Have foobar2000 open. Then open the Album-art program. Go to the FILE menu, New menu, select foobar browser. Then choose either the entire library or a particular Tab that is open. Then select the check boxes for albums that don't have album art and at the bottom click the button "Get Artwork for selection. It's fairly explanatory after that.
Album-art:
http://sourceforge.net/projects/album-art/ (http://sourceforge.net/projects/album-art/)
Make sure you follow the Com Automation server install instructions.
Have foobar2000 open. Then open the Album-art program. Go to the FILE menu, New menu, select foobar browser. Then choose either the entire library or a particular Tab that is open. Then select the check boxes for albums that don't have album art and at the bottom click the button "Get Artwork for selection. It's fairly explanatory after that.
Thank you for the quick reply! I have been using the program with foobar 0.9.6.9, but will now try it with foobar 1.0 instead.
While I wrapped foobar COM object in some code I want to print some data to console
Is it possible?
I found nothing related in .idl file
If not with this COM server maybe somehow to pass strings to foobar console through piping to running foobar process?
Hello!
I have tried to write a simple application to control the Foobar by it, but I have not found any methods to add/remove files to playlist.
Are such methods available in interface? Where could I found them?
If such methods are not available in the interfave - is it planned to add such methods?
Aleksandr.
Is it possible to get the index of track in the playlist which is being currently played?
python example:
fb2k = win32com.client.Dispatch("Foobar2000.Application.0.7")
trk = fb2k.Playback.FormatTitle("%path%")
apl = fb2k.Playlists.ActivePlaylist
cnt = 0
for x in apl.GetTracks():
cnt += 1
if x.FormatTitle("%path%") == trk: print cnt
[edit] it's just example as active playlist doesn't necessarily mean that it's playing playlist and assuming there are no duplicates in playlist, but solution through numbering GetTracks() and using it as %list_index% workaround
python example:
[edit] it's just example as active playlist doesn't necessarily mean that it's playing playlist and assuming there are no duplicates in playlist, but solution through numbering GetTracks() and using it as %list_index% workaround
This variant is not universal, but it seems to be a suitable workaround.
2 All: As I see - the project is frozen now. Is there source codes available? I think - users which are interested in it - they could write the necessary functionality themselves and then place the corrected code here.
I have found that the path equality is not enough condition. If the .cue sheet is being played - all the tracks have the same path.
The titile, artist, track length and album should also be compared.
This method is implemented in my application. On note - the playlist shall no contain any doubles, as was said above.
Can't get it to work with latest 1.1b1
com object gets assigned: <COMObject Foobar2000.Application.0.7> but any interface like Playback, Playlist etc. raises error
above problem can be avoided by leaving foo_comserver2.dll in foobar's components folder, as installer hardcodes the path to the dll in 2 reg keys (logically)
@foosion: would it be not much of trouble to extend this wrapper also to DSP manager and converter
Providing what DSP manager and Converter functionality specifically?
querying presets, modifying states (DSP), assigning actions...
I'm not sure if I put right words there, but here is real example:
I wanted to script automatic audiotag.info retreival information about current track i.e. so I need to use converter to make 15 sec sample from the track then sent it there. As only option is to use foobar command line assuming right converter preset exists seemed not very comfortable, and thinking about it I thought it would be nice idea which would open other fine possibilities.
OK. Changing DSP settings is possible.
But e.g. the Converter doesn't provide any programatic ways to manage the presets nor control its other behavior, except running a preset command on some tracks, naturally.
thanks for clearance, didn't know that converter is so closed (not that it's options are ever changing AFAIK, but there must be some reason)
(not that it's options are ever changing AFAIK, but there must be some reason)
I can image a few reasons actually. Providing programmatic access to a component takes effort. You have to design, document and implement an interface, and unless you are willing to annoy other developers you will be stuck with it for quite some time once you have released it. Changing it would force everyone who uses it to change their own code.
Also, this project is now officially on hiatus. Indefinitely. It has always been (one of) the most time consuming component projects I have ever started. The reasons are twofold. Firstly, COM programming in C++ is neither fun nor easy. Secondly, testing the compatibility with various client languages (among others: Visual Basic 6, C#, Python, Lua, PowerShell) has taken me a lot of time.
Nevertheless I am not going to just post the source on the web and hope that someone will come and pick it up. If someone is interested in maintaining this component, they should contact me. Below is a short list of things they should have experience with (or at least they should not be scared of them ):
- Implementing COM objects in C++ with ATL.
- Versioning of COM interfaces.
- Implementing foobar2000 components.
- Implementing a COM server in a DLL that is started by running an EXE you do not control.
- Installing COM libraries.
Furthermore I am only looking for people who are committed to maintaining the component for the foreseeable future, lets says for six months at the very least. I am not fond of code-and-run tactics where someone adds their favorite feature and three bugs to a component and then vanishes to never be seen again.
I hope the above does not sound too demanding.
I am loving this. Thanks!!!
So it's status-quo for foobar COM component... pity
It seems to me that Playlist interface doesn't have method for selected tracks, or is there a way to get selected tracks somehow
Playback.Start(bPaused) starts the current track always in paused mode, regardless of the value of the bPaused flag.
Issuing Pause() right after Start() works, but it's strange!
Is it a known bug?
Or maybe I don't understand how to use the flag?
Hello There,
If have followed this forum quite a while now before deciding to add a comment. Over the years people have asked several times for an active queuelist track enqueue and dequeue options in com_server2.dll. Sofar I did not see any solution that would address this wanted feature. Any chance this will be added to the com_server2 COm object? If not, is there a work around for adding removing tracks to/from the active foobar tracklist remotely? (not by commandline)?
Thanks....
Hello,
is there meanwhile a way to get the current playing song info with help of PHP?
Any Example?
Maybe this LinqPad example will be of interest to some: https://gist.github.com/10009197 (https://gist.github.com/10009197)
So with less then 40 lines of code, current playing track is identified by web service, then sent for similarity lookup and finally result matched to user library and presented in accessible interface:
(http://i.imgur.com/drpeJw8m.png) (http://i.imgur.com/drpeJw8.png)
Results in result pane can be comprehended as kind of live playlist - clicking on a track link start track playback.
For this example to work user would need to reference foobar Interop assembly (generated from comserver2 dll) and echonest api key.
Echonest is just a familiar example, which is hopefully enough to show interesting possibilities for other services or even interconnecting multiple services in friendly interface...
when using the Foobar Query Syntax in the searchbar the command "artist IS Motorhead" returns everything "Motorhead" aswell as "Motörhead"
unfortunately using COM Automation Server for the same thing just returns the exactly same string.
does anyone know a way around this?
Maybe this LinqPad example will be of interest to some: https://gist.github.com/10009197 (https://gist.github.com/10009197)
So with less then 40 lines of code, current playing track is identified by web service, then sent for similarity lookup and finally result matched to user library and presented in accessible interface:
(http://i.imgur.com/drpeJw8m.png) (http://i.imgur.com/drpeJw8.png)
Results in result pane can be comprehended as kind of live playlist - clicking on a track link start track playback.
For this example to work user would need to reference foobar Interop assembly (generated from comserver2 dll) and echonest api key.
Echonest is just a familiar example, which is hopefully enough to show interesting possibilities for other services or even interconnecting multiple services in friendly interface...
Can you provide instructions to set this up please??
Any way we can either get the source or get it updated. FB 1.3.6 is crashing like mad. Half the time it works part of the time. Change some little thing and it causes FB to crash. I realize you don't want to release the source code for good reasons, but a better reason is that, at least if it is out there, someone can work on it. If you store it away then it will never get anywhere unless someone decides to take up the challenge. At the very least, you could put it up on Github and maintain it there. This will solve both problems. (you can maintain the official version and only accept pushes to it that you want)
In any case, here is the foobar stack trace dump of the most recent crash.
Address: 764C4B32h (KERNELBASE+14B32h), symbol: "RaiseException" (+49h)
Address: 00C7CEDDh (foobar2000+2CEDDh)
Address: 00CBAA41h (foobar2000+6AA41h)
Address: 00C75D9Dh (foobar2000+25D9Dh)
Address: 10006F1Ch (foo_comserver2+6F1Ch), symbol: "foobar2000_get_interface" (+5DACh)
Address: 1000A7E5h (foo_comserver2+A7E5h), symbol: "foobar2000_get_interface" (+9675h)
Address: 740A2775h (shared+2775h), symbol: "uBugCheck" (+20h)
Address: 740B9168h (shared+19168h), symbol: "CreateFileAbortable" (+E6E9h)
Address: 740BF810h (shared+1F810h), symbol: "CreateFileAbortable" (+14D91h)
Address: 00CD2631h (foobar2000+82631h)
Address: 76C54802h (RPCRT4+14802h), symbol: "RpcImpersonateClient" (+124h)
Address: 00D81976h (foobar2000+131976h)
Address: 1001752Ch (foo_comserver2+1752Ch), symbol: "foobar2000_get_interface" (+163BCh)
Address: 71FDF6ECh (foo_input_std+F6ECh)
Address: 1001F008h (foo_comserver2+1F008h), symbol: "foobar2000_get_interface" (+1DE98h)
Address: 00DCE4D0h (foobar2000+17E4D0h)
Address: 1002EDD8h (foo_comserver2+2EDD8h), symbol: "foobar2000_get_interface" (+2DC68h)
Address: 1000D34Fh (foo_comserver2+D34Fh), symbol: "foobar2000_get_interface" (+C1DFh)
Address: 71FDF61Ch (foo_input_std+F61Ch)
Address: 1002E160h (foo_comserver2+2E160h), symbol: "foobar2000_get_interface" (+2CFF0h)
Address: 1000D4B1h (foo_comserver2+D4B1h), symbol: "foobar2000_get_interface" (+C341h)
Address: 1000D55Ah (foo_comserver2+D55Ah), symbol: "foobar2000_get_interface" (+C3EAh)
Address: 76C5E980h (RPCRT4+1E980h), symbol: "NdrServerInitialize" (+413h)
Address: 76CDADE1h (RPCRT4+9ADE1h), symbol: "NdrStubCall2" (+2A4h)
Address: 1000D550h (foo_comserver2+D550h), symbol: "foobar2000_get_interface" (+C3E0h)
Address: 76840629h (combase+10629h), symbol: "DcomChannelSetHResult" (+6CCh)
Address: 768405E2h (combase+105E2h), symbol: "DcomChannelSetHResult" (+685h)
Address: 10032024h (foo_comserver2+32024h), symbol: "foobar2000_get_interface" (+30EB4h)
....
BTW, there doesn't seem to be any way to get information about the currently playing or selected track or to select specific tracks to play(we can do next, previous, etc... but not select, say, the first track of the playlist)?
I think the reason why it is crashing is that when changing the active playlist you have to select a song. If you start foobar up and change the active playlist (application.Playlists.ActivePlaylist = p), then try to play foobar using application.Playback.Start, it will crash.
As long as I change the active playlist at least once in foobar or my app(it is synchronized), then foobar doesn't crash. (If I uncomment the playback.start, it also doesn't crash)
My guess is that the bug is either with foobar trying to play a song that doesn't exist or comserver trying to force foobar to play such a song. (If we had a way to set the first song of the playlist, this would probably solve it) I can't even seem to find a way to get the current playing song's title, which I could use to compare to the tracks and find it's location.
So, even just selecting the track I want to play prevents the crash. I guess trying to play foobar through the com automation (application.Playback.Start) will cause foobar to crash if a track isn't selected.... yet there seems to be no way to select a track!!
Does anyone have any information about this tool? I've installed it and there is literally no information about it. FB2K says it's not running and I have no idea how to start it up. I just want to use the Album Art Downloader and I'm beyond frustrated. ANY documentation would be great and I don't mean the "copy the dll to your foobar components folder" "documentation".
Thanks,
rocket
Can you provide instructions to set this up please??
I would guess it's self-explainable, but maybe you have problem with generating assembly?
One way to generate assembly is to use TlbImp utility (https://msdn.microsoft.com/en-us/library/697w37zd(v=vs.110).aspx) that comes with Windows sdk:
tlbimp foo_comserver2.dll /out:C:\Temp\Interop.Foobar2000.dll /namespace:Foobar2000
I was using assembly implicitly generated by Visual Studio.
Now if you paste to code linked in upper post in LinqPad, you press F4 and browse for this assembly. Then in the "Additional namespace import" tab, select "Pick from assembly" link and add the "Foobar2000" namespace.
You'll also need echonest api key, which you paste in Password manager (Linqpad > File > Password Manager) and name it as "api.echonest" so that you won't have to edit pasted code.
Then just play some song in foobar and hit play in Linqpad (or F5), and it will generate interactive playlist with similar songs (from your library) just in seconds.
Hope this helps, otherwise fell free to ask if you have further problems.
Can you provide instructions to set this up please??
I would guess it's self-explainable, but maybe you have problem with generating assembly?
One way to generate assembly is to use TlbImp utility (https://msdn.microsoft.com/en-us/library/697w37zd(v=vs.110).aspx) that comes with Windows sdk:
tlbimp foo_comserver2.dll /out:C:\Temp\Interop.Foobar2000.dll /namespace:Foobar2000
I was using assembly implicitly generated by Visual Studio.
Now if you paste to code linked in upper post in LinqPad, you press F4 and browse for this assembly. Then in the "Additional namespace import" tab, select "Pick from assembly" link and add the "Foobar2000" namespace.
You'll also need echonest api key, which you paste in Password manager (Linqpad > File > Password Manager) and name it as "api.echonest" so that you won't have to edit pasted code.
Then just play some song in foobar and hit play in Linqpad (or F5), and it will generate interactive playlist with similar songs (from your library) just in seconds.
Hope this helps, otherwise fell free to ask if you have further problems.
It probably is self-explanatory if you have some experience with the tool but I don't. I know this thing works. There are people all over the site using it with AAD and somewhere there HAS to be a document that says "go here, click that, type the other and hit OK. If someone could screenshot their config at least I could take a look and see what is actually being done.
In this post you mention a "problem with generating assembly". I don't even know what "assembly" means in this context, I'm guessing it's some kind of code construct but that's a WAG. Could be that this setup requires a skill level that I don't have, or I may just be a dumb-ass. If that's the case, then please, please, have mercy on the dumb-ass.
Thanks,
rocket
I imagine you made to the point of installing this component which indeed is not trivial. But if someone wishes to program foobar the easy way, they have to make that step which comserver installer anyways does smoothly.
If your only problem is AAD then I suggest you open new thread with title describing the problem so that also others could learn and more people will reply. I can't help you as I don't use AAD, but I guess you want to automate cover download for your whole library...
As far as this component is concerned, I as many before feel frustrated with limited options provided by comserver, and one most obvious frustration is that you can't get selected track nor do anything useful with playlist, but just use media library search and the likes...
But I'm not to judge com developer that brings the cookies, as I have very little knowledge about it and everything I've seen about com programming seems unnecessarily complicated, leading me to the thought that it must be done by program developer or not at all, but hardly will anyone take this component to next level
I'd just like to say, that this component is really really useful for what I do. In a few weeks I will make my work pubilc, which is a script to do unidirectional sync (copy/convert by rules) of selected library items and playlists to different targets (usb-devices, folders) in a very flexible way.
Thats why I'd like to encourage to keep this component alive!
I used the COM Automation Server successfully to create a script, that can synchronize chosen playlists and medialibrary items to USB-players and folder locations.
Because it's a VBscript, someone may find it interesting to look at the code.
Code and Wiki is here (http://foobarsync.lima-city.de/wikka/HomePage),
discussion thread for users is here (http://www.hydrogenaud.io/forums/index.php?showtopic=108834).
Hi there,
I am not able to uninstall Com Automation Server from foobar (it's grayed-out) and it's not in my list of installed software (Windows 10). Can anybody help?
Thanks
Hi there,
I am not able to uninstall Com Automation Server from foobar (it's grayed-out) and it's not in my list of installed software (Windows 10). Can anybody help?
Thanks
Nevermind, just found its uninstaller under: "C:\Program Files (x86)\foobar2000". See you.