You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
7.8 KiB
401 lines
7.8 KiB
#include "mp_amipinterface.h"
|
|
#include "kvi_options.h"
|
|
|
|
#ifdef COMPILE_ON_WINDOWS
|
|
|
|
#include <tqtextcodec.h>
|
|
|
|
#include "kvi_locale.h"
|
|
#include "kvi_module.h"
|
|
|
|
#include <windows.h>
|
|
|
|
enum ac_StartMode
|
|
{
|
|
AC_START_ALL = 0,
|
|
AC_START_CLIENT,
|
|
AC_START_SERVER,
|
|
AC_START_NONE
|
|
};
|
|
|
|
enum ac_ErrorCode
|
|
{
|
|
AC_ERR_NOERROR = 0,
|
|
AC_ERR_CLIENTISNULL,
|
|
AC_ERR_EXCEPTION,
|
|
AC_ERR_CONNECTIONFAILED,
|
|
AC_ERR_SERVERNOTRUNNING
|
|
};
|
|
|
|
#define AC_BUFFER_SIZE 2048
|
|
|
|
static HINSTANCE amip_dll = NULL;
|
|
|
|
#define MP_AC_DYNPTR(__rettype,__func,__args) \
|
|
typedef __rettype (CALLBACK* lp_##__func)(__args); \
|
|
lp_##__func __func
|
|
|
|
#define MP_AC_FUNC(__func) \
|
|
__func = (lp_##__func)GetProcAddress(amip_dll,#__func); \
|
|
if(!__func) { \
|
|
FreeLibrary(amip_dll); \
|
|
return false; \
|
|
}
|
|
|
|
#define COMMA() ,
|
|
|
|
MP_AC_DYNPTR(void, ac_init, int mode);
|
|
MP_AC_DYNPTR(void, ac_uninit, void);
|
|
MP_AC_DYNPTR(void, ac_getDestHost, char *out);
|
|
MP_AC_DYNPTR(int, ac_getDestPort, void);
|
|
MP_AC_DYNPTR(bool, ac_pingServer, const char *host COMMA() int port COMMA() int timeout);
|
|
MP_AC_DYNPTR(int, ac_exec, const char *cmd);
|
|
MP_AC_DYNPTR(int, ac_eval, const char *cmd COMMA() char *result);
|
|
|
|
|
|
static bool loadAmipDll()
|
|
{
|
|
amip_dll = LoadLibrary("ac.dll");
|
|
if (!amip_dll) return false;
|
|
|
|
MP_AC_FUNC(ac_init);
|
|
MP_AC_FUNC(ac_uninit);
|
|
MP_AC_FUNC(ac_getDestHost);
|
|
MP_AC_FUNC(ac_getDestPort);
|
|
MP_AC_FUNC(ac_pingServer);
|
|
MP_AC_FUNC(ac_eval);
|
|
MP_AC_FUNC(ac_exec);
|
|
|
|
return true;
|
|
};
|
|
|
|
static TQTextCodec * mediaplayer_get_codec()
|
|
{
|
|
TQTextCodec * c= TQTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding));
|
|
if(!c)c = TQTextCodec::codecForLocale();
|
|
return c;
|
|
}
|
|
|
|
MP_IMPLEMENT_DESCRIPTOR(
|
|
KviAmipInterface,
|
|
"amip",
|
|
__tr2qs_ctx(
|
|
"An interface to the AMIP plug-in.\n" \
|
|
"You can download it from http://amip.tools-for.net.\n" \
|
|
"To use this interface you must " \
|
|
"install AMIP plug-in for your player."
|
|
,
|
|
"mediaplayer"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
KviAmipInterface::KviAmipInterface()
|
|
: KviMediaPlayerInterface()
|
|
{
|
|
if(!amip_dll) {
|
|
bool res = loadAmipDll();
|
|
if(!res) {
|
|
amip_dll = NULL;
|
|
return;
|
|
}
|
|
ac_init(AC_START_CLIENT);
|
|
}
|
|
}
|
|
|
|
KviAmipInterface::~KviAmipInterface()
|
|
{
|
|
if(!amip_dll) return;
|
|
ac_uninit();
|
|
FreeLibrary(amip_dll);
|
|
amip_dll = NULL;
|
|
}
|
|
|
|
|
|
int KviAmipInterface::detect(bool bStart)
|
|
{
|
|
if(!amip_dll) return 0;
|
|
char host[AC_BUFFER_SIZE];
|
|
ac_getDestHost(host);
|
|
if(ac_pingServer(host, ac_getDestPort(), 5000)) return 99;
|
|
return 1;
|
|
}
|
|
|
|
#define MP_AMIP_COMMAND(__cmdname,__acmd) \
|
|
bool KviAmipInterface::__cmdname() \
|
|
{ \
|
|
return (ac_exec(__acmd) == AC_ERR_NOERROR); \
|
|
}
|
|
|
|
MP_AMIP_COMMAND(play,"control play")
|
|
MP_AMIP_COMMAND(stop,"control stop")
|
|
MP_AMIP_COMMAND(next,"control >")
|
|
MP_AMIP_COMMAND(prev,"control <")
|
|
MP_AMIP_COMMAND(pause,"control pause")
|
|
MP_AMIP_COMMAND(quit,"control exit")
|
|
|
|
// helper function for evaluating variables returning integers
|
|
int eval_int(const char *var)
|
|
{
|
|
if(!amip_dll) return -1;
|
|
char buff[AC_BUFFER_SIZE];
|
|
int res = -1;
|
|
if (AC_ERR_NOERROR == ac_eval(var, buff)) {
|
|
res = atoi(buff);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
TQString eval_str(const char *var)
|
|
{
|
|
TQString res;
|
|
if(!amip_dll) return res;
|
|
char buff[AC_BUFFER_SIZE];
|
|
if (AC_ERR_NOERROR == ac_eval(var, buff)) {
|
|
res.append(buff);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
int KviAmipInterface::length()
|
|
{
|
|
return eval_int("var_sl") * 1000;
|
|
}
|
|
|
|
int KviAmipInterface::position()
|
|
{
|
|
return eval_int("var_psec") * 1000;
|
|
}
|
|
|
|
int KviAmipInterface::bitRate()
|
|
{
|
|
return eval_int("var_br");
|
|
}
|
|
|
|
int KviAmipInterface::sampleRate()
|
|
{
|
|
return eval_int("var_sr");
|
|
}
|
|
|
|
int KviAmipInterface::channels()
|
|
{
|
|
int ret = -1;
|
|
if(eval_str("var_typ").startsWith("Stereo")) {
|
|
ret = 2;
|
|
} else if(eval_str("var_typ").startsWith("Mono")) {
|
|
ret = 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
KviMediaPlayerInterface::PlayerStatus KviAmipInterface::status()
|
|
{
|
|
int ret = eval_int("var_stat");
|
|
switch(ret)
|
|
{
|
|
case 0:
|
|
return KviMediaPlayerInterface::Stopped;
|
|
break;
|
|
case 3:
|
|
return KviMediaPlayerInterface::Paused;
|
|
break;
|
|
case 1:
|
|
return KviMediaPlayerInterface::Playing;
|
|
break;
|
|
default:
|
|
return KviMediaPlayerInterface::Unknown;
|
|
break;
|
|
}
|
|
return KviMediaPlayerInterface::Unknown;
|
|
}
|
|
|
|
TQString KviAmipInterface::mrl()
|
|
{
|
|
TQString ret;
|
|
TQString fn = eval_str("var_fn");
|
|
TQTextCodec *c=mediaplayer_get_codec();
|
|
if (c) ret = c->toUnicode(fn);
|
|
else ret=fn;
|
|
if(!ret.startsWith("http://",false))
|
|
ret.prepend("file://");
|
|
|
|
return ret;
|
|
}
|
|
|
|
TQString getAmipString(const char * var) {
|
|
TQString ret;
|
|
TQString s = eval_str(var);
|
|
TQTextCodec *c=mediaplayer_get_codec();
|
|
if (c) ret = c->toUnicode(s);
|
|
else ret=s;
|
|
return ret;
|
|
}
|
|
|
|
TQString KviAmipInterface::nowPlaying()
|
|
{
|
|
return getAmipString("var_s");
|
|
}
|
|
|
|
TQString KviAmipInterface::artist()
|
|
{
|
|
return getAmipString("var_1");
|
|
}
|
|
|
|
TQString KviAmipInterface::title()
|
|
{
|
|
return getAmipString("var_2");
|
|
}
|
|
|
|
TQString KviAmipInterface::album()
|
|
{
|
|
return getAmipString("var_4");
|
|
}
|
|
|
|
TQString KviAmipInterface::year()
|
|
{
|
|
return getAmipString("var_5");
|
|
}
|
|
|
|
TQString KviAmipInterface::comment()
|
|
{
|
|
return getAmipString("var_6");
|
|
}
|
|
|
|
TQString KviAmipInterface::genre()
|
|
{
|
|
return getAmipString("var_7");
|
|
}
|
|
|
|
bool KviAmipInterface::setVol(kvs_int_t &iVol)
|
|
{
|
|
if(!amip_dll) return false;
|
|
char volcmd[AC_BUFFER_SIZE];
|
|
sprintf(volcmd, "control vol %d", iVol);
|
|
return (ac_exec(volcmd) == AC_ERR_NOERROR);
|
|
}
|
|
|
|
int KviAmipInterface::getVol()
|
|
{
|
|
return eval_int("var_vol");
|
|
}
|
|
|
|
bool KviAmipInterface::jumpTo(kvs_int_t &iPos)
|
|
{
|
|
if(!amip_dll) return false;
|
|
char jmpcmd[AC_BUFFER_SIZE];
|
|
sprintf(jmpcmd, "jumptotime %d", iPos/1000);
|
|
return (ac_exec(jmpcmd) == AC_ERR_NOERROR);
|
|
}
|
|
bool KviAmipInterface::hide()
|
|
{
|
|
HWND hWinamp = (HWND)eval_int("var_phwnd");
|
|
if(hWinamp && hWinamp != (HWND)-1)
|
|
{
|
|
ShowWindow(hWinamp, SW_HIDE);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KviAmipInterface::show()
|
|
{
|
|
HWND hWinamp = (HWND)eval_int("var_phwnd");
|
|
if(hWinamp && hWinamp != (HWND)-1)
|
|
{
|
|
ShowWindow(hWinamp, SW_SHOW);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KviAmipInterface::minimize()
|
|
{
|
|
if(!amip_dll) return false;
|
|
return (ac_exec("control mimimize") == AC_ERR_NOERROR);
|
|
}
|
|
|
|
bool KviAmipInterface::setPlayListPos(kvs_int_t &iPos)
|
|
{
|
|
if(!amip_dll) return false;
|
|
char jmpcmd[AC_BUFFER_SIZE];
|
|
sprintf(jmpcmd, "setplpos %d", iPos + 1);
|
|
return (ac_exec(jmpcmd) == AC_ERR_NOERROR);
|
|
}
|
|
|
|
int KviAmipInterface::getPlayListPos()
|
|
{
|
|
return eval_int("var_pos");
|
|
}
|
|
|
|
int KviAmipInterface::getListLength()
|
|
{
|
|
return eval_int("var_ll");
|
|
}
|
|
|
|
bool KviAmipInterface::getRepeat()
|
|
{
|
|
return eval_str("var_repeat").startsWith("on");
|
|
}
|
|
|
|
bool KviAmipInterface::getShuffle()
|
|
{
|
|
return eval_str("var_shuffle").startsWith("on");
|
|
}
|
|
|
|
bool KviAmipInterface::setShuffle(bool &bVal)
|
|
{
|
|
if(!amip_dll) return false;
|
|
bool res;
|
|
if (bVal)
|
|
{
|
|
res = (ac_exec("setshuffle on") == AC_ERR_NOERROR);
|
|
}
|
|
else
|
|
{
|
|
res = (ac_exec("setshuffle off") == AC_ERR_NOERROR);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool KviAmipInterface::setRepeat(bool &bVal)
|
|
{
|
|
if(!amip_dll) return false;
|
|
bool res;
|
|
if (bVal)
|
|
{
|
|
res = (ac_exec("setrepeat on") == AC_ERR_NOERROR);
|
|
}
|
|
else
|
|
{
|
|
res = (ac_exec("setrepeat off") == AC_ERR_NOERROR);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool KviAmipInterface::amipExec(const TQString &cmd)
|
|
{
|
|
if(!amip_dll) return false;
|
|
TQTextCodec *c=mediaplayer_get_codec();
|
|
KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
|
|
return (ac_exec(szCmd) == AC_ERR_NOERROR);
|
|
}
|
|
|
|
TQString KviAmipInterface::amipEval(const TQString &cmd)
|
|
{
|
|
TQString ret;
|
|
if(!amip_dll) return ret;
|
|
TQTextCodec *c=mediaplayer_get_codec();
|
|
KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
|
|
char buff[AC_BUFFER_SIZE];
|
|
if((ac_eval(szCmd, buff) == AC_ERR_NOERROR)) {
|
|
TQString s = buff;
|
|
TQTextCodec *c=mediaplayer_get_codec();
|
|
if (c) ret = c->toUnicode(s);
|
|
else ret=s;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //COMPILE_ON_WINDOWS
|