diff options
Diffstat (limited to 'src/modules/mediaplayer')
-rw-r--r-- | src/modules/mediaplayer/Makefile.am | 36 | ||||
-rw-r--r-- | src/modules/mediaplayer/libkvimediaplayer.cpp | 1751 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_amarokinterface.cpp | 189 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_amarokinterface.h | 76 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_amipinterface.cpp | 400 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_amipinterface.h | 58 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_dcopinterface.cpp | 224 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_dcopinterface.h | 57 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_interface.cpp | 277 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_interface.h | 238 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_jukinterface.cpp | 185 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_jukinterface.h | 77 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_mp3.cpp | 468 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_mp3.h | 137 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_winampinterface.cpp | 566 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_winampinterface.h | 76 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_xmmsinterface.cpp | 355 | ||||
-rw-r--r-- | src/modules/mediaplayer/mp_xmmsinterface.h | 84 |
18 files changed, 5254 insertions, 0 deletions
diff --git a/src/modules/mediaplayer/Makefile.am b/src/modules/mediaplayer/Makefile.am new file mode 100644 index 00000000..af5caa60 --- /dev/null +++ b/src/modules/mediaplayer/Makefile.am @@ -0,0 +1,36 @@ +############################################################################### +# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it> +############################################################################### + +AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \ +$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\" + +pluglib_LTLIBRARIES = libkvimediaplayer.la + +#%.moc: %.h +# $(SS_QT_MOC) $< -o $@ + +libkvimediaplayer_la_LDFLAGS = -avoid-version -module + +libkvimediaplayer_la_SOURCES = libkvimediaplayer.cpp \ + mp_amarokinterface.cpp \ + mp_amipinterface.cpp \ + mp_dcopinterface.cpp \ + mp_interface.cpp \ + mp_jukinterface.cpp \ + mp_mp3.cpp \ + mp_winampinterface.cpp \ + mp_xmmsinterface.cpp + +libkvimediaplayer_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la + +noinst_HEADERS = mp_amarokinterface.h \ + mp_amipinterface.h \ + mp_dcopinterface.h \ + mp_interface.h \ + mp_jukinterface.h \ + mp_mp3.h \ + mp_winampinterface.h \ + mp_xmmsinterface.h + + diff --git a/src/modules/mediaplayer/libkvimediaplayer.cpp b/src/modules/mediaplayer/libkvimediaplayer.cpp new file mode 100644 index 00000000..bd8a144f --- /dev/null +++ b/src/modules/mediaplayer/libkvimediaplayer.cpp @@ -0,0 +1,1751 @@ +//============================================================================= +// +// File : libkvimediaplayer.cpp +// Creation date : Sat Nov 3 19:28:25 2001 GMT by Szymon Stefanek +// Renamed to file : libkvimediaplayer.cpp on Fri Mar 25 2005 +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_interface.h" +#include "mp_xmmsinterface.h" +#include "mp_amarokinterface.h" +#include "mp_winampinterface.h" +#include "mp_amipinterface.h" +#include "mp_jukinterface.h" + +#include "kvi_module.h" +#include "kvi_options.h" + + +#include "kvi_locale.h" +#include "kvi_out.h" + +static KviPointerList<KviMediaPlayerInterfaceDescriptor> * g_pDescriptorList = 0; + +static KviMediaPlayerInterface * g_pMPInterface = 0; + +static KviMediaPlayerInterface * auto_detect_player(KviWindow * pOut = 0) +{ + int iBest = 0; + KviMediaPlayerInterface * pBest = 0; + KviMediaPlayerInterfaceDescriptor * d; + KviMediaPlayerInterfaceDescriptor * pDBest = 0; + for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + KviMediaPlayerInterface * i = d->instance(); + if(i) + { + int iScore = i->detect(false); + if(iScore > iBest) + { + iBest = iScore; + pBest = i; + pDBest = d; + } + if(pOut) + { + QString szOut; + QString szNam = d->name(); + KviQString::sprintf(szOut,__tr2qs_ctx("Trying media player interface \"%Q\": score %d","mediaplayer"),&(szNam),iScore); + pOut->output(KVI_OUT_MULTIMEDIA,szOut); + } + } + } + if(iBest < 90) + { + if(pOut) + pOut->outputNoFmt(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Not sure about the results, trying a second, more agressive detection pass","mediaplayer")); + // no sure player found... try again with a destructive test + for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + KviMediaPlayerInterface * i = d->instance(); + if(i) + { + int iScore = i->detect(true); + if(iScore > iBest) + { + iBest = iScore; + pBest = i; + pDBest = d; + } + if(pOut) + { + QString szOut; + QString szNam = d->name(); + KviQString::sprintf(szOut,__tr2qs_ctx("Trying media player interface \"%Q\": score %d","mediaplayer"),&(szNam),iScore); + pOut->output(KVI_OUT_MULTIMEDIA,szOut); + } + } + } + } + if(pDBest) + { + KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) = pDBest->name(); + if(pOut) + pOut->output(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Choosing media player interface \"%Q\"","mediaplayer"),&(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer))); + } else { + if(pOut) + pOut->outputNoFmt(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Seems that there is no usable media player on this machine","mediaplayer")); + } + return pBest; +} + + + + #define MP_KVS_FAIL_ON_NO_INTERFACE \ + if(!g_pMPInterface) \ + { \ + c->warning(__tr2qs_ctx("No mediaplayer interface selected. Try /mediaplayer.detect","mediaplayer")); \ + return true; \ + } \ + + #define MP_KVS_COMMAND(__name) static bool mediaplayer_kvs_cmd_ ## __name (KviKvsModuleCommandCall * c) + #define MP_KVS_FUNCTION(__name) static bool mediaplayer_kvs_fnc_ ## __name (KviKvsModuleFunctionCall * c) + + #define MP_KVS_SIMPLE_COMMAND(__name,__ifacecommand) \ + MP_KVS_COMMAND(__name) \ + { \ + KVSM_PARAMETERS_BEGIN(c) \ + KVSM_PARAMETERS_END(c) \ + \ + MP_KVS_FAIL_ON_NO_INTERFACE \ + \ + if(!g_pMPInterface->__ifacecommand()) \ + { \ + if(!c->hasSwitch('q',"quiet")) \ + { \ + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); \ + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); \ + tmp += g_pMPInterface->lastError(); \ + c->warning(tmp); \ + } \ + }\ + return true; \ + } + + #define MP_KVS_SIMPLE_STRING_FUNCTION(__name,__ifacecommand) \ + MP_KVS_FUNCTION(__name) \ + { \ + MP_KVS_FAIL_ON_NO_INTERFACE \ + QString szRet = g_pMPInterface->__ifacecommand(); \ + c->returnValue()->setString(szRet); \ + return true; \ + } + + #define MP_KVS_SIMPLE_INT_FUNCTION(__name,__ifacecommand) \ + MP_KVS_FUNCTION(__name) \ + { \ + MP_KVS_FAIL_ON_NO_INTERFACE \ + int iRet = g_pMPInterface->__ifacecommand(); \ + c->returnValue()->setInteger(iRet); \ + return true; \ + } + // FINDME! + #define MP_KVS_SIMPLE_BOOL_FUNCTION(__name,__ifacecommand) \ + MP_KVS_FUNCTION(__name) \ + { \ + MP_KVS_FAIL_ON_NO_INTERFACE \ + bool bRet = g_pMPInterface->__ifacecommand(); \ + c->returnValue()->setBoolean(bRet); \ + return true; \ + } + + +/* + @doc: mediaplayer.play + @type: + command + @title: + mediaplayer.play + @short: + Starts media playback in the selected media player + @syntax: + mediaplayer.play [-q] + @description: + Starts playback in the remote instance of the currently selected media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.stop[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(play,play) + +/* + @doc: mediaplayer.hide + @type: + command + @title: + mediaplayer.hide + @short: + Hide the mediaplayer [-q] + @syntax: + mediaplayer.hide + @description: + Hide the player interface.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.quit[/cmd], + [cmd]mediaplayer.show[/cmd], + [cmd]mediaplayer.minimize[/cmd] +*/ + +MP_KVS_SIMPLE_COMMAND(hide,hide) + +/* + @doc: mediaplayer.show + @type: + command + @title: + mediaplayer.show + @short: + Show the mediaplayer. + @syntax: + mediaplayer.show [-q] + @description: + Show the player interface.[br] + When you use this function in your script, remember to reshow mediaplayer's window [br] + or quit the mediplayerwindow to the exit.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.quit[/cmd], + [cmd]mediaplayer.hide[/cmd], + [cmd]mediaplayer.minimize[/cmd] +*/ + +MP_KVS_SIMPLE_COMMAND(show,show) + +/* + @doc: mediaplayer.minimize + @type: + command + @title: + mediaplayer.minimize + @short: + Minimize the mediaplayer. + @syntax: + mediaplayer.minimize [-q] + @description: + Minimize the player interface.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.quit[/cmd], + [cmd]mediaplayer.hide[/cmd], + [cmd]mediaplayer.show[/cmd] +*/ + +MP_KVS_SIMPLE_COMMAND(minimize,minimize) + +/* + @doc: mediaplayer.stop + @type: + command + @title: + mediaplayer.stop + @short: + Stops media playback in the selected media player + @syntax: + mediaplayer.stop [-q] + @description: + Stops playback in the remote instance of the currently selected media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.play[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(stop,stop) + +/* + @doc: mediaplayer.next + @type: + command + @title: + mediaplayer.next + @short: + Starts playback of the next song (mediaplayer interface module) + @syntax: + mediaplayer.next [-q] + @description: + Starts playback of the next song in the remote instance of the slave media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.stop[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.play[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(next,next) + +/* + @doc: mediaplayer.prev + @type: + command + @title: + mediaplayer.prev + @short: + Starts playback of the previous song (mediaplayer interface module) + @syntax: + mediaplayer.prev [-q] + @description: + Starts playback of the previous song in the remote instance of the slave media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.stop[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.play[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(prev,prev) + +/* + @doc: mediaplayer.quit + @type: + command + @title: + mediaplayer.quit + @short: + Quits the remote media player (mediaplayer interface module) + @syntax: + mediaplayer.quit [-q] + @description: + Quits the remote instance of the slave media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.stop[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(quit,quit) + +/* + @doc: mediaplayer.pause + @type: + command + @title: + mediaplayer.pause + @short: + Pauses playback (mediaplayer interface module) + @syntax: + mediaplayer.pause [-q] + @description: + Pauses playback in the remote instance of the slave media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.stop[/cmd], + [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(pause,pause) + +/* + @doc: mediaplayer.detect + @type: + command + @title: + mediaplayer.detect + @short: + Detects the media player interface to use + @syntax: + mediaplayer.detect [-q] + @description: + Attempts to detect the best media player interface + for the current system. The -q switch causes the detection + algorithm to run quietly. This function may attempt to start + the media players in order to verify their presence on the system. + You can guide the function by starting the media player you + prefer before running it: if a running media player is found, it takes + precedence over the others.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.stop[/cmd], [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc], + [cmd]mediaplayer.setPlayer[/cmd], + [fnc]$mediaplayer.player[/fnc] +*/ + +MP_KVS_COMMAND(detect) +{ + g_pMPInterface = auto_detect_player(c->hasSwitch('q',"quiet") ? 0 : c->window()); + return true; +} + +/* + @doc: mediaplayer.setPlayer + @type: + command + @title: + mediaplayer.setPlayer + @short: + Sets the media player interface + @syntax: + mediaplayer.setPlayer <player_name> + @description: + Sets the media player interface to be used by the + mediaplayer module. <interface_name> must be one + of the player names returned by [fnc]$mediaplayer.playerList()[/fnc] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.detect[/cmd], [fnc]$mediaplayer.player[/fnc] +*/ + +MP_KVS_COMMAND(setPlayer) +{ + QString szPlayer; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("player",KVS_PT_STRING,0,szPlayer) + KVSM_PARAMETERS_END(c) + + for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + if(d->name() == szPlayer) + { + g_pMPInterface = d->instance(); + KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) = szPlayer; + return true; + } + } + + return true; +} + +/* + @doc: mediaplayer.player + @type: + function + @title: + $mediaplayer.player + @short: + Returns the currently set media player interface + @syntax: + $mediaplayer.player() + @description: + Returns the currently set media player interface. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.detect[/cmd], [cmd]mediaplayer.setPlayer[/cmd] +*/ + +MP_KVS_FUNCTION(player) +{ + c->returnValue()->setString(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer)); + return true; +} + +/* + @doc: mediaplayer.playerList + @type: + function + @title: + $mediaplayer.playerList + @short: + Returns a the list of the supported media player interfaces + @syntax: + $mediaplayer.playerList() + @description: + Returns an array containing the supported media player interfaces. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [cmd]mediaplayer.detect[/cmd], [cmd]mediaplayer.setPlayer[/cmd], + [fnc]$mediaplayer.player[/fnc] +*/ + +MP_KVS_FUNCTION(playerList) +{ + KviKvsArray* pArray = new KviKvsArray(); + int id=0; + + for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + pArray->set(id++,new KviKvsVariant(d->name())); + } + c->returnValue()->setArray(pArray); + return true; +} +/* + @doc: mediaplayer.playmrl + @type: + command + @title: + mediaplayer.playMrl + @short: + Plays the specified media on the selected media player + @syntax: + mediaplayer.playMrl <mrl> + @description: + Plays the media specified by the <mrl> on the currently + selected media player interface. <mrl> is a standard Media Resource + Locator. Examples of such locators are: 'file:///home/myfile.mp3' , + 'http://streaming.server.top:123', 'dvd:// or dvb://channelname'. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], + [fnc]$mediaplayer.localFile[/fnc], + [cmd]mediaplayer.play[/cmd] +*/ + +MP_KVS_COMMAND(playMrl) +{ + QString szMrl; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->playMrl(szMrl)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + + return true; +} + +MP_KVS_COMMAND(amipExec) +{ + QString szMrl; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->amipExec(szMrl)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + + return true; +} + + +/* + @doc: mediaplayer.jumpTo + @type: + command + @title: + mediaplayer.jumpTo + @short: + Sets the position in seconds of the current song. + @syntax: + mediaplayer.jumpTo [-q] <pos> + @description: + Sets the position in seconds of the current song . + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.position[/fnc], + [fnc]$mediaplayer.lenght[/fnc], +*/ + +MP_KVS_COMMAND(jumpTo) +{ + int iPos; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("position",KVS_PT_INT,0,iPos) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->jumpTo(iPos)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + +/* + @doc: mediaplayer.setVol + @type: + command + @title: + mediaplayer.setVol + @short: + Set the media player volume to <vol> (from 0-255) + @syntax: + mediaplayer.setVol [-q] <vol> + @description: + Set the media player volume to <vol> (the valid range is from 0 to ....) + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.getVol[/fnc] +*/ + +MP_KVS_COMMAND(setVol) +{ + kvs_int_t iVol; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("volume",KVS_PT_INT,0,iVol) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->setVol(iVol)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + +/* + @doc: mediaplayer.getVol + @type: + function + @title: + $mediaplayer.getVol + @short: + Returns the current volume of the media player + @syntax: + $mediaplayer.getVol() + @description: + Returns the current volume of the media player within 0 to 255. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.setVol[/cmd] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(getVol,getVol) + +/* + @doc: mediaplayer.mute + @type: + command + @title: + mediaplayer.mute + @short: + Mute the volume selected media player + @syntax: + mediaplayer.mute + @description: + Mutes the volume selected media player.[br] + If already muted, it restores the volume.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.play[/cmd], [cmd]mediaplayer.pause[/cmd], + [cmd]mediaplayer.prev[/cmd], + [cmd]mediaplayer.next[/cmd], + [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.status[/fnc] +*/ + +MP_KVS_SIMPLE_COMMAND(mute,mute) + + +/* + @doc: mediaplayer.mrl + @type: + function + @title: + $mediaplayer.mrl + @short: + Returns the mrl of the currently played media + @syntax: + $mediaplayer.mrl() + @description: + Returns the mrl of the media currently played by the selected media player interface. + The mrl is a standard Media Resource Locator. + Examples of such locators are: 'file:///home/myfile.mp3' , + 'http://streaming.server.top:123', 'dvd:// or dvb://channelname'. + This means that the returned string may NOT refer to a local file: + it refers to the local file only if the 'file://' prefix is found ([fnc]$mediaplayer.localFile()[/fnc] + checks that for you). + The returned string is empty if the player isn't currently playing.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.playMrl[/cmd], + [fnc]$mediaplayer.localFile[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(mrl,mrl) + +/* + @doc: mediaplayer.nowPlaying + @type: + function + @title: + $mediaplayer.nowPlaying + @short: + Returns a descripting of the currently played media + @syntax: + $mediaplayer.nowPlaying() + @description: + Returns a description fo the media currently played + by the selected media player interface. The description + will usually contain the title of the media and eventually + some additional information like the artist name or album. + This function is granted to be implemented by all the media + player interfaces and return an empty string only + if the player is not currently playing or there is a communication + error. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.title[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.genre[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], + [fnc]$mediaplayer.bitRate[/fnc], + [fnc]$mediaplayer.sampleRate[/fnc], + [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(nowPlaying,nowPlaying) + +/* + @doc: mediaplayer.title + @type: + function + @title: + $mediaplayer.title + @short: + Returns the title of the current media + @syntax: + $mediaplayer.title() + @description: + Returns the title of the multimedia file being played by the + remote instance of the media player. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.genre[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(title,title) + +/* + @doc: mediaplayer.artist + @type: + function + @title: + $mediaplayer.artist + @short: + Returns the artist of the media player + @syntax: + $mediaplayer.artist() + @description: + Returns the artist property of the media currently played by + the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.title[/fnc], [fnc]$mediaplayer.genre[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], + [fnc]$mediaplayer.album[/fnc], + [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(artist,artist) + +/* + @doc: mediaplayer.genre + @type: + function + @title: + $mediaplayer.genre + @short: + Returns the genre of the media player + @syntax: + $mediaplayer.genre() + @description: + Returns the genre property of the media currently played by + the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc], + [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(genre,genre) + +/* + @doc: mediaplayer.year + @type: + function + @title: + $mediaplayer.year + @short: + Returns the year of the media player + @syntax: + $mediaplayer.year() + @description: + Returns the year property of the media currently played by + the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.genre[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc], + [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(year,year) + +/* + @doc: mediaplayer.comment + @type: + function + @title: + $mediaplayer.comment + @short: + Returns the comment of the media player + @syntax: + $mediaplayer.comment() + @description: + Returns the comment property of the media currently played by + the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.year[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc], + [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(comment,comment) + +/* + @doc: mediaplayer.album + @type: + function + @title: + $mediaplayer.album + @short: + Returns the album of the media player + @syntax: + $mediaplayer.album() + @description: + Returns the album property of the media currently played by + the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types: + if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc] + instead.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.mediaType[/fnc], + [fnc]$mediaplayer.bitRate[/fnc], + [fnc]$mediaplayer.sampleRate[/fnc], + [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(album,album) + +/* + @doc: mediaplayer.mediaType + @type: + function + @title: + $mediaplayer.mediaType + @short: + Returns the currently played media type + @syntax: + $mediaplayer.medyaType() + @description: + Returns a string describing the media type currently played + by the selected media player interface. This function is not granted + to work with all the player interfaces and all the media types. + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc] +*/ + +MP_KVS_SIMPLE_STRING_FUNCTION(mediaType,mediaType) + +/* + @doc: mediaplayer.bitRate + @type: + function + @title: + $mediaplayer.bitRate + @short: + Returns the bit rate of the current song + @syntax: + $mediaplayer.bitRate + @description: + Returns the bit rate (in bits/sec) of the multimedia file being played by the + remote instance of the media player.This function is not granted + to work with all the player interfaces and all the media types so + you may get -1 or 0 in return sometimes.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.sampleRate[/fnc], + [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(bitRate,bitRate) + + +/* + @doc: mediaplayer.sampleRate + @type: + function + @title: + $mediaplayer.sampleRate + @short: + Returns the sample rate of the current song + @syntax: + $mediaplayer.sampleRate + @description: + Returns the sample rate (in Hz) of the multimedia file being played by the + remote instance of the media player.This function is not granted + to work with all the player interfaces and all the media types so + you may get -1 or 0 in return sometimes.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.bitRate[/fnc], [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.position[/fnc], [fnc]$mediaplayer.channels[/fnc] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(sampleRate,sampleRate) + + +/* + @doc: mediaplayer.length + @type: + function + @title: + $mediaplayer.length + @short: + Returns the length of the current media + @syntax: + $mediaplayer.length() + @description: + Returns the length in milliseconds of the multimedia file being played by the + remote instance of the media player.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.sampleRate[/fnc], + [fnc]$mediaplayer.bitRate[/fnc], + [fnc]$mediaplayer.position[/fnc] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(length,length) + +/* + @doc: mediaplayer.position + @type: + function + @title: + $mediaplayer.position + @short: + Returns the position of the current media + @syntax: + $mediaplayer.position() + @description: + Returns the currently elapsed time of the multimedia file being played by the + remote instance of the media player. + The time is expressed in milliseconds.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd], + [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc], + [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc], + [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc], + [fnc]$mediaplayer.sampleRate[/fnc], + [fnc]$mediaplayer.length[/fnc], + [fnc]$mediaplayer.bitRate[/fnc], [fnc]$mediaplayer.channels[/fnc] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(position,position) + +/* + @doc: mediaplayer.channels + @type: + function + @title: + $mediaplayer.channels + @short: + Returns the number of channels of the current song + @syntax: + $mediaplayer.channels() + @description: + Returns the number of channels of the multimedia file being played by the + remote instance of the media player.This function is not granted + to work with all the player interfaces and all the media types so + you may get -1 or 0 in return sometimes.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(channels,channels) + + +/* + @doc: mediaplayer.setPlayListPos + @type: + command + @title: + mediaplayer.setPlayListPos + @short: + Set the position for the current song. + @syntax: + mediaplayer.setPlayListPos [-q] <pos:integer> + @description: + Set the position in the player list for the current song to <pos>.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.getPlayListPos[/fnc] +*/ + +MP_KVS_COMMAND(setPlayListPos) +{ + int iPos; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("position",KVS_PT_INT,0,iPos) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->setPlayListPos(iPos)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + +/* + @doc: mediaplayer.getPlayListPos + @type: + function + @title: + $mediaplayer.getPlayListPos + @short: + Get the position for the current song. + @syntax: + $mediaplayer.getPlayListPos() + @description: + Get the song's position in the player list.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.getPlayListPos[/cmd] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(getPlayListPos,getPlayListPos) + +/* + @doc: mediaplayer.getListLength + @type: + function + @title: + $mediaplayer.getListLength + @short: + Return the play list length. + @syntax: + $mediaplayer.getListLength() + @description: + Return the player list length.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(getListLength,getListLength) + + +/* + @doc: mediaplayer.getRepeat + @type: + function + @title: + $mediaplayer.getRepeat + @short: + Return if "Repeat" is on. + @syntax: + $mediaplayer.getRepeat() + @description: + Return the value of the Repeat flag for the current track (1 for ON, 0 for OFF.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.setRepeat[/cmd], [cmd]mediaplayer.setShuffle[/cmd], + [fnc]$mediaplayer.getShuffle[/fnc] +*/ + +MP_KVS_SIMPLE_INT_FUNCTION(getRepeat,getRepeat) + + +/* + @doc: mediaplayer.getShuffle + @type: + function + @title: + $mediaplayer.getShuffle + @short: + Return if "Shuffle" is on. + @syntax: + $mediaplayer.getShuffle() + @description: + Return the value of the Shuffle flag (1 for ON, 0 for OFF.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.setShuffle[/cmd], [cmd]mediaplayer.setRepeat[/cmd], + [fnc]$mediaplayer.getRepeat[/fnc] +*/ + +MP_KVS_SIMPLE_BOOL_FUNCTION(getShuffle,getShuffle) + +/* + @doc: mediaplayer.getEqData + @type: + function + @title: + $mediaplayer.getEqData + @short: + Return the Equalizer Value. + @syntax: + $mediaplayer.getEqData(<item:integer>,<options:string>) + @description: + Return the value of the Eq <item>.[br] + if 'q' is given as an option, it runs in quiet mode.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.setShuffle[/cmd], [cmd]mediaplayer.setRepeat[/cmd], + [fnc]$mediaplayer.getRepeat[/fnc] + +*/ + +MP_KVS_FUNCTION(getEqData) +{ + int iValue; + QString szOptions; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("item",KVS_PT_INT,0,iValue) + KVSM_PARAMETER("options",KVS_PT_STRING,KVS_PF_OPTIONAL,szOptions) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + + bool bQuiet = szOptions.find('q',false) != -1; + + int ret = g_pMPInterface->getEqData(iValue); + + if(!ret && !bQuiet) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + + c->returnValue()->setInteger(ret); + return true; +} + +/* + @doc: mediaplayer.setEqData + @type: + command + @title: + mediaplayer.setEqData + @short: + Return the Equalizer Value. + @syntax: + mediaplayer.setEqData [-q] <item:integer> <value:integer> + @description: + Set the value of the Eq <item> to <value>.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.getEqData[/fnc] +*/ + +MP_KVS_COMMAND(setEqData) +{ + int iPos; + int iValue; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("item",KVS_PT_INT,0,iPos) + KVSM_PARAMETER("value",KVS_PT_INT,0,iValue) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->setEqData(iPos,iValue)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + +/* + @doc: mediaplayer.localFile + @type: + function + @title: + $mediaplayer.localFile + @short: + Returns the name of the local file played by the media player + @syntax: + $mediaplayer.localFile() + @description: + Returns the name of the local file played by the currently + selected media player interface. This function returns + an empty string if the player is not playing, there is a communication + error or the media played is not a local file (e.g. a stream or another + kind of media).[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.play[/cmd] +*/ + +MP_KVS_FUNCTION(localFile) +{ + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + QString szRet = g_pMPInterface->mrl(); + if(szRet.isEmpty())return true; + if(szRet.startsWith("file://",false)) + { + szRet.remove(0,7); + c->returnValue()->setString(szRet); + } + return true; +} + +MP_KVS_FUNCTION(amipEval) +{ + QString szMrl; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + QString szRet = g_pMPInterface->amipEval(szMrl); + if(szRet.isEmpty())return true; + + c->returnValue()->setString(szRet); + + return true; +} + +/* + @doc: mediaplayer.status + @type: + function + @title: + $mediaplayer.status + @short: + Returns the status of the media player + @syntax: + $mediaplayer.status() + @description: + Returns the status if the currently selected media player: "playing", + "stopped", "paused" or "unknown". + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [cmd]mediaplayer.play[/cmd] +*/ + +MP_KVS_FUNCTION(status) +{ + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + KviMediaPlayerInterface::PlayerStatus eStat = g_pMPInterface->status(); + switch(eStat) + { + case KviMediaPlayerInterface::Stopped: + c->returnValue()->setString("stopped"); + break; + case KviMediaPlayerInterface::Playing: + c->returnValue()->setString("playing"); + break; + case KviMediaPlayerInterface::Paused: + c->returnValue()->setString("paused"); + break; + default: + c->returnValue()->setString("unknown"); + break; + } + return true; +} + + +/* + @doc: mediaplayer + @type: + module + @short: + Interface to various media players + @title: + The mediaplayer interface module + @body: + The mediaplayer module is an interface to various popular media players. + It allows controlling them remotely to a certain degree and retrieving + the informations about the currently played media (in order to implement the nice /playing + scripts). The module has replaced the old mediaplayer module which after + years of development had developed some design flaws and needed a complete rewrite. + At the moment of writing the supported players are: xmms (unix), audacious (unix), winamp (windows), + amarok (kde) and juk (kde). You choose the player interface by either setting + the option in the settings dialog, by manually setting [cmd]option[/cmd] stringPreferredMediaPlayer + or by running [cmd]mediaplayer.detect[/cmd] that will guess the media player interface for you.[br] + If you're going to use the Winamp media player then you must install the "gen_kvirc.dll" plugin + (included in the kvirc distribution) as a "general" winamp plugin. + This is achieved by simpy copying the file gen_kvirc.dll + to the winamp plugins directory and restarting winamp.[br] + [br] + The commands and functions exported by this module serve mainly for two + purposes: control the playback and get informations about the currently played media. + Playback control is achieved by the means of [cmd]mediaplayer.play[/cmd], + [cmd]mediaplayer.stop[/cmd], [cmd]mediaplayer.pause[/cmd], [cmd]mediaplayer.next[/cmd], + [cmd]mediaplayer.prev[/cmd] and [fnc]$mediaplayer.status()[/fnc]. The + informations about the currently played media can be retrieved with + [fnc]$mediaplayer.nowplaying()[/fnc] and [fnc]$mediaplayer.mrl()[/fnc]. + Several other informative function are available as well but they are not + granted to work with all the supported media players or media types (e.g. + with winamp you can play video files that probably have no album, genre + or sampleRate information...).[br] + If you intend to write portable code, you should check the return value + of the functions like [fnc]$mediaplayer.artist()[/fnc], [fnc]$mediaplayer.title()[/fnc] + or [fnc]$mediaplayer.channels()[/fnc] and be ready to discard it when it + does not appear to be meaningful. The functions that are granted + to work are [fnc]$mediaplayer.nowplaying()[/fnc], [fnc]$mediaplayer.mrl()[/fnc] + and [fnc]$mediaplayer.localFile()[/fnc]. +*/ + +/* + @doc: mediaplayer.setRepeat + @type: + command + @title: + $mediaplayer.setRepeat + @short: + Set the repeat flag. + @syntax: + mediaplayer.getRepeat [-q] <repeat:bool> + @description: + Set the Repeat flag to "repeat" (1 for ON, 0 for OFF.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.getRepeat[/fnc], [cmd]mediaplayer.setShuffle[/cmd], + [fnc]$mediaplayer.getShuffle[/fnc] +*/ + +MP_KVS_COMMAND(setRepeat) +{ + bool bVal; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("repeat",KVS_PT_BOOL,0,bVal) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->setRepeat(bVal)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + + +/* + @doc: mediaplayer.setShuffle + @type: + command + @title: + $mediaplayer.setShuffle + @short: + Set the repeat flag. + @syntax: + mediaplayer.getShuffle [-q] <shuffle:bool> + @description: + Set the Shuffle flag to "shuffle" (1 for ON, 0 for OFF.[br] + Take a look at the [module:mediaplayer]mediaplayer module documentation[/module] + for more details about how it works.[br] + @seealso: + [module:mediaplayer]media player module documentation[/module], + [fnc]$mediaplayer.getShuffle[/fnc], [cmd]mediaplayer.setRepeat[/cmd], + [fnc]$mediaplayer.getRepeat[/fnc] +*/ + +MP_KVS_COMMAND(setShuffle) +{ + bool bVal; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("shuffle",KVS_PT_BOOL,0,bVal) + KVSM_PARAMETERS_END(c) + + MP_KVS_FAIL_ON_NO_INTERFACE + if(!g_pMPInterface->setShuffle(bVal)) + { + if(!c->hasSwitch('q',"quiet")) + { + c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); + QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); + tmp += g_pMPInterface->lastError(); + c->warning(tmp); + } + } + return true; +} + +static bool mediaplayer_module_init( KviModule * m ) +{ + g_pDescriptorList = new KviPointerList<KviMediaPlayerInterfaceDescriptor>; + g_pDescriptorList->setAutoDelete(true); + +#ifndef COMPILE_ON_WINDOWS + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviXmmsInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAudaciousInterface)); +#endif + +#ifdef COMPILE_ON_WINDOWS + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmipInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviWinampInterface)); +#endif + +#ifdef COMPILE_KDE_SUPPORT + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmarokInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviJukInterface)); +#endif + + g_pMPInterface = 0; + + if(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) == "auto") + { + g_pMPInterface = auto_detect_player(); + } else { + for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + if(d->name() == KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer)) + { + g_pMPInterface = d->instance(); + } + } + } + + // check for "auto" interface too! + + + #define MP_KVS_REGCMD(__name,__stringname) KVSM_REGISTER_SIMPLE_COMMAND(m,__stringname,mediaplayer_kvs_cmd_ ## __name) + #define MP_KVS_REGFNC(__name,__stringname) KVSM_REGISTER_FUNCTION(m,__stringname,mediaplayer_kvs_fnc_ ## __name) + + MP_KVS_REGCMD(play,"play"); + MP_KVS_REGCMD(stop,"stop"); + MP_KVS_REGCMD(next,"next"); + MP_KVS_REGCMD(prev,"prev"); + MP_KVS_REGCMD(quit,"quit"); + MP_KVS_REGCMD(pause,"pause"); + MP_KVS_REGCMD(detect,"detect"); + MP_KVS_REGCMD(playMrl,"playMrl"); + MP_KVS_REGCMD(amipExec,"amipExec"); + MP_KVS_REGCMD(hide,"hide"); + MP_KVS_REGCMD(show,"show"); + MP_KVS_REGCMD(minimize,"minimize"); + MP_KVS_REGCMD(jumpTo,"jumpTo"); + MP_KVS_REGCMD(setPlayer,"setPlayer"); + MP_KVS_REGCMD(setVol,"setVol"); + MP_KVS_REGCMD(mute,"mute"); + MP_KVS_REGCMD(setRepeat,"setRepeat"); + MP_KVS_REGCMD(setShuffle,"setShuffle"); + MP_KVS_REGCMD(setPlayListPos,"setPlayListPos"); + MP_KVS_REGCMD(setEqData,"setEqData"); + + MP_KVS_REGFNC(nowPlaying,"nowPlaying"); + MP_KVS_REGFNC(mrl,"mrl"); + MP_KVS_REGFNC(title,"title"); + MP_KVS_REGFNC(artist,"artist"); + MP_KVS_REGFNC(genre,"genre"); + MP_KVS_REGFNC(year,"year"); + MP_KVS_REGFNC(comment,"comment"); + MP_KVS_REGFNC(album,"album"); + MP_KVS_REGFNC(mediaType,"mediaType"); + MP_KVS_REGFNC(bitRate,"bitRate"); + MP_KVS_REGFNC(sampleRate,"sampleRate"); + MP_KVS_REGFNC(length,"length"); + MP_KVS_REGFNC(position,"position"); + MP_KVS_REGFNC(status,"status"); + MP_KVS_REGFNC(player,"player"); + MP_KVS_REGFNC(playerList,"playerList"); + MP_KVS_REGFNC(localFile,"localFile"); + MP_KVS_REGFNC(amipEval,"amipEval"); + MP_KVS_REGFNC(channels,"channels"); + MP_KVS_REGFNC(getListLength,"getListLength"); + MP_KVS_REGFNC(getPlayListPos,"getPlayListPos"); + MP_KVS_REGFNC(getEqData,"getEqData"); + MP_KVS_REGFNC(getRepeat,"getRepeat"); + MP_KVS_REGFNC(getShuffle,"getShuffle"); + MP_KVS_REGFNC(getVol,"getVol"); +/* + // Crissi + m->registerFunction( "getmp3tag_date", mediaplayer_fnc_getmp3tag_date ); + m->registerFunction( "getmp3tag_version", mediaplayer_fnc_getmp3tag_version ); + m->registerFunction( "getmp3tag_layer", mediaplayer_fnc_getmp3tag_layer ); + m->registerFunction( "getmp3tag_crc", mediaplayer_fnc_getmp3tag_crc ); + m->registerFunction( "getmp3tag_copyright", mediaplayer_fnc_getmp3tag_copyright ); + m->registerFunction( "getmp3tag_original", mediaplayer_fnc_getmp3tag_original ); + m->registerFunction( "getmp3tag_emphasis", mediaplayer_fnc_getmp3tag_emphasis ); + m->registerFunction( "getmp3tag_tracknumber", mediaplayer_fnc_getmp3tag_tracknumber ); +*/ + return true; +} + +static bool mediaplayer_module_cleanup( KviModule * m ) +{ + delete g_pDescriptorList; + return true; +} + +static bool mediaplayer_module_can_unload( KviModule * m ) +{ + return true; +} + +static bool mediaplayer_module_ctrl(KviModule * m,const char * operation,void * param) +{ + if(kvi_strEqualCI(operation,"getAvailableMediaPlayers")) + { + // we expect param to be a pointer to QStringList + QStringList * l = (QStringList *)param; + for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + { + l->append(d->name()); + } + return true; + } + if(kvi_strEqualCI(operation,"detectMediaPlayer")) + { + auto_detect_player(0); + return true; + } + return false; +} + + + +KVIRC_MODULE( + "mediaplayer", + "1.1.0", + "Copyright (C) 2001-2007 Szymon Stefanek (pragma at kvirc dot net), " \ + "Christoph Thielecke (crissi99 at gmx dot de)," \ + "Tonino Imbesi (grifisx at barmes dot org)," \ + "Alessandro Carbone (noldor at barmes dot org)," \ + "Alexey Uzhva (wizard at opendoor dot ru), " \ + "Serge Baranov (sbaranov at gmail dot com)", + "Interface to various media players", + mediaplayer_module_init, + mediaplayer_module_can_unload, + mediaplayer_module_ctrl, + mediaplayer_module_cleanup +) diff --git a/src/modules/mediaplayer/mp_amarokinterface.cpp b/src/modules/mediaplayer/mp_amarokinterface.cpp new file mode 100644 index 00000000..5c941d4f --- /dev/null +++ b/src/modules/mediaplayer/mp_amarokinterface.cpp @@ -0,0 +1,189 @@ +//============================================================================= +// +// File : mp_amarokinterface.cpp +// Created on Sun 27 Mar 2005 16:55:09 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_amarokinterface.h" + +#ifdef COMPILE_KDE_SUPPORT + +#include "kvi_app.h" + +#include "dcopclient.h" +#include "kurl.h" + +#include <qdatastream.h> +#include <qvaluelist.h> + +#include "kvi_locale.h" + +MP_IMPLEMENT_DESCRIPTOR( + KviAmarokInterface, + "amarok", + __tr2qs_ctx( + "An interface to the AmaroK KDE media player." + , + "mediaplayer" + ) +) + + +KviAmarokInterface::KviAmarokInterface() + : KviDCOPHelper(true, "amarok") +{ +} + +KviAmarokInterface::~KviAmarokInterface() +{ +} + +int KviAmarokInterface::detect(bool bStart){ return detectApp("amarok",bStart,95,99); } + +bool KviAmarokInterface::prev(){ return voidRetVoidDCOPCall("player","prev()"); } +bool KviAmarokInterface::next(){ return voidRetVoidDCOPCall("player","next()"); } +bool KviAmarokInterface::play(){ return voidRetVoidDCOPCall("player","play()"); } +bool KviAmarokInterface::stop(){ return voidRetVoidDCOPCall("player","stop()"); } +bool KviAmarokInterface::pause(){ return voidRetVoidDCOPCall("player","pause()"); } +bool KviAmarokInterface::mute(){ return voidRetVoidDCOPCall("player","mute()"); } +bool KviAmarokInterface::quit(){ return voidRetVoidDCOPCall("MainApplication-Interface","quit()"); } + +bool KviAmarokInterface::jumpTo(kvs_int_t &iPos) +{ + return voidRetIntDCOPCall("player","seek(int)",iPos/1000); +} +bool KviAmarokInterface::setVol(kvs_int_t &iVol) +{ + return voidRetIntDCOPCall("player","setVolume(int)",100*iVol/255); +} + +#define MP_DCOP_STRING_CALL(_fncname,_iface,_fnc) \ +QString KviAmarokInterface::_fncname() \ +{ \ + QString ret; \ + if(!stringRetVoidDCOPCall(_iface,_fnc,ret))return false; \ + return ret; \ +} + +MP_DCOP_STRING_CALL(nowPlaying,"player","nowPlaying()") +MP_DCOP_STRING_CALL(artist,"player","artist()") +MP_DCOP_STRING_CALL(title,"player","title()") +MP_DCOP_STRING_CALL(genre,"player","genre()") +MP_DCOP_STRING_CALL(year,"player","year()") +MP_DCOP_STRING_CALL(comment,"player","comment()") +MP_DCOP_STRING_CALL(album,"player","album()") + +int KviAmarokInterface::getVol() +{ + int ret; + if(!intRetVoidDCOPCall("player","getVolume()",ret))return false; + return ret * 255 / 100; +} + +int KviAmarokInterface::sampleRate() +{ + int ret; + if(!intRetVoidDCOPCall("player","sampleRate()",ret))return false; + return ret; +} + +int KviAmarokInterface::length() +{ + int ret; + if(!intRetVoidDCOPCall("player","trackTotalTime()",ret))return false; + return ret * 1000; +} + +int KviAmarokInterface::position() +{ + int ret; + if(!intRetVoidDCOPCall("player","trackCurrentTime()",ret))return false; + return ret * 1000; +} + +bool KviAmarokInterface::getRepeat() +{ + bool ret; + if(!boolRetVoidDCOPCall("player","repeatTrackStatus()",ret))return false; + return ret; +} + +bool KviAmarokInterface::getShuffle() +{ + bool ret; + if(!boolRetVoidDCOPCall("player","randomModeStatus()",ret))return false; + return ret; +} + +bool KviAmarokInterface::setRepeat(bool &bVal) +{ + return voidRetBoolDCOPCall("player","enableRepeatTrack(bool)",bVal); +} + +bool KviAmarokInterface::setShuffle(bool &bVal) +{ + return voidRetBoolDCOPCall("player","enableRandomMode(bool)",bVal); +} + +KviMediaPlayerInterface::PlayerStatus KviAmarokInterface::status() +{ + int ret; + if(!intRetVoidDCOPCall("player","status()",ret))return KviMediaPlayerInterface::Unknown; + switch(ret) + { + case 0: + return KviMediaPlayerInterface::Stopped; + break; + case 1: + return KviMediaPlayerInterface::Paused; + break; + case 2: + return KviMediaPlayerInterface::Playing; + break; + default: + return KviMediaPlayerInterface::Unknown; + break; + } + return KviMediaPlayerInterface::Unknown; +} + +QString KviAmarokInterface::mrl() +{ + QString ret; + if(!stringRetVoidDCOPCall("player","encodedURL()",ret))return false; + KURL url(ret); + return url.prettyURL(); +} + +bool KviAmarokInterface::playMrl(const QString &mrl) +{ + QString title; + QByteArray data, replyData; + KviQCString replyType; + QDataStream arg(data,IO_WriteOnly); + arg << KURL(mrl); + if(!g_pApp->dcopClient()->call(m_szAppId,"playlist","playMedia(KURL)",data,replyType,replyData)) + return false; + return true; +} + + +#endif //COMPILE_KDE_SUPPORT diff --git a/src/modules/mediaplayer/mp_amarokinterface.h b/src/modules/mediaplayer/mp_amarokinterface.h new file mode 100644 index 00000000..ac856219 --- /dev/null +++ b/src/modules/mediaplayer/mp_amarokinterface.h @@ -0,0 +1,76 @@ +#ifndef _MP_AMAROKINTERFACE_H_ +#define _MP_AMAROKINTERFACE_H_ +//============================================================================= +// +// File : mp_amarokinterface.h +// Created on Sun 27 Mar 2005 16:55:09 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + + +#ifdef COMPILE_KDE_SUPPORT + + #include "kvi_dcophelper.h" + #include "mp_interface.h" + + class KviAmarokInterface : public KviMediaPlayerInterface, private KviDCOPHelper + { + public: + KviAmarokInterface(); + ~KviAmarokInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual bool setVol(kvs_int_t &iVol); + virtual bool mute(); + virtual int getVol(); + virtual bool quit(); + virtual QString nowPlaying(); + virtual QString mrl(); + virtual QString title(); + virtual QString artist(); + virtual QString genre(); + virtual QString comment(); + virtual QString year(); + virtual QString album(); + virtual int position(); + virtual int length(); + //virtual int bitRate(); unsupported + virtual int sampleRate(); + virtual bool playMrl(const QString &mrl); + virtual KviMediaPlayerInterface::PlayerStatus status(); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + }; + + MP_DECLARE_DESCRIPTOR(KviAmarokInterface) + +#endif //COMPILE_KDE_SUPPORT + +#endif //!_MP_AMAROKINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_amipinterface.cpp b/src/modules/mediaplayer/mp_amipinterface.cpp new file mode 100644 index 00000000..3a7094bc --- /dev/null +++ b/src/modules/mediaplayer/mp_amipinterface.cpp @@ -0,0 +1,400 @@ +#include "mp_amipinterface.h" +#include "kvi_options.h" + +#ifdef COMPILE_ON_WINDOWS + +#include <qtextcodec.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 QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding)); + if(!c)c = QTextCodec::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; +} + +QString eval_str(const char *var) +{ + QString 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; +} + +QString KviAmipInterface::mrl() +{ + QString ret; + QString fn = eval_str("var_fn"); + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(fn); + else ret=fn; + if(!ret.startsWith("http://",false)) + ret.prepend("file://"); + + return ret; +} + +QString getAmipString(const char * var) { + QString ret; + QString s = eval_str(var); + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(s); + else ret=s; + return ret; +} + +QString KviAmipInterface::nowPlaying() +{ + return getAmipString("var_s"); +} + +QString KviAmipInterface::artist() +{ + return getAmipString("var_1"); +} + +QString KviAmipInterface::title() +{ + return getAmipString("var_2"); +} + +QString KviAmipInterface::album() +{ + return getAmipString("var_4"); +} + +QString KviAmipInterface::year() +{ + return getAmipString("var_5"); +} + +QString KviAmipInterface::comment() +{ + return getAmipString("var_6"); +} + +QString 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 QString &cmd) +{ + if(!amip_dll) return false; + QTextCodec *c=mediaplayer_get_codec(); + KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8(); + return (ac_exec(szCmd) == AC_ERR_NOERROR); +} + +QString KviAmipInterface::amipEval(const QString &cmd) +{ + QString ret; + if(!amip_dll) return ret; + QTextCodec *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)) { + QString s = buff; + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(s); + else ret=s; + } + return ret; +} + +#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_amipinterface.h b/src/modules/mediaplayer/mp_amipinterface.h new file mode 100644 index 00000000..22bbf9d5 --- /dev/null +++ b/src/modules/mediaplayer/mp_amipinterface.h @@ -0,0 +1,58 @@ +#ifndef _MP_AMIPINTERFACE_H_ +#define _MP_AMIPINTERFACE_H_ + +#include "kvi_settings.h" + +#ifdef COMPILE_ON_WINDOWS + + #include "mp_interface.h" + + class KviAmipInterface : public KviMediaPlayerInterface + { + public: + KviAmipInterface(); + ~KviAmipInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual QString nowPlaying(); + virtual QString artist(); + virtual QString title(); + virtual QString genre(); + virtual QString comment(); + virtual QString album(); + virtual QString year(); + virtual QString mrl(); + virtual int position(); + virtual int length(); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual int sampleRate(); + virtual int bitRate(); + virtual int channels(); + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + virtual int getPlayListPos(); + virtual bool setPlayListPos(kvs_int_t &iPos); + virtual int getListLength(); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + virtual bool amipExec(const QString &cmd); + virtual QString amipEval(const QString &cmd); + virtual KviMediaPlayerInterface::PlayerStatus status(); + }; + + MP_DECLARE_DESCRIPTOR(KviAmipInterface) + +#endif //COMPILE_ON_WINDOWS + +#endif //!_MP_AMIPINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_dcopinterface.cpp b/src/modules/mediaplayer/mp_dcopinterface.cpp new file mode 100644 index 00000000..7c86e420 --- /dev/null +++ b/src/modules/mediaplayer/mp_dcopinterface.cpp @@ -0,0 +1,224 @@ +//============================================================================= +// +// File : mp_dcopinterface.cpp +// Created on Sun 27 Mar 2005 16:56:21 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_dcopinterface.h" + +#ifdef COMPILE_KDE_SUPPORT + +#include "dcopclient.h" + +#include <qdatastream.h> +#include <qvaluelist.h> + +#include "kvi_app.h" +#include "kvi_thread.h" + +KviMediaPlayerDCOPInterface::KviMediaPlayerDCOPInterface(const KviQCString &szAppId) +: KviMediaPlayerInterface() +{ + m_szAppId = szAppId; +} + +KviMediaPlayerDCOPInterface::~KviMediaPlayerDCOPInterface() +{ +} + +bool KviMediaPlayerDCOPInterface::ensureAppRunning(const QString &szApp) +{ + if(findRunningApp(m_szAppId))return true; + return startApp(m_szAppId,400); +} + + +bool KviMediaPlayerDCOPInterface::simpleDCOPCall(const KviQCString &szObj,const KviQCString &szFunc) +{ + if(!ensureAppRunning(m_szAppId))return false; + QByteArray data; + return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data); +} + +bool KviMediaPlayerDCOPInterface::boolDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool bVal) +{ + if(!ensureAppRunning(m_szAppId))return false; + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << bVal; + return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data); +} + +bool KviMediaPlayerDCOPInterface::intDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int iVal) +{ + if(!ensureAppRunning(m_szAppId))return false; + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << iVal; + return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data); +} + +bool KviMediaPlayerDCOPInterface::floatDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,float fVal) +{ + if(!ensureAppRunning(m_szAppId))return false; + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << fVal; + return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data); +} + +bool KviMediaPlayerDCOPInterface::stringDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString szVal) +{ + if(!ensureAppRunning(m_szAppId))return false; + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << szVal; + return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data); +} + +bool KviMediaPlayerDCOPInterface::stringRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString &ret) +{ + if(!ensureAppRunning(m_szAppId))return false; + QString title; + QByteArray data, replyData; + KviQCString replyType; + if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData)) + return false; + QDataStream reply( replyData, IO_ReadOnly ); + if(replyType == "QString") + { + reply >> ret; + return true; + } + return false; +} + +bool KviMediaPlayerDCOPInterface::intRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int &ret) +{ + if(!ensureAppRunning(m_szAppId))return false; + QString title; + QByteArray data, replyData; + KviQCString replyType; + if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData)) + return false; + QDataStream reply( replyData, IO_ReadOnly ); + if(replyType == "int") + { + reply >> ret; + return true; + } + return false; +} + +bool KviMediaPlayerDCOPInterface::boolRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool &ret) +{ + if(!ensureAppRunning(m_szAppId))return false; + QString title; + QByteArray data, replyData; + KviQCString replyType; + if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData)) + return false; + QDataStream reply( replyData, IO_ReadOnly ); + if(replyType == "bool") + { + reply >> ret; + return true; + } + return false; +} + + +bool KviMediaPlayerDCOPInterface::findRunningApp(const QString &szApp) +{ + QValueList<KviQCString> allApps = g_pApp->dcopClient() ->registeredApplications(); + QValueList<KviQCString>::iterator iterator; + KviQCString sz = szApp.local8Bit(); + for(iterator = allApps.begin();iterator != allApps.end();iterator++) + { + if(*iterator == sz)return true; + } + return false; +} + +int KviMediaPlayerDCOPInterface::detectApp(const QString &szApp,bool bStart,int iScoreWhenFound,int iScoreWhenStarted) +{ + // lookup the amarok interface + if(!g_pApp->dcopClient())return 0; + if(findRunningApp(szApp))return 95; // found a running amarok, no need to run further + + // no amarok app found + if(bStart) + { + // try to start it + if(!startApp(szApp,5000))return 10; // very low possibility + return findRunningApp(szApp) ? 99 : 0; // try to find it again + } + + return 30; // it still might be installed on the system but we're just unable to start it... +} + + +bool KviMediaPlayerDCOPInterface::startApp(const QString &szApp,int iWaitMSecs) +{ + // we could use KApplication::startServiceByDesktopName here + // but we want to be able to wait a defined amount of time + QStringList tmp; + QByteArray data, replyData; + KviQCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << szApp << tmp; + if(!g_pApp->dcopClient()->call( + "klauncher", + "klauncher", + "start_service_by_desktop_name(QString,QStringList)", + data, + replyType, + replyData)) + { + return false; + } else { + QDataStream reply(replyData, IO_ReadOnly); + if(replyType != "serviceResult")return false; + int result; + KviQCString dcopName; + QString error; + reply >> result >> dcopName >> error; + if(result != 0)return false; + } + // ok , we seem to have started it.. but it might take some seconds + // for the app to get registered + // we wait up to five seconds + if(iWaitMSecs > 0) + { + int i = 0; + while(i < iWaitMSecs) + { + if(findRunningApp(szApp))return true; + KviThread::msleep(100); + i += 100; + } + return findRunningApp(szApp); + } + return true; +} + + +#endif //COMPILE_KDE_SUPPORT diff --git a/src/modules/mediaplayer/mp_dcopinterface.h b/src/modules/mediaplayer/mp_dcopinterface.h new file mode 100644 index 00000000..6ce8594d --- /dev/null +++ b/src/modules/mediaplayer/mp_dcopinterface.h @@ -0,0 +1,57 @@ +#ifndef _MP_DCOPINTERFACE_H_ +#define _MP_DCOPINTERFACE_H_ +//============================================================================= +// +// File : mp_dcopinterface.h +// Created on Sun 27 Mar 2005 16:56:21 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#ifdef COMPILE_KDE_SUPPORT + +#include "mp_interface.h" + +class KviMediaPlayerDCOPInterface : public KviMediaPlayerInterface +{ +public: + KviMediaPlayerDCOPInterface(const KviQCString &szAppId); + ~KviMediaPlayerDCOPInterface(); +protected: + KviQCString m_szAppId; +protected: + bool ensureAppRunning(const QString &szApp); + bool findRunningApp(const QString &szApp); + bool startApp(const QString &szApp,int iWaitMSecs = 0); + int detectApp(const QString &szApp,bool bStart,int iScoreWhenFound,int iScoreWhenStarted); + bool simpleDCOPCall(const KviQCString &szObj,const KviQCString &szFunc); + bool intDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int iVal); + bool boolDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool bVal); + bool stringDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString szVal); + bool floatDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,float fVal); + bool stringRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString &ret); + bool intRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int &ret); + bool boolRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool &ret); +}; + +#endif //COMPILE_KDE_SUPPORT + +#endif //!_MP_DCOPINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_interface.cpp b/src/modules/mediaplayer/mp_interface.cpp new file mode 100644 index 00000000..0894de05 --- /dev/null +++ b/src/modules/mediaplayer/mp_interface.cpp @@ -0,0 +1,277 @@ +//============================================================================= +// +// File : mp_interface.cpp +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_interface.h" +#include "mp_mp3.h" +#include "kvi_options.h" +#include "kvi_locale.h" +#include <qtextcodec.h> + +static QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding)); + if(!c)c = QTextCodec::codecForLocale(); + return c; + +} + +void KviMediaPlayerInterface::notImplemented() +{ + setLastError(__tr2qs_ctx("Function not implemented","mediaplayer")); +} + + +int KviMediaPlayerInterface::position() +{ + notImplemented(); + return -1; +} + +int KviMediaPlayerInterface::length() +{ + notImplemented(); + return -1; +} + +bool KviMediaPlayerInterface::quit() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::hide() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::show() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::minimize() +{ + notImplemented(); + return false; +} + +QString KviMediaPlayerInterface::getLocalFile() +{ + QString ret = mrl(); + if(ret.isEmpty())return ret; + if(ret.startsWith("file://",false)) + { + ret.remove(0,7); + return ret; + } + return QString::null; +} + +QString KviMediaPlayerInterface::amipEval(const QString &cmd) +{ + return QString::null; +} + +#define SCAN_MP3_FILE \ + QString f = getLocalFile(); \ + if(f.isEmpty())return QString::null; \ + mp3info mp3; \ + if(!scan_mp3_file(f,&mp3))return QString::null; \ + QTextCodec *pCodec; \ + pCodec=mediaplayer_get_codec(); + +#define SCAN_MP3_FILE_RET_INT \ + QString f = getLocalFile(); \ + if(f.isEmpty())return -1; \ + mp3info mp3; \ + if(!scan_mp3_file(f,&mp3))return -1; + + +QString KviMediaPlayerInterface::artist() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(KviQCString(mp3.id3.artist)); +} + +QString KviMediaPlayerInterface::title() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(KviQCString(mp3.id3.title)); +} + + +QString KviMediaPlayerInterface::genre() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(KviQCString(get_typegenre(mp3.id3.genre[0]))); +} + +QString KviMediaPlayerInterface::comment() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(KviQCString(mp3.id3.comment)); +} + +QString KviMediaPlayerInterface::year() +{ + SCAN_MP3_FILE + return QString(mp3.id3.year); +} + +QString KviMediaPlayerInterface::album() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(KviQCString(mp3.id3.album)); +} + +bool KviMediaPlayerInterface::playMrl(const QString &mrl) +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::amipExec(const QString &cmd) +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::setVol(kvs_int_t &iVol) +{ + notImplemented(); + return false; +} + +int KviMediaPlayerInterface::getVol() +{ + notImplemented(); + return -1; +} + +bool KviMediaPlayerInterface::mute() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::jumpTo(int &iPos) +{ + notImplemented(); + return false; +} + +KviMediaPlayerInterface::PlayerStatus KviMediaPlayerInterface::status() +{ + notImplemented(); + return KviMediaPlayerInterface::Unknown; +} + +int KviMediaPlayerInterface::bitRate() +{ + SCAN_MP3_FILE_RET_INT + return header_bitrate(&(mp3.header)); +} + +int KviMediaPlayerInterface::sampleRate() +{ + SCAN_MP3_FILE_RET_INT + return header_frequency(&(mp3.header)); +} + +int KviMediaPlayerInterface::channels() +{ + SCAN_MP3_FILE_RET_INT + return header_channels(&(mp3.header)); +} + +int KviMediaPlayerInterface::getPlayListPos() +{ + notImplemented(); + return -1; +} + +bool KviMediaPlayerInterface::setPlayListPos(int &iPos) +{ + notImplemented(); + return false; +} + +int KviMediaPlayerInterface::getListLength() +{ + notImplemented(); + return -1; +} + + +int KviMediaPlayerInterface::getEqData(int &ival) +{ + notImplemented(); + return -1; +} + +bool KviMediaPlayerInterface::setEqData(int &iPos, int &iVal) +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::getRepeat() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::getShuffle() +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::setRepeat(bool &bVal) +{ + notImplemented(); + return false; +} + +bool KviMediaPlayerInterface::setShuffle(bool &bVal) +{ + notImplemented(); + return false; +} + +QString KviMediaPlayerInterface::mediaType() +{ + QString ret = mrl(); + if(ret.endsWith(".mp3",false))ret = "MPEG Layer 3"; + else if(ret.endsWith(".ogg",false))ret = "OGG Vorbis"; + else if(ret.endsWith(".avi",false))ret = "Audio Video Interleave"; + else if(ret.endsWith(".mpeg",false))ret = "MPEG Video"; + else if(ret.endsWith(".mpg",false))ret = "MPEG Video"; + else if(ret.startsWith("http://",false))ret = "HTTP Audio Stream"; + else ret = QString::null; + return ret; +} + diff --git a/src/modules/mediaplayer/mp_interface.h b/src/modules/mediaplayer/mp_interface.h new file mode 100644 index 00000000..44667309 --- /dev/null +++ b/src/modules/mediaplayer/mp_interface.h @@ -0,0 +1,238 @@ +#ifndef _MP_INTERFACE_H_ +#define _MP_INTERFACE_H_ +//============================================================================= +// +// File : mp_interface.h +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "kvi_qstring.h" +#include "kvi_kvs_types.h" + +class KviMediaPlayerInterface +{ +public: + // don't do any initialization in the constructor + // implement lazy initialization in each function instead + KviMediaPlayerInterface(){}; + virtual ~KviMediaPlayerInterface(){}; +protected: + QString m_szLastError; +public: + const QString & lastError(){ return m_szLastError; }; + + // + // mandatory interface + // + + // This should attempt to detect if the player is available on the user's system + // and returning a score from 0 to 100 depending on how likely the player will work + // and how many of its functions are available. 100 means that the interface + // is absolutely sure that the player will start and play stuff. + // If bStart is true then the function is allowed to explicitly start the player, + // otherwise a startup attempt should not be made and different methods should be used. + // This function is used for auto-detection and is called twice: the first time + // with bStart set to false to determine the players that potentially could run. + // If no player returns a reasonably high value by just guessing, then + // a second loop may be attempted with the "bStart" parameter set to true. + // A level of 0 is considered total failure: in this case detect() should + // also set the last error to a descriptive string. + virtual int detect(bool bStart) = 0; + + // play previous media, return false only on communication failure + virtual bool prev() = 0; + // play next media, return false only on communication failure + virtual bool next() = 0; + // start playback now, return false only on communication failure (i.e. return true when already playing) + virtual bool play() = 0; + // stop playback now, return false only on communication failure (i.e. return true when already stopped) + virtual bool stop() = 0; + // pause playback now (do NOT toggle pause, just pause), return false only on communication failure + virtual bool pause() = 0; + + // current media related + + // currently played media: it should include AT least the title + // but may also include other informations. + // this string MUST be non-empty when the player is playing something. + // If it is empty then either the player is not playing or there are + // communication errors. + virtual QString nowPlaying() = 0; + // currently played media resource locator + // file://<filepath> for local files, dvb:// for dvb media , dvd:// for dvd's + // http:// for audio streams etc... + // empty if player is not playing (or in the tragic case that the player + // can't determine the url). + virtual QString mrl() = 0; + + // optional interface + + // this should play the specified mrl + // the mrl may be (or may be not) added to the player's playlist + // the function should return false if the player doesn't support + // this function or there is a communication error + virtual bool playMrl(const QString &mrl); + // what is this ? :D + virtual bool amipExec(const QString &cmd); + virtual QString amipEval(const QString &cmd); + // this is functions to hide,show and minimize the player interface + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + // set the volume of mediaplayer (0-255) + virtual bool setVol(kvs_int_t &iVol); + // get the pvolume value(0-255) + virtual int getVol(); + //mute the volume + virtual bool mute(); + // should quit the player if it's running + // return false only on communication failure + virtual bool quit(); + // return the current player status + enum PlayerStatus { Unknown, Stopped, Playing, Paused }; + virtual KviMediaPlayerInterface::PlayerStatus status(); + // current position in the media (msecs) + // 0 if the player isn't playing anything and -1 if unknown + virtual int position(); + // total length of the media (msecs) + // 0 if the player isn't playing anyting and -1 if unknown (e.g. a stream) + virtual int length(); + // jump to position + virtual bool jumpTo(int &iPos); + // interface with a default implementation for certain types of media (read for mp3) + // reimplement only if the player knows better + + // currently played media title (it's player choice if the title + // is to be derived from the media file name or from the informations + // stored inside the file like the ID3 tag...) + // If the player is not playing, the returned string should be empty + virtual QString title(); + // currently played media artist's name + // If the player is not playing, the returned string should be empty + // If the player can't guess the artist it should return the string "unknown" + virtual QString artist(); + // currently plaued media genre + // If the player is not playing, the returned string should be empty + // If the player can't guess the genre it should return the string "unknown" + virtual QString genre(); + // currently played media comment. + // Empty string if the player isn't playing anything or there is no comment + virtual QString comment(); + // currently played media year + // Empty string if the player isn't playing anything or the year is unknown + virtual QString year(); + // currently played media album + // Empty string if the player isn't playing anything + // If the player can't guess the album/collection then this string should be "unknown" + virtual QString album(); + // bit rate in bits/sec, 0 if unknown + virtual int bitRate(); + // sample rate in samples/sec (Hz), 0 if unknown + virtual int sampleRate(); + // number of channels + virtual int channels(); + // frequency + // the type of the media (MPEG Layer 3, MPEG Layer 4, OGG Vorbis, AVI Stream etc..) + virtual QString mediaType(); + // get the position in the playlist + virtual int getPlayListPos(); + // set the position in the playlist + virtual bool setPlayListPos(int &iPos); + // return the list's length + virtual int getListLength(); + // return the Eq(number) value + virtual int getEqData(int &i_val); + // set the Eq(iPos) to Eq(iVal) value + virtual bool setEqData(int &iPos, int &iVal); + // get the Repeat bool value + virtual bool getRepeat(); + // get the shuffle bool value + virtual bool getShuffle(); + // set the Repeat bool value + virtual bool setRepeat(bool &bVal); + // set the shuffle bool value + virtual bool setShuffle(bool &bVal); + void setLastError(const QString &szLastError){ m_szLastError = szLastError; }; +protected: + void notImplemented(); + QString getLocalFile(); +}; + + +class KviMediaPlayerInterfaceDescriptor +{ +public: + KviMediaPlayerInterfaceDescriptor(){}; + virtual ~KviMediaPlayerInterfaceDescriptor(){}; +public: + virtual const QString & name() = 0; + virtual const QString & description() = 0; + virtual KviMediaPlayerInterface * instance() = 0; +}; + + +#define MP_DECLARE_DESCRIPTOR(_interfaceclass) \ + class _interfaceclass ## Descriptor : public KviMediaPlayerInterfaceDescriptor \ + { \ + public: \ + _interfaceclass ## Descriptor(); \ + virtual ~_interfaceclass ## Descriptor(); \ + protected: \ + _interfaceclass * m_pInstance; \ + QString m_szName; \ + QString m_szDescription; \ + public: \ + virtual const QString & name(); \ + virtual const QString & description(); \ + virtual KviMediaPlayerInterface * instance(); \ + }; + +#define MP_IMPLEMENT_DESCRIPTOR(_interfaceclass,_name,_description) \ + _interfaceclass ## Descriptor::_interfaceclass ## Descriptor() \ + : KviMediaPlayerInterfaceDescriptor() \ + { \ + m_pInstance = 0; \ + m_szName = _name; \ + m_szDescription = _description; \ + } \ + _interfaceclass ## Descriptor::~_interfaceclass ## Descriptor() \ + { \ + if(m_pInstance)delete m_pInstance; \ + } \ + const QString & _interfaceclass ## Descriptor::name() \ + { \ + return m_szName; \ + } \ + const QString & _interfaceclass ## Descriptor::description() \ + { \ + return m_szDescription; \ + } \ + KviMediaPlayerInterface * _interfaceclass ## Descriptor::instance() \ + { \ + if(!m_pInstance)m_pInstance = new _interfaceclass(); \ + return m_pInstance; \ + } + +#define MP_CREATE_DESCRIPTOR(_interfaceclass) \ + new _interfaceclass ## Descriptor() + +#endif //!_MP_INTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_jukinterface.cpp b/src/modules/mediaplayer/mp_jukinterface.cpp new file mode 100644 index 00000000..d5a69a77 --- /dev/null +++ b/src/modules/mediaplayer/mp_jukinterface.cpp @@ -0,0 +1,185 @@ +//============================================================================= +// +// File : mp_jukinterface.cpp +// Created on Tue 29 Mar 2005 01:38:34 by Szymon Stfeanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stfeanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_jukinterface.h" + +#ifdef COMPILE_KDE_SUPPORT + +#include "kvi_app.h" + +#include "dcopclient.h" +#include "kurl.h" + +#include <qdatastream.h> +#include <qvaluelist.h> + +#include "kvi_locale.h" + +// the dcop interface of this player is incomplete :( + +MP_IMPLEMENT_DESCRIPTOR( + KviJukInterface, + "juk", + __tr2qs_ctx( + "An interface to the Juk KDE media player." + , + "mediaplayer" + ) +) + + +KviJukInterface::KviJukInterface() + : KviDCOPHelper(true, "amarok") +{ +} + +KviJukInterface::~KviJukInterface() +{ +} + +int KviJukInterface::detect(bool bStart){ return detectApp("juk",bStart,90,96); } + +bool KviJukInterface::prev(){ return voidRetVoidDCOPCall("Player","forward()"); } +bool KviJukInterface::next(){ return voidRetVoidDCOPCall("Player","back()"); } +bool KviJukInterface::play(){ return voidRetVoidDCOPCall("Player","play()"); } +bool KviJukInterface::stop(){ return voidRetVoidDCOPCall("Player","stop()"); } +bool KviJukInterface::pause(){ return voidRetVoidDCOPCall("Player","pause()"); } +bool KviJukInterface::quit(){ return voidRetVoidDCOPCall("MainApplication-Interface","quit()"); } + +bool KviJukInterface::setVol(kvs_int_t &iVol) +{ + return voidRetFloatDCOPCall("player","setVolume(float)",(float)(iVol)/255.); +} + +bool KviJukInterface::jumpTo(kvs_int_t &iPos) +{ + return voidRetIntDCOPCall("player","seek(int)",iPos/1000); +} + +bool KviJukInterface::getShuffle() +{ + QString szMode; + if(!stringRetVoidDCOPCall("player","randomPlayMode()",szMode))return false; + return (szMode != "NoRandom"); +} + +bool KviJukInterface::setShuffle(bool &bVal) +{ + QString szMode; + if(bVal) + { + szMode = "Random"; + } else { + szMode = "NoRandom"; + } + if(!voidRetStringDCOPCall("player","setRandomPlayMode(QString)",szMode))return false; + return true; +} + + +#define MP_DCOP_STRING_CALL(_fncname,_iface,_fnc) \ +QString KviJukInterface::_fncname() \ +{ \ + QString ret; \ + if(!stringRetVoidDCOPCall(_iface,_fnc,ret))return false; \ + return ret; \ +} + +MP_DCOP_STRING_CALL(nowPlaying,"Player","playingString()") + +/* + FIXME: there is trackProperty(propertyName) for these... +MP_DCOP_STRING_CALL(artist,"player","artist()") +MP_DCOP_STRING_CALL(title,"player","title()") +MP_DCOP_STRING_CALL(genre,"player","genre()") +MP_DCOP_STRING_CALL(year,"player","year()") +MP_DCOP_STRING_CALL(comment,"player","comment()") +MP_DCOP_STRING_CALL(album,"player","album()") + + +int KviJukInterface::sampleRate() +{ + int ret; + if(!intRetVoidDCOPCall("player","sampleRate()",ret))return false; + return ret; +} +*/ + +int KviJukInterface::length() +{ + int ret; + if(!intRetVoidDCOPCall("player","totalTime()",ret))return false; + return ret * 1000; +} + +int KviJukInterface::position() +{ + int ret; + if(!intRetVoidDCOPCall("player","currentTime()",ret))return false; + return ret * 1000; +} + +KviMediaPlayerInterface::PlayerStatus KviJukInterface::status() +{ + int ret; + if(!intRetVoidDCOPCall("player","status()",ret))return KviMediaPlayerInterface::Unknown; + switch(ret) + { + case 0: + return KviMediaPlayerInterface::Stopped; + break; + case 1: + return KviMediaPlayerInterface::Paused; + break; + case 2: + return KviMediaPlayerInterface::Playing; + break; + default: + return KviMediaPlayerInterface::Unknown; + break; + } + return KviMediaPlayerInterface::Unknown; +} + +QString KviJukInterface::mrl() +{ + // ugh :/ + QString ret; + return ret; +} + +bool KviJukInterface::playMrl(const QString &mrl) +{ + QString title; + QByteArray data, replyData; + KviQCString replyType; + QDataStream arg(data,IO_WriteOnly); + arg << mrl; + if(!g_pApp->dcopClient()->call(m_szAppId,"playlist","play(QString)",data,replyType,replyData)) + return false; + return true; +} + + +#endif //COMPILE_KDE_SUPPORT diff --git a/src/modules/mediaplayer/mp_jukinterface.h b/src/modules/mediaplayer/mp_jukinterface.h new file mode 100644 index 00000000..478a3c16 --- /dev/null +++ b/src/modules/mediaplayer/mp_jukinterface.h @@ -0,0 +1,77 @@ +#ifndef _MP_JUKINTERFACE_H_ +#define _MP_JUKINTERFACE_H_ +//============================================================================= +// +// File : mp_jukinterface.h +// Created on Tue 29 Mar 2005 01:38:34 by Szymon Stfeanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stfeanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "kvi_settings.h" + +#ifdef COMPILE_KDE_SUPPORT + + #include "kvi_dcophelper.h" + #include "mp_interface.h" + + class KviJukInterface : public KviMediaPlayerInterface, private KviDCOPHelper + { + public: + KviJukInterface(); + ~KviJukInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual bool setVol(kvs_int_t &iVol); + virtual QString nowPlaying(); + virtual QString mrl(); + /* + virtual QString title(); + virtual QString artist(); + virtual QString genre(); + virtual QString comment(); + virtual QString year(); + virtual QString album(); + */ + virtual int position(); + virtual int length(); + /* + virtual int bitRate(); + virtual int sampleRate(); + */ + virtual bool getShuffle(); + virtual bool setShuffle(bool &bVal); + + virtual bool playMrl(const QString &mrl); + virtual KviMediaPlayerInterface::PlayerStatus status(); + }; + + MP_DECLARE_DESCRIPTOR(KviJukInterface) + +#endif //COMPILE_KDE_SUPPORT + +#endif //!_MP_JUKINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_mp3.cpp b/src/modules/mediaplayer/mp_mp3.cpp new file mode 100644 index 00000000..6e27fa5f --- /dev/null +++ b/src/modules/mediaplayer/mp_mp3.cpp @@ -0,0 +1,468 @@ +//============================================================================= +// +// File : mp_mp3.cpp +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This file is based on the mp3tech.c. It is released under the original +// license and the original copyright notice follows. +// +// mp3tech.c +// +// Copyright (C) 2000 Cedric Tefft <cedric@earthling.net> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// This file is based in part on: +// +// * MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net> +// * MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and +// Johannes Overmann <overmann@iname.com> +// +// There has been also a remarkable work by Cristopher Tieckle (Crissi) +// +//============================================================================= + +#include "mp_mp3.h" +#include "kvi_options.h" + +#include <qfileinfo.h> +#include <qtextcodec.h> + +#define MAXGENRE 147 +#define GENREROWS 50 + +/* + The Information is stored in the last 128 bytes of an MP3. The Tag + has got the following fields, and the offsets given here, are from + 0-127. + + Field Length Offsets + Tag 3 0-2 + Songname 30 3-32 + Artist 30 33-62 + Album 30 63-92 + Year 4 93-96 + Comment 30 97-126 + Genre 1 127 + + + The string-fields contain ASCII-data, coded in ISO-Latin 1 codepage. + Strings which are smaller than the field length are padded with zero- + bytes. + + Tag: The tag is valid if this field contains the string "TAG". This + has to be uppercase! + + Songname: This field contains the title of the MP3 (string as + above). + + Artist: This field contains the artist of the MP3 (string as above). + + Album: this field contains the album where the MP3 comes from + (string as above). + + Year: this field contains the year when this song has originally + been released (string as above). + + Comment: this field contains a comment for the MP3 (string as + above). Revision to this field has been made in ID3v1.1. See + A.4. + + Genre: this byte contains the offset of a genre in a predefined + list the byte is treated as an unsigned byte. The offset is + starting from 0. See A.3. +*/ + + +const char *typegenre [MAXGENRE+2] = +{ + "Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge", + "Hip-Hop","Jazz","Metal","New Age","Oldies","Other","Pop","R&B", + "Rap","Reggae","Rock","Techno","Industrial","Alternative","Ska", + "Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient", + "Trip-Hop","Vocal","Jazz+Funk","Fusion","Trance","Classical", + "Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise", + "Alt. Rock","Bass","Soul","Punk","Space","Meditative", + "Instrumental Pop","Instrumental Rock","Ethnic","Gothic", + "Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance", + "Dream","Southern Rock","Comedy","Cult","Gangsta Rap","Top 40", + "Christian Rap","Pop/Funk","Jungle","Native American","Cabaret", + "New Wave","Psychedelic","Rave","Showtunes","Trailer","Lo-Fi", + "Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical", + "Rock & Roll","Hard Rock","Folk","Folk/Rock","National Folk", + "Swing","Fast-Fusion","Bebob","Latin","Revival","Celtic", + "Bluegrass","Avantgarde","Gothic Rock","Progressive Rock", + "Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band", + "Chorus","Easy Listening","Acoustic","Humour","Speech","Chanson", + "Opera","Chamber Music","Sonata","Symphony","Booty Bass","Primus", + "Porn Groove","Satire","Slow Jam","Club","Tango","Samba", + "Folklore","Ballad","Power Ballad","Rhythmic Soul","Freestyle", + "Duet","Punk Rock","Drum Solo","A Cappella","Euro-House", + "Dance Hall","Goa","Drum & Bass","Club-House","Hardcore","Terror", + "Indie","BritPop","Negerpunk","Polsk Punk","Beat", + "Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover", + "Contemporary Christian","Christian Rock","Merengue","Salsa", + "Thrash Metal","Anime","JPop","Synthpop","" +}; + +const char * get_typegenre(int idx) +{ + if(idx > MAXGENRE)return typegenre[12]; + return typegenre[idx]; +} + +int galphagenreindex[MAXGENRE+2] = +{ + 148,123,74,73,34,99,40,20,26,145,90, + 116,41,135,85,96,138,89,0,107,132,65,88, + 104,102,97,136,61,141,1,32,128,112,57,140, + 2,139,58,125,3,50,22,4,55,127,122,120, + 98,52,48,124,25,54,84,81,115,80,119,5, + 30,36,59,126,38,91,49,6,79,129,137,7, + 35,100,131,19,46,47,33,146,29,8,63,86, + 71,45,142,9,77,82,64,133,10,66,39,11, + 103,12,75,134,53,62,13,109,117,23,108,92, + 93,67,121,43,14,15,68,16,76,87,118,78, + 17,143,114,110,69,21,111,95,105,42,37,24, + 56,44,101,83,94,106,147,113,51,18,130,144, + 60,70,31,72,27,28 +}; + +int *alphagenreindex=&(galphagenreindex[1]); + + +int layer_tab[4]= {0, 3, 2, 1}; + +int frequencies[3][4] = +{ + {22050,24000,16000,50000}, /* MPEG 2.0 */ + {44100,48000,32000,50000}, /* MPEG 1.0 */ + {11025,12000,8000,50000} /* MPEG 2.5 */ +}; + +int bitrate[2][3][14] = +{ + { /* MPEG 2.0 */ + {32,48,56,64,80,96,112,128,144,160,176,192,224,256}, /* layer 1 */ + {8,16,24,32,40,48,56,64,80,96,112,128,144,160}, /* layer 2 */ + {8,16,24,32,40,48,56,64,80,96,112,128,144,160} /* layer 3 */ + }, + { /* MPEG 1.0 */ + {32,64,96,128,160,192,224,256,288,320,352,384,416,448}, /* layer 1 */ + {32,48,56,64,80,96,112,128,160,192,224,256,320,384}, /* layer 2 */ + {32,40,48,56,64,80,96,112,128,160,192,224,256,320} /* layer 3 */ + } +}; + +int frame_size_index[] = {24000, 72000, 72000}; + +const char *mode_text[] = +{ + "Stereo", "Joint Stereo", "Dual Channel", "Mono" +}; + +const char *emphasis_text[] = +{ + "None", "50/15 Microseconds", "Reserved", "CCITT J 17" +}; +void resetmp3infoStruct(mp3info *i) +{ + i->file=0; + i->datasize=0; + i->header_isvalid=0; + memset(&i->header,0,sizeof(i->header)); + i->id3_isvalid=0; + memset(&i->id3,0,sizeof(i->id3)); + i->vbr=0; + i->vbr_average=0; + i->seconds=0; + i->frames=0; + i->badframes=0; +} + +int get_mp3_info(mp3info *mp3) +{ + int frame_type[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + float seconds=0,total_rate=0; + int frames=0,frame_types=0,frames_so_far=0; + int l,vbr_median=-1; + int bitrate,lastrate; + int counter=0; +// mp3header header; + + int sample_pos,data_start=0; + + QFile fi(mp3->filename); + mp3->datasize=fi.size();//filestat.st_size; + + get_id3(mp3); + + if(get_first_header(mp3,0L)) + { + data_start=ftell(mp3->file); + lastrate=15-mp3->header.bitrate; + while((counter < NUM_SAMPLES) && lastrate) + { + sample_pos=(counter*(mp3->datasize/NUM_SAMPLES+1))+data_start; + if(get_first_header(mp3,sample_pos)) + { + bitrate=15-mp3->header.bitrate; + } else { + bitrate=-1; + } + + if(bitrate != lastrate) + { + mp3->vbr=1; + } + lastrate=bitrate; + counter++; + + } + mp3->frames=(mp3->datasize-data_start)/(l=frame_length(&mp3->header)); + mp3->seconds = (int)((float)(frame_length(&mp3->header)*mp3->frames)/ + (float)(header_bitrate(&mp3->header)*125)+0.5); + mp3->vbr_average = (float)header_bitrate(&mp3->header); + } + + return 0; +} + + +int get_first_header(mp3info *mp3, long startpos) +{ + int k, l=0,c; + mp3header h, h2; + long valid_start=0; + + fseek(mp3->file,startpos,SEEK_SET); + while(1) + { + while((c=fgetc(mp3->file)) != 255 && (c != EOF)); + if(c == 255) + { + ungetc(c,mp3->file); + valid_start=ftell(mp3->file); + if((l=get_header(mp3->file,&h))) + { + fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); + for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) + { + if(!(l=get_header(mp3->file,&h2))) break; + if(!sameConstant(&h,&h2)) break; + fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); + } + if(k == MIN_CONSEC_GOOD_FRAMES) + { + fseek(mp3->file,valid_start,SEEK_SET); + memcpy(&(mp3->header), &h2, sizeof(mp3header)); + mp3->header_isvalid = 1; + return 1; + } + } + } else { + return 0; + } + } + return 0; +} + + +// Get next MP3 frame header. +// Return codes: +// positive value = Frame Length of this header +// 0 = No, we did not retrieve a valid frame header + +int get_header(FILE *file,mp3header *header) +{ + unsigned char buffer[FRAME_HEADER_SIZE]; + int fl; + + if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) + { + header->sync=0; + return 0; + } + header->sync=(((int)buffer[0]<<4) | ((int)(buffer[1]&0xE0)>>4)); + if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1; + else header->version=2; + header->layer=(buffer[1] >> 1) & 3; + if((header->sync != 0xFFE) || (header->layer != 1)) + { + header->sync=0; + return 0; + } + header->crc=buffer[1] & 1; + header->bitrate=(buffer[2] >> 4) & 0x0F; + header->freq=(buffer[2] >> 2) & 0x3; + header->padding=(buffer[2] >>1) & 0x1; + header->extension=(buffer[2]) & 0x1; + header->mode=(buffer[3] >> 6) & 0x3; + header->mode_extension=(buffer[3] >> 4) & 0x3; + header->copyright=(buffer[3] >> 3) & 0x1; + header->original=(buffer[3] >> 2) & 0x1; + header->emphasis=(buffer[3]) & 0x3; + + return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0); +} + +int frame_length(mp3header *header) +{ + return header->sync == 0xFFE ? + (frame_size_index[3-header->layer]*((header->version&1)+1)* + header_bitrate(header)/header_frequency(header))+ + header->padding : 1; +} + +int header_layer(mp3header *h) +{ + return layer_tab[h->layer]; +} + +int header_bitrate(mp3header *h) +{ + if(h->bitrate > 0) + return bitrate[h->version & 1][3-h->layer][h->bitrate-1]; + else + return -1; // unknown +} + +int header_frequency(mp3header *h) +{ + return frequencies[h->version][h->freq]; +} + +const char *header_emphasis(mp3header *h) +{ + return emphasis_text[h->emphasis]; +} + +const char *header_mode(mp3header *h) +{ + return mode_text[h->mode]; +} + +int header_channels(mp3header * h) +{ + return h->mode == 3 ? 1 : 2; +} + +int header_crc(mp3header *h) +{ + return (!h->crc); +} + +int sameConstant(mp3header *h1, mp3header *h2) +{ + if((*(uint*)h1) == (*(uint*)h2)) return 1; + + if((h1->version == h2->version ) && + (h1->layer == h2->layer ) && + (h1->crc == h2->crc ) && + (h1->freq == h2->freq ) && + (h1->mode == h2->mode ) && + (h1->copyright == h2->copyright ) && + (h1->original == h2->original ) && + (h1->emphasis == h2->emphasis )) + return 1; + else return 0; +} + + +int get_id3(mp3info *mp3) +{ + // this will read ID3v1 tags + int retcode=0; + char fbuf[4]; + + if(mp3->datasize >= 128) + { + if(fseek(mp3->file, -128, SEEK_END )) + { + retcode |= 4; + } else { + fread(fbuf,1,3,mp3->file); fbuf[3] = '\0'; + mp3->id3.genre[0]=255; + + if(!strcmp((const char *)"TAG",(const char *)fbuf)) + { + mp3->id3_isvalid=1; + mp3->datasize -= 128; + fseek(mp3->file, -125, SEEK_END); + fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0'; + fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0'; + fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0'; + fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0'; + fread(mp3->id3.comment,1,30,mp3->file); mp3->id3.comment[30] = '\0'; + if(mp3->id3.comment[28] == '\0') + { + mp3->id3.track[0] = mp3->id3.comment[29]; + } + fread(mp3->id3.genre,1,1,mp3->file); + unpad(mp3->id3.title); + unpad(mp3->id3.artist); + unpad(mp3->id3.album); + unpad(mp3->id3.year); + unpad(mp3->id3.comment); + } + } + } + return retcode; +} + +char *pad(char *string, int length) +{ + int l; + + l=strlen(string); + while(l<length) + { + string[l] = ' '; + l++; + } + + string[l]='\0'; + return string; +} + +// Remove trailing whitespace from the end of a string + +char *unpad(char *string) +{ + char *pos=string+strlen(string)-1; + while(isspace(pos[0])) (pos--)[0]=0; + return string; +} + +bool scan_mp3_file(QString& szFileName,mp3info * i) +{ + //memset(i,0,sizeof(mp3info)); + resetmp3infoStruct(i); + + + i->filename = "text"; + i->file = fopen(QTextCodec::codecForLocale()->fromUnicode(i->filename).data(),"rb"); + if(!i->file)return false; + + get_mp3_info(i); + + fclose(i->file); + + return (i->id3_isvalid); +} + diff --git a/src/modules/mediaplayer/mp_mp3.h b/src/modules/mediaplayer/mp_mp3.h new file mode 100644 index 00000000..d42c5ef7 --- /dev/null +++ b/src/modules/mediaplayer/mp_mp3.h @@ -0,0 +1,137 @@ +//============================================================================= +// +// File : mp_mp3.h +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This file is based on the mp3tech.h. It is released under the original +// license and the original copyright notice follows. +// +// mp3tech.h +// +// Copyright (C) 2000 Cedric Tefft <cedric@earthling.net> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// This file is based in part on: +// +// * MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net> +// * MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and +// Johannes Overmann <overmann@iname.com> +// +// There has been also a remarkable work by Cristopher Tieckle (Crissi) +// +//============================================================================= + +// MIN_CONSEC_GOOD_FRAMES defines how many consecutive valid MP3 frames +// we need to see before we decide we are looking at a real MP3 file +#define MIN_CONSEC_GOOD_FRAMES 4 +#define FRAME_HEADER_SIZE 4 +#define MIN_FRAME_SIZE 21 +#define NUM_SAMPLES 4 +#define TEXT_FIELD_LEN 30 +#define INT_FIELD_LEN 4 + + +#include "kvi_settings.h" + +#include <stdio.h> +#include <stdlib.h> +#include <qstring.h> + +#ifdef COMPILE_ON_WINDOWS + #include <windows.h> +#else + #include <unistd.h> + #include <sys/stat.h> + #include <ctype.h> + #include <string.h> +#endif + + +enum VBR_REPORT { VBR_VARIABLE, VBR_AVERAGE, VBR_MEDIAN }; + +typedef struct { + unsigned int sync; + unsigned int version; + unsigned int layer; + unsigned int crc; + unsigned int bitrate; + unsigned int freq; + unsigned int padding; + unsigned int extension; + unsigned int mode; + unsigned int mode_extension; + unsigned int copyright; + unsigned int original; + unsigned int emphasis; +} mp3header; + +typedef struct { + char title[31]; + char artist[31]; + char album[31]; + char year[5]; + char comment[31]; + unsigned char track[1]; + unsigned char genre[1]; +} id3tag; + +typedef struct { + QString filename; + FILE *file; + unsigned int datasize; + int header_isvalid; + mp3header header; + int id3_isvalid; + id3tag id3; + int vbr; + float vbr_average; + int seconds; + int frames; + int badframes; +} mp3info; + +// mode field: +// 00 - Stereo +// 01 - Joint stereo (Stereo) +// 10 - Dual channel (2 mono channels) +// 11 - Single channel (Mono) + +bool scan_mp3_file(QString& szFileName,mp3info * i); + +void resetmp3infoStruct(mp3info *i); + +int header_channels(mp3header *h); +int header_frequency(mp3header *h); +const char *header_emphasis(mp3header *h); +const char *header_mode(mp3header *h); +int header_layer(mp3header *h); +int header_bitrate(mp3header *h); +double header_version(mp3header *h); +int header_crc(mp3header *h); +int get_header(FILE *file,mp3header *header); +int frame_length(mp3header *header); +int sameConstant(mp3header *h1, mp3header *h2); +int get_mp3_info(mp3info *mp3); +int get_id3(mp3info *mp3); +char *pad(char *string, int length); +char *unpad(char *string); +int get_first_header(mp3info *mp3,long startpos); +//void tagedit_curs(char *filename, int filenum, int fileoutof, id3tag *tag); +const char * get_typegenre(int idx); + diff --git a/src/modules/mediaplayer/mp_winampinterface.cpp b/src/modules/mediaplayer/mp_winampinterface.cpp new file mode 100644 index 00000000..ae157782 --- /dev/null +++ b/src/modules/mediaplayer/mp_winampinterface.cpp @@ -0,0 +1,566 @@ +//============================================================================= +// +// File : mp_winampinterface.cpp +// Created on Mon 28 Mar 2005 23:41:50 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "mp_winampinterface.h" +#include "kvi_options.h" + +#ifdef COMPILE_ON_WINDOWS + +#include <qtextcodec.h> + +#include "kvi_locale.h" +#include "kvi_module.h" + +#include <windows.h> + +#define IPC_STARTPLAY 102 +#define IPC_ISPLAYING 104 + +#define IPC_GETOUTPUTTIME 105 +// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME); +// ** +// ** IPC_GETOUTPUTTIME returns the position in milliseconds of the +// ** current song (mode = 0), or the song length, in seconds (mode = 1). +// ** Returns -1 if not playing or error. + +#define IPC_JUMPTOTIME 106 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME); +// ** IPC_JUMPTOTIME sets the position in milliseconds of the +// ** current song (approximately). + +#define IPC_SETPLAYLISTPOS 121 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS) +// ** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'. + +#define IPC_SETVOLUME 122 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME); +// ** IPC_SETVOLUME sets the volume of Winamp (from 0-255). + +#define IPC_GETLISTLENGTH 124 +// ** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH); +// ** IPC_GETLISTLENGTH returns the length of the current playlist, in +// ** tracks. + +#define IPC_GETEQDATA 127 +// ** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); +// ** IPC_GETEQDATA queries the status of the EQ. +// ** The value returned depends on what 'pos' is set to: +// ** Value Meaning +// ** ------------------ +// ** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db) +// ** 10 The preamp value. 0-63 (+20db - -20db) +// ** 11 Enabled. zero if disabled, nonzero if enabled. +// ** 12 Autoload. zero if disabled, nonzero if enabled. + +#define IPC_SETEQDATA 128 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA); +// ** IPC_SETEQDATA sets the value of the last position retrieved +// ** by IPC_GETEQDATA. This is pretty lame, and we should provide +// ** an extended version that lets you do a MAKELPARAM(pos,value). +// ** someday... + +#define IPC_GETPLAYLISTFILE 211 +// ** (requires Winamp 2.04+, only usable from plug-ins (not external apps)) +// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE); +// ** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index]. +// ** returns a pointer to it. returns NULL on error. + +#define IPC_GETPLAYLISTTITLE 212 +// * (requires Winamp 2.04+, only usable from plug-ins (not external apps)) +// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE); +// ** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index]. +// ** returns a pointer to it. returns NULL on error. + +#define IPC_GET_SHUFFLE 250 +// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE); +// ** +// ** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set) + +#define IPC_GET_REPEAT 251 +// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT); +// ** +// ** IPC_GET_REPEAT returns the status of the Repeat option (1 if set) + +#define IPC_SET_SHUFFLE 252 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE); +// ** +// ** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on) + +#define IPC_SET_REPEAT 253 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT); +// ** +// ** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on) + +#define IPC_GETLISTPOS 125 +// ** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS); +// ** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST +// ** only faster since it doesn't have to write out the list. Heh, silly me. + +#define IPC_GETINFO 126 +// ** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO); +// ** IPC_GETINFO returns info about the current playing song. The value +// ** it returns depends on the value of 'mode'. +// ** Mode Meaning +// ** ------------------ +// ** 0 Samplerate (i.e. 44100) +// ** 1 Bitrate (i.e. 128) +// ** 2 Channels (i.e. 2) + +#define IPC_PLAYFILE 100 +// ** COPYDATASTRUCT cds; +// ** cds.dwData = IPC_PLAYFILE; +// ** cds.lpData = (void *) "file.mp3"; +// ** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char +// ** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds); +// ** +// ** This will play the file "file.mp3". + +#define IPC_ISPLAYING 104 +// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING); +// ** IPC_ISPLAYING returns the status of playback. +// ** If it returns 1, it is playing. if it returns 3, it is paused, +// ** if it returns 0, it is not playing. + +// The following stuff needs PostMessage(hwnd_winamp,WM_COMMAND,id,0); +#define WINAMP_BUTTON1 40044 +#define WINAMP_BUTTON2 40045 +#define WINAMP_BUTTON3 40046 +#define WINAMP_BUTTON4 40047 +#define WINAMP_BUTTON5 40048 + +#define WINAMP_CMD_PREV WINAMP_BUTTON1 +#define WINAMP_CMD_PLAY WINAMP_BUTTON2 +#define WINAMP_CMD_PAUSE WINAMP_BUTTON3 +#define WINAMP_CMD_STOP WINAMP_BUTTON4 +#define WINAMP_CMD_NEXT WINAMP_BUTTON5 + +#define WINAMP_CMD_QUIT 40001 + +#define KVIRC_WM_USER 63112 + +#define KVIRC_WM_USER_CHECK 13123 +#define KVIRC_WM_USER_CHECK_REPLY 13124 +#define KVIRC_WM_USER_GETTITLE 5000 +#define KVIRC_WM_USER_GETFILE 10000 +#define KVIRC_WM_USER_TRANSFER 15000 + + +static QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding)); + if(!c)c = QTextCodec::codecForLocale(); + return c; + +} + +static HWND find_winamp(KviWinampInterface * i) +{ + HWND hWnd = FindWindow("Winamp v1.x",NULL); + if(!hWnd) + { + // try to start the process ? + i->setLastError(__tr2qs_ctx("Can't find a running winamp window","mediaplayer")); + } + return hWnd; +} + + +MP_IMPLEMENT_DESCRIPTOR( + KviWinampInterface, + "winamp", + __tr2qs_ctx( + "An interface to the popupar Winamp media player.\n" \ + "You can download it from http://www.winamp.com.\n" \ + "To use all the features of this interface you must " \ + "copy the gen_kvirc.dll plugin found in the KVIrc " \ + "distribution directory to the Winamp plugins folder " \ + "and restart winamp." + , + "mediaplayer" + ) +) + + +KviWinampInterface::KviWinampInterface() +: KviMediaPlayerInterface() +{ +} + +KviWinampInterface::~KviWinampInterface() +{ +} + + +int KviWinampInterface::detect(bool bStart) +{ + if(find_winamp(this))return 80; + // FIXME : check for Programs Folder\Winamp\Winamp.exe ? + // FIXME : if bStart try to start winamp.exe ? + return 50; +} + +#define MP_WINAMP_SENDMESSAGE(__cmdname,__wmmsg,__lparam,__wparam) \ + bool KviWinampInterface::__cmdname() \ + { \ + HWND hWinamp = find_winamp(this); \ + if(hWinamp)SendMessage(hWinamp,__wmmsg,__lparam,__wparam); \ + return hWinamp != 0; \ + } + +#define MP_WINAMP_WM_USER(__cmdname,_ipcmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_USER,0,_ipcmsg) +#define MP_WINAMP_WM_COMMAND(__cmdname,_cmdmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_COMMAND,_cmdmsg,0) + +MP_WINAMP_WM_USER(play,IPC_STARTPLAY) +MP_WINAMP_WM_COMMAND(stop,WINAMP_CMD_STOP) +MP_WINAMP_WM_COMMAND(next,WINAMP_CMD_NEXT) +MP_WINAMP_WM_COMMAND(prev,WINAMP_CMD_PREV) +MP_WINAMP_WM_COMMAND(pause,WINAMP_CMD_PAUSE) +MP_WINAMP_WM_COMMAND(quit,WINAMP_CMD_QUIT) + + +int KviWinampInterface::length() +{ + int leninsecs = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)leninsecs = SendMessage(hWinamp,WM_USER,1,IPC_GETOUTPUTTIME); + return leninsecs * 1000; +} + +int KviWinampInterface::position() +{ + int leninmsecs = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)leninmsecs = SendMessage(hWinamp,WM_USER,0,IPC_GETOUTPUTTIME); + return leninmsecs; +} + +int KviWinampInterface::bitRate() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,1,IPC_GETINFO); + return ret; +} + +int KviWinampInterface::sampleRate() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_GETINFO); + return ret; +} + +int KviWinampInterface::channels() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETINFO); + return ret; +} + +KviMediaPlayerInterface::PlayerStatus KviWinampInterface::status() +{ + HWND hWinamp = find_winamp(this); + int ret = 1000; + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_ISPLAYING); + 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; +} + +QString KviWinampInterface::mrl() +{ + QString ret; + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + int ret2 = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); + + if(ret2 =! KVIRC_WM_USER_CHECK_REPLY) + { + setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer")); + return ret; + } + + int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETFILE); + + if(len < 4096) + { + char szBuffer[4096]; + + for(int i = 0;i < len;i++) + { + szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); + } + szBuffer[len] = '\0'; + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(szBuffer); + else ret=szBuffer; + if(!ret.startsWith("http://",false)) + ret.prepend("file://"); + } + } + return ret; +} + +QString KviWinampInterface::nowPlaying() +{ + QString ret; + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + int retpippo = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); + if(retpippo =! KVIRC_WM_USER_CHECK_REPLY) + { + setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer") ); + return ret; + } + + int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETTITLE); + + if(len < 4096) + { + char szBuffer[4096]; + + for(int i = 0;i < len;i++) + { + szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); + } + szBuffer[ len ] = '\0'; + + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(szBuffer); + else ret=szBuffer; + } + } + return ret; +} + +bool KviWinampInterface::playMrl(const QString &mrl) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + QTextCodec *c=mediaplayer_get_codec(); + KviStr szMrl = c ? c->fromUnicode(mrl) : mrl.utf8(); + COPYDATASTRUCT cds; + cds.dwData = IPC_PLAYFILE; + cds.lpData = (void *)szMrl.ptr(); + cds.cbData = szMrl.len() + 1; // include space for null char + SendMessage(hWinamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM) &cds); + return true; + } + return false; +} + +bool KviWinampInterface::setVol(kvs_int_t &iVol) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iVol,IPC_SETVOLUME); + return true; + } + return false; +} + +int KviWinampInterface::getVol() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,-666,IPC_SETVOLUME); + return ret; +} + +bool KviWinampInterface::jumpTo(kvs_int_t &iPos) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_JUMPTOTIME); + return true; + } + return false; +} +bool KviWinampInterface::hide() +{ + HWND hWinamp = find_winamp(this); + HWND hWinampPE = FindWindow("Winamp PE",NULL); /*Playlist*/ + HWND hWinampEQ = FindWindow("Winamp EQ",NULL); /*Equalizer*/ + HWND hWinampMB = FindWindow("Winamp MB",NULL); /*MiniBrowser*/ + HWND hWinampGen = FindWindow("Winamp Gen",NULL); /*Library*/ + HWND hWinampVideo = FindWindow("Winamp Video",NULL); /*Video*/ + if(hWinamp) + { + ShowWindow(hWinamp, SW_HIDE); + if(hWinampPE || hWinampEQ || hWinampMB || hWinampGen || hWinampVideo ) + { + if(hWinampPE) + ShowWindow(hWinampPE, SW_HIDE); + if(hWinampEQ) + ShowWindow(hWinampEQ, SW_HIDE); + if(hWinampMB) + ShowWindow(hWinampMB, SW_HIDE); + if(hWinampGen) + ShowWindow(hWinampGen, SW_HIDE); + if(hWinampVideo) + ShowWindow(hWinampVideo, SW_HIDE); + return true; + } + return true; + } + return false; +} + +bool KviWinampInterface::show() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + ShowWindow(hWinamp, SW_SHOW); + return true; + } + return false; +} + +bool KviWinampInterface::minimize() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + ShowWindow(hWinamp, SW_SHOWMINIMIZED); + return true; + } + return false; +} + +bool KviWinampInterface::setPlayListPos(int &iPos) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_SETPLAYLISTPOS); + return true; + } + return false; +} + +int KviWinampInterface::getPlayListPos() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTPOS); + return ret; +} + +int KviWinampInterface::getListLength() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTLENGTH); + return ret; +} + +bool KviWinampInterface::setEqData(int &iPos, int &iVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_GETEQDATA); + SendMessage(hWinamp,WM_USER,iVal,IPC_SETEQDATA); + return true; + } + return false; +} + +int KviWinampInterface::getEqData(int &ival) +{ + HWND hWinamp = find_winamp(this); + int ret = -1; + if(hWinamp) + { + ret = SendMessage(hWinamp,WM_USER,ival,IPC_GETEQDATA); + return ret; + } + return ret; +} + +bool KviWinampInterface::getRepeat() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bRepeat = SendMessage(hWinamp,WM_USER,0,IPC_GET_REPEAT); + return bRepeat; + } + return false; +} + +bool KviWinampInterface::getShuffle() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bShuffle = SendMessage(hWinamp,WM_USER,0,IPC_GET_SHUFFLE); + return bShuffle; + } + return false; +} + +bool KviWinampInterface::setShuffle(bool &bVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bRepeat = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_SHUFFLE); + return bRepeat; + } + return false; +} + +bool KviWinampInterface::setRepeat(bool &bVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bShuffle = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_REPEAT); + return bShuffle; + } + return false; +} +#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_winampinterface.h b/src/modules/mediaplayer/mp_winampinterface.h new file mode 100644 index 00000000..ed2068db --- /dev/null +++ b/src/modules/mediaplayer/mp_winampinterface.h @@ -0,0 +1,76 @@ +#ifndef _MP_WINAMPINTERFACE_H_ +#define _MP_WINAMPINTERFACE_H_ +//============================================================================= +// +// File : mp_winampinterface.h +// Created on Mon 28 Mar 2005 23:41:50 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#ifdef COMPILE_ON_WINDOWS + + #include "mp_interface.h" + + class KviWinampInterface : public KviMediaPlayerInterface + { + public: + KviWinampInterface(); + ~KviWinampInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual QString nowPlaying(); + virtual QString mrl(); + virtual int position(); + virtual int length(); + virtual bool playMrl(const QString &mrl); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual int sampleRate(); + virtual int bitRate(); + virtual int channels(); + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + virtual int getPlayListPos(); + virtual bool setPlayListPos(int &iPos); + virtual int getListLength(); + virtual int getEqData(int &ival); + virtual bool setEqData(int &iPos, int &iVal); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + virtual KviMediaPlayerInterface::PlayerStatus status(); + }; + + MP_DECLARE_DESCRIPTOR(KviWinampInterface) + +#endif //COMPILE_ON_WINDOWS + +#endif //!_MP_WINAMPINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_xmmsinterface.cpp b/src/modules/mediaplayer/mp_xmmsinterface.cpp new file mode 100644 index 00000000..532327af --- /dev/null +++ b/src/modules/mediaplayer/mp_xmmsinterface.cpp @@ -0,0 +1,355 @@ +//============================================================================= +// +// File : mp_xmmsinterface.cpp +// Created on Fri 25 Mar 2005 20:04:54 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2007 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// Thnx to Alexander Stillich <torque at pltn dot org> for Audacious +// media player interface hints :) +// +//============================================================================= + +#include "mp_xmmsinterface.h" + +#ifndef COMPILE_ON_WINDOWS + +#include "kvi_locale.h" + +MP_IMPLEMENT_DESCRIPTOR( + KviXmmsInterface, + "xmms", + __tr2qs_ctx( + "An interface to the popular UNIX xmms media player.\n" \ + "Download it from http://www.xmms.org\n" + , + "mediaplayer" + ) +) + +MP_IMPLEMENT_DESCRIPTOR( + KviAudaciousInterface, + "audacious", + __tr2qs_ctx( + "An interface to the popular UNIX audacious media player.\n" \ + "Download it from http://audacious-media-player.org\n" + , + "mediaplayer" + ) +) + +static const char *xmms_lib_names[] = +{ + "libxmms.so", + "libxmms.so.1", + "/usr/lib/libxmms.so", + "/usr/lib/libxmms.so.1", + "/usr/local/lib/libxmms.so", + "/usr/local/lib/libxmms.so.1", + 0 +}; + +static const char *audacious_lib_names[] = +{ + "libaudacious.so", + "libaudacious.so.4", + "/usr/lib/libaudacious.so", + "/usr/lib/libaudacious.so.4", + "/usr/local/lib/libaudacious.so", + "/usr/local/lib/libaudacious.so.4", + 0 +}; + + + +KviXmmsInterface::KviXmmsInterface() +: KviMediaPlayerInterface() +{ + m_hPlayerLibrary = 0; + m_szPlayerLibraryName = "libxmms.so"; + m_pLibraryPaths = xmms_lib_names; +} + +KviXmmsInterface::~KviXmmsInterface() +{ + if(m_hPlayerLibrary) + { + kvi_library_close(m_hPlayerLibrary); + m_hPlayerLibrary = 0; + } +} + +KviAudaciousInterface::KviAudaciousInterface() +: KviXmmsInterface() +{ + m_szPlayerLibraryName = "libaudacious.so"; + m_pLibraryPaths = audacious_lib_names; +} + +KviAudaciousInterface::~KviAudaciousInterface() +{ +} + +bool KviXmmsInterface::loadPlayerLibrary() +{ + if(m_hPlayerLibrary)return true; + + const char **lib_name = m_pLibraryPaths; + while(*lib_name) + { + m_hPlayerLibrary = kvi_library_load(*lib_name); + if(m_hPlayerLibrary) + { + m_szPlayerLibraryName = *lib_name; + break; + } + lib_name++; + } + return true; +} + +void * KviXmmsInterface::lookupSymbol(const char * szSymbolName) +{ + if(!m_hPlayerLibrary) + { + if(!loadPlayerLibrary()) + { + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("Can't load the player library (%Q)","mediaplayer"),&m_szPlayerLibraryName); + setLastError(tmp); + return 0; + } + } + void * symptr = kvi_library_symbol(m_hPlayerLibrary,szSymbolName); + if(!symptr) + { + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("Can't find symbol %s in %Q","mediaplayer"),szSymbolName,&m_szPlayerLibraryName); + setLastError(tmp); + } + return symptr; +} + + +int KviXmmsInterface::detect(bool bStart) +{ + void * sym = lookupSymbol("xmms_remote_play"); + return sym ? 80 : 0; +} + +#define XMMS_SIMPLE_CALL(__symname) \ + void (*sym)(int) = (void (*)(int))lookupSymbol(__symname); \ + if(!sym)return false; \ + sym(0); \ + return true; + +bool KviXmmsInterface::prev() +{ + XMMS_SIMPLE_CALL("xmms_remote_playlist_prev") +} + +bool KviXmmsInterface::next() +{ + XMMS_SIMPLE_CALL("xmms_remote_playlist_next") +} + +bool KviXmmsInterface::play() +{ + XMMS_SIMPLE_CALL("xmms_remote_play") +} + +bool KviXmmsInterface::stop() +{ + XMMS_SIMPLE_CALL("xmms_remote_stop") +} + +bool KviXmmsInterface::pause() +{ + XMMS_SIMPLE_CALL("xmms_remote_pause") +} + +bool KviXmmsInterface::quit() +{ + XMMS_SIMPLE_CALL("xmms_remote_quit") +} + +bool KviXmmsInterface::jumpTo(kvs_int_t &iPos) +{ + void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_jump_to_time"); + if(!sym)return false; + sym(0,iPos); + return true; +} + +bool KviXmmsInterface::setVol(kvs_int_t &iVol) +{ + void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_main_volume"); + if(!sym)return false; + sym(0,100*iVol/255); + return true; +} + +int KviXmmsInterface::getVol() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_main_volume"); + if(!sym)return -1; + int iVol = sym(0); + return iVol * 255 /100; +} + +bool KviXmmsInterface::getRepeat() +{ + bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); + if(!sym)return false; + bool ret = sym(0); + return ret; +} + +bool KviXmmsInterface::setRepeat(bool &bVal) +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); + if(!sym1)return false; + bool bNow = sym1(0); + if(bNow != bVal) + { + void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_repeat"); + if(!sym2)return false; + sym2(0); + } + return true; +} + +bool KviXmmsInterface::getShuffle() +{ + bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); + if(!sym)return false; + bool ret = sym(0); + return ret; +} + +bool KviXmmsInterface::setShuffle(bool &bVal) +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); + if(!sym1)return false; + bool bNow = sym1(0); + if(bNow != bVal) + { + void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_shuffle"); + if(!sym2)return false; + sym2(0); + } + return true; +} + +KviMediaPlayerInterface::PlayerStatus KviXmmsInterface::status() +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_paused"); + if(sym1) + { + if(sym1(0))return KviMediaPlayerInterface::Paused; + bool (*sym2)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_playing"); + if(sym2) + { + if(sym2(0))return KviMediaPlayerInterface::Playing; + else return KviMediaPlayerInterface::Stopped; + } + } + + return KviMediaPlayerInterface::Unknown; +} + +bool KviXmmsInterface::playMrl(const QString &mrl) +{ + void (*sym)(int,char *) = (void (*)(int,char *))lookupSymbol("xmms_remote_playlist_add_url_string"); + KviQCString tmp = mrl.local8Bit(); + if(!tmp.isEmpty()) + { + if(sym) + { + sym(0,tmp.data()); + int (*sym1)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_length"); + if(sym1) + { + int len = sym1(0); + if(len > 0) + { + void (*sym2)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_playlist_pos"); + if(sym2) + { + sym2(0,len - 1); + } else return false; + } else return false; + } else return false; + } else return false; + } + return true; +} + +QString KviXmmsInterface::nowPlaying() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return QString::null; + int pos = sym(0); + char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_title"); + if(!sym2)return QString::null; + return QString::fromLocal8Bit(sym2(0,pos)); +} + +QString KviXmmsInterface::mrl() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return QString::null; + int pos = sym(0); + char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_file"); + if(!sym2)return QString::null; + QString ret = QString::fromLocal8Bit(sym2(0,pos)); + if(ret.length() > 1) + if(ret[0] == '/')ret.prepend("file://"); + return ret; +} + +int KviXmmsInterface::position() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + int pos = sym(0); + int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_output_time"); + if(!sym2)return -1; + return sym2(0,pos); +} + +int KviXmmsInterface::length() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + int pos = sym(0); + int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_playlist_time"); + if(!sym2)return -1; + return sym2(0,pos); +} + +int KviXmmsInterface::getPlayListPos() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + return sym(0); +} + + + +#endif //!COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_xmmsinterface.h b/src/modules/mediaplayer/mp_xmmsinterface.h new file mode 100644 index 00000000..15f81811 --- /dev/null +++ b/src/modules/mediaplayer/mp_xmmsinterface.h @@ -0,0 +1,84 @@ +#ifndef _MP_XMMSINTERFACE_H_ +#define _MP_XMMSINTERFACE_H_ +//============================================================================= +// +// File : mp_xmmsinterface.h +// Created on Fri 25 Mar 2005 20:04:54 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2007 Szymon Stefanek <pragma at kvirc dot net> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// Thnx to Alexander Stillich <torque at pltn dot org> for Audacious +// media player interface hints :) +// +//============================================================================= + +#include "kvi_settings.h" +#include "mp_interface.h" +#include "kvi_library.h" + +#ifndef COMPILE_ON_WINDOWS + class KviXmmsInterface : public KviMediaPlayerInterface + { + public: + KviXmmsInterface(); + virtual ~KviXmmsInterface(); + protected: + kvi_library_t m_hPlayerLibrary; + QString m_szPlayerLibraryName; + const char ** m_pLibraryPaths; + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual KviMediaPlayerInterface::PlayerStatus status(); + virtual QString nowPlaying(); + virtual bool playMrl(const QString &mrl); + virtual QString mrl(); + virtual int getPlayListPos(); + virtual int position(); + virtual int length(); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + protected: + bool loadPlayerLibrary(); + void * lookupSymbol(const char * szSymbolName); + }; + + MP_DECLARE_DESCRIPTOR(KviXmmsInterface) + + class KviAudaciousInterface : public KviXmmsInterface + { + public: + KviAudaciousInterface(); + virtual ~KviAudaciousInterface(); + }; + + MP_DECLARE_DESCRIPTOR(KviAudaciousInterface) + +#endif //!COMPILE_ON_WINDOWS + +#endif //!_MP_XMMSINTERFACE_H_ |