player.cpp
来自「这是一个mp3的源代码」· C++ 代码 · 共 1,991 行 · 第 1/4 页
CPP
1,991 行
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Portions Copyright (C) 1998-1999 EMusic.com
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.
$Id: player.cpp,v 1.172 2000/01/20 00:48:45 robert Exp $
____________________________________________________________________________*/
#include <iostream.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef WIN32
#include <direct.h>
#define MKDIR(z) mkdir(z)
#else
#define MKDIR(z) mkdir(z, 0755)
#endif
#include "config.h"
#include "event.h"
#include "lmc.h"
#include "player.h"
#include "thread.h"
#include "debug.h"
#include "ui.h"
#include "queue.h"
#include "semaphore.h"
#include "eventdata.h"
#include "registrar.h"
#include "preferences.h"
#include "properties.h"
#include "facontext.h"
#include "log.h"
#include "pmo.h"
#include "utility.h"
#include "downloadmanager.h"
#define DB Debug_v("%s:%d\n", __FILE__, __LINE__);
Player *Player::m_thePlayer = NULL;
const char *szPlaylistExt = ".M3U";
const char *themeExtension = "fat";
#define SEND_NORMAL_EVENT(e) { Event *ev = new Event(e); GetUIManipLock(); \
SendToUI(ev); ReleaseUIManipLock(); delete ev; \
}
Player *
Player::
GetPlayer(FAContext *context)
{
if (m_thePlayer == NULL)
m_thePlayer = new Player(context);
return m_thePlayer;
}
Player::
Player(FAContext *context):
EventQueue()
{
m_context = context;
m_context->player = this;
// cout << "Creating player..." << endl;
m_eventSem = new Semaphore();
m_eventQueue = new Queue < Event * >();
// cout << "Created queue" << endl;
m_eventServiceThread = NULL;
// cout << "Started event thread" << endl;
m_uiList = new vector < UserInterface * >;
// cout << "Created Lists" << endl;
m_uiManipLock = new Mutex();
m_lmcMutex = new Mutex();
m_pmiMutex = new Mutex();
m_pmoMutex = new Mutex();
m_uiMutex = new Mutex();
// cout << "Created mutex" << endl;
m_imQuitting = 0;
m_quitWaitingFor = 0;
m_plm = new PlaylistManager(m_context);
m_playerState = PlayerState_Stopped;
m_lmcRegistry = NULL;
m_pmiRegistry = NULL;
m_pmoRegistry = NULL;
m_uiRegistry = NULL;
m_lmcExtensions = NULL;
m_browserUI = NULL;
m_downloadUI = NULL;
m_pmo = NULL;
m_lmc = NULL;
m_ui = NULL;
m_argUIList = new vector < char *>();
m_argc = 0;
m_argv = NULL;
m_pTermSem = NULL;
m_didUsage = false;
m_autoplay = true;
m_props.RegisterPropertyWatcher("pcm_volume", (PropertyWatcher *) this);
m_context->plm = m_plm;
m_context->props = &m_props;
m_context->target = (EventQueue *) this;
m_musicCatalog = new MusicCatalog(m_context);
m_context->catalog = m_musicCatalog;
// make sure the db dir exists so we have a place to store our
// stuff
char* tempDir = new char[_MAX_PATH];
uint32 length = _MAX_PATH;
struct stat st;
m_context->prefs->GetPrefString(kDatabaseDirPref, tempDir, &length);
if(-1 == stat(tempDir, &st))
{
MKDIR(tempDir);
}
string freeampdir = tempDir;
freeampdir += DIR_MARKER_STR;
freeampdir += "metadatabase";
m_musicCatalog->SetDatabase(freeampdir.c_str());
// make sure the music dir exists so we have a place to store our
// stuff
length = _MAX_PATH;
m_context->prefs->GetPrefString(kSaveMusicDirPref, tempDir, &length);
if(-1 == stat(tempDir, &st))
{
MKDIR(tempDir);
}
delete [] tempDir;
m_dlm = new DownloadManager(m_context);
m_context->downloadManager = m_dlm;
}
#define TYPICAL_DELETE(x) /*printf("deleting...\n");*/ if (x) { delete x; x = NULL; }
Player::
~Player()
{
TYPICAL_DELETE(m_dlm);
TYPICAL_DELETE(m_pTermSem);
if(m_argUIList)
{
vector<char*>::iterator i = m_argUIList->begin();
for (; i != m_argUIList->end(); i++)
delete [] *i;
delete m_argUIList;
m_argUIList = NULL;
}
if(m_eventServiceThread)
{
m_eventServiceThread->Join();
delete m_eventServiceThread;
m_eventServiceThread = NULL;
}
if(m_pmo)
{
m_pmo->Pause();
delete m_pmo;
m_pmo = NULL;
}
TYPICAL_DELETE(m_eventSem);
TYPICAL_DELETE(m_eventQueue);
// Delete CIOs
if(m_uiList)
{
vector<UserInterface *>::iterator i = m_uiList->begin();
for (; i != m_uiList->end(); i++)
delete *i;
delete m_uiList;
m_uiList = NULL;
}
TYPICAL_DELETE(m_plm);
TYPICAL_DELETE(m_uiManipLock);
TYPICAL_DELETE(m_lmcMutex);
TYPICAL_DELETE(m_pmiMutex);
TYPICAL_DELETE(m_pmoMutex);
TYPICAL_DELETE(m_uiMutex);
TYPICAL_DELETE(m_lmcRegistry);
TYPICAL_DELETE(m_pmiRegistry);
TYPICAL_DELETE(m_pmoRegistry);
TYPICAL_DELETE(m_uiRegistry);
TYPICAL_DELETE(m_lmcExtensions);
TYPICAL_DELETE(m_musicCatalog);
}
void
Player::
SetTerminationSemaphore(Semaphore * pSem)
{
m_pTermSem = pSem;
}
/*
return true if parsing was successful, false otherwise.
*/
typedef char *pchar;
bool
Player::
SetArgs(int32 argc, char **argv)
{
bool autoplay = false;
char* path = new char[_MAX_PATH];
char* url = new char[_MAX_PATH];
// remember these guys so we can use them later and elsewhere
m_argc = argc;
m_argv = argv;
m_context->argv = m_argv;
m_context->argc = m_argc;
// now parse them and pull out any args we know about
for (int32 i = 1; i < argc; i++)
{
char* arg = argv[i];
// is this an option?
if(arg[0] == '-'
#ifdef WIN32
|| arg[0] == '/'
#endif
)
{
switch(arg[1])
{
// print help
case 'h':
case 'H':
case '-':
if(!strcasecmp(arg + 1, "help") || !strcasecmp(arg + 2, "help"))
{
Usage(argv[0]);
AcceptEvent(new Event(CMD_QuitPlayer));
return true;
}
break;
// autoplay
case 'p':
case 'P':
if(!strcasecmp(arg + 1, "play"))
autoplay = true;
// save streams
// shuffle
case 's':
case 'S':
if(!strcasecmp(arg + 1, "save"))
m_context->argFlags |= FAC_ARGFLAGS_SAVE_STREAMS;
else if(!strcasecmp(arg + 1, "shuffle"))
m_plm->SetShuffleMode(true);
break;
// set UIs
case 'u':
case 'U':
{
if(arg[2] == 'i' || arg[2] == 'I')
{
char* argUI = NULL;
i++;
if(i >= argc)
{
Usage(argv[0]);
AcceptEvent(new Event(CMD_QuitPlayer));
return false;
}
arg = argv[i];
argUI = new char[strlen(arg) + 1];
strcpy(argUI, arg);
m_argUIList->push_back(argUI);
}
break;
}
default:
break;
}
}
else
{
// is this a URL we know how to handle
if( !strncasecmp(arg, "http://", 7) ||
!strncasecmp(arg, "rtp://", 6))
{
m_plm->AddItem(arg);
}
else
{
#ifdef WIN32
strcpy(path, arg);
HANDLE handle;
WIN32_FIND_DATA data;
handle = FindFirstFile(arg, &data);
// find long filename for item and
// expand wildcards...
if(handle != INVALID_HANDLE_VALUE)
{
do
{
char* cp = NULL;
cp = strrchr(path, '\\');
if(cp)
cp++;
else
cp = path;
strcpy(cp, data.cFileName);
// make sure we have an absolute path
ResolvePath(&path);
// format this path as a URL
uint32 length = _MAX_PATH;
FilePathToURL(path, url, &length);
// who needs to get this, plm or dlm?
bool giveToDLM = false;
bool giveToTheme = false;
char* extension = NULL;
extension = strrchr(url, '.');
if(extension)
{
DownloadFormatInfo dlfi;
uint32 i = 0;
extension++;
while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++)))
{
if(!strcasecmp(extension, dlfi.GetExtension()))
{
giveToDLM = true;
break;
}
}
if (strcasecmp(extension, themeExtension) == 0)
giveToTheme = true;
}
if(giveToDLM)
m_dlm->ReadDownloadFile(url);
else
if(giveToTheme)
{
char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH];
uint32 iLen = _MAX_PATH;
m_context->prefs->GetPrefString(kThemePathPref,
szSavedTheme, &iLen);
iLen = _MAX_PATH;
URLToFilePath(url, szNewTheme, &iLen);
m_context->prefs->SetPrefString(kThemePathPref,
szNewTheme);
AcceptEvent(new LoadThemeEvent(url, szSavedTheme));
}
else
m_plm->AddItem(url);
}while(FindNextFile(handle, &data));
FindClose(handle);
}
else // is this a URL we know how to handle ?
{
// file not found? don't add it...
continue;
}
#else
strcpy(path, arg);
//printf("Path: %s\r\n", path);
// make sure we have an absolute path
ResolvePath(&path);
//printf("Resolved: %s\r\n", path);
// format this path as a URL
uint32 length = _MAX_PATH;
FilePathToURL(path, url, &length);
//printf("URL: %s\r\n", url);
// who needs to get this, plm or dlm?
bool giveToDLM = false;
bool giveToTheme = false;
char* extension = NULL;
extension = strrchr(url, '.');
if(extension)
{
DownloadFormatInfo dlfi;
uint32 i = 0;
extension++;
while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++)))
{
if(!strcasecmp(extension, dlfi.GetExtension()))
{
giveToDLM = true;
break;
}
}
if (strcasecmp(extension, themeExtension) == 0)
giveToTheme = true;
}
if (giveToDLM)
m_dlm->ReadDownloadFile(url);
else if (giveToTheme)
{
char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH];
uint32 iLen = _MAX_PATH;
m_context->prefs->GetPrefString(kThemePathPref,
szSavedTheme, &iLen);
iLen = _MAX_PATH;
URLToFilePath(url, szNewTheme, &iLen);
m_context->prefs->SetPrefString(kThemePathPref, szNewTheme);
AcceptEvent(new LoadThemeEvent(url, szSavedTheme));
}
else
{
m_plm->AddItem(url);
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?