/*************************************************************************** artsplayer.cpp ------------------- begin : Tue Dec 02 2003 copyright : (C) 2003 by Luis De la Parra email : yammi-developer@lists.sourceforge.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. * * * ***************************************************************************/ #include "artsplayer.h" #include #include #include #include #include #include "songentry.h" #include "songentryint.h" namespace Yammi { ArtsPlayer::ArtsPlayer(YammiModel *yammi) : MediaPlayer(yammi) { kdDebug() << "ArtsPlayer::ArtsPlayer(YammiModel *yammi)" << endl; m_dispatcher = new KArtsDispatcher( ); kdDebug() << "creating KArtsServer...\n"; m_server = new KArtsServer( ); if(m_server == 0) { kdError() << "ERROR: could not create KArtsServer\n"; return; } Arts::SoundServerV2 server = m_server->server(); if(server.isNull()) { kdError() << "ERROR: could not get server from KArtsServer\n"; return; } kdDebug() << "creating PlayObjectFactory...\n"; m_factory = new KDE::PlayObjectFactory( server ); kdDebug() << "...done\n"; m_currentPlay = 0; m_currentSong = 0; } bool ArtsPlayer::finishInitialization() { return true; } ArtsPlayer::~ArtsPlayer() { kdDebug() << "---ArtsPlayer::~ArtsPlayer(YammiModel *yammi)" << endl; quit( ); delete m_factory; delete m_server; delete m_dispatcher; } void ArtsPlayer::check() { PlayerStatus s = getStatus( ); if( s != status ) { if( status == PLAYING && s == STOPPED ) { if( m_currentSong == playlist->firstSong() ) { kdDebug() << "Song finished... get new one!" << endl; playlist->removeFirst( ); delete m_currentPlay; m_currentPlay = 0; m_currentSong = 0; emit playlistChanged( ); } // if there are more songs in yammi's list, play them play( ); } status = s; emit statusChanged( ); } } PlayerStatus ArtsPlayer::getStatus() { if(!m_currentPlay) return STOPPED; switch( m_currentPlay->state() ) { case Arts::posIdle: return STOPPED; case Arts::posPaused: return PAUSED; case Arts::posPlaying: return PLAYING; } return STOPPED; // shut up compiler warnings } void ArtsPlayer::clearPlaylist() { emit playlistChanged( ); } bool ArtsPlayer::play() { if( m_currentPlay ) { if( m_currentPlay->state() != Arts::posPlaying ) { m_currentPlay->play( ); } status = getStatus(); emit statusChanged(); return true; } return false; } bool ArtsPlayer::pause() { if( m_currentPlay && m_currentPlay->state() == Arts::posPlaying ) { m_currentPlay->pause(); } status = getStatus( ); emit statusChanged( ); return true; } bool ArtsPlayer::stop() { pause(); jumpTo(0); /* if( m_currentPlay && m_currentPlay->state() != Arts::posIdle ) { m_currentPlay->halt(); } status = getStatus( ); emit statusChanged( );*/ return true; } bool ArtsPlayer::playPause() { if( !m_currentPlay ) { play( ); //start new play } else if( m_currentPlay && m_currentPlay->state() == Arts::posPlaying ) { m_currentPlay->pause(); } else if ( m_currentPlay && ( m_currentPlay->state() == Arts::posPaused || m_currentPlay->state( ) == Arts::posIdle ) ) { m_currentPlay->play(); } status = getStatus( ); emit statusChanged( ); return true; } bool ArtsPlayer::skipForward(bool) { if( playlist->count() < 2 ) { // there is no "next song" return false; } int savedStatus = getStatus(); if( m_currentPlay ) { if(m_currentPlay->state() != Arts::posIdle ) { m_currentPlay->halt(); } delete m_currentPlay; m_currentPlay = 0; } m_currentSong = 0; // remove the first song and sync playlist again playlist->removeFirst( ); syncYammi2Player(); emit playlistChanged(); if(!m_currentSong) { return false; } if(savedStatus == PLAYING) { play(); } return true; } bool ArtsPlayer::skipBackward(bool withoutCrossfading) { Song* last=playlist->at(0)->song(); // insert pseudo-song to be removed playlist->insert(0, new SongEntryInt(last, 0)); return skipForward(withoutCrossfading); } void ArtsPlayer::syncYammi2Player() { kdDebug() << "ArtsPlayer::syncYammi2Player()" << endl; bool haveToUpdate=model->skipUnplayableSongs(); if(playlist->count()==0) { if( m_currentPlay && m_currentPlay->state() != Arts::posIdle ) { m_currentPlay->halt(); } delete m_currentPlay; m_currentPlay = 0; m_currentSong = 0; if(haveToUpdate) { emit playlistChanged(); } return; } if(m_currentSong != 0) { kdDebug() << "m_currentSong: " << m_currentSong->displayName() << endl; } if(playlist->count() > 0) { kdDebug() << "playlist->at(0): " << playlist->at(0)->song()->displayName() << endl; } if(m_currentSong == playlist->at(0)->song()) { if(haveToUpdate) { emit playlistChanged(); } return; } if( m_currentPlay ) { if (m_currentPlay->state() != Arts::posIdle ) { m_currentPlay->halt(); } delete m_currentPlay; m_currentPlay = 0; } m_currentSong = 0; QString location = model->checkAvailability( playlist->at(0)->song() ); kdDebug() << "returned location: " << location << endl; m_currentSong = playlist->at(0)->song(); KURL url; url.setPath(location); if(!url.isValid()) { kdDebug() << "ERROR: url not valid: " << url << endl; return; } m_currentPlay = m_factory->createPlayObject( url, true ); kdDebug() << "ArtsPlayer::PlayObject created" << endl; // these 2 lines ensure that totalTime() returns meaningful values // (otherwise, totalTime() seems to return 0 as long as song has not started playing yet) m_currentPlay->play(); m_currentPlay->pause(); kdDebug() << "ArtsPlayer:: play/pause done (for initializing totalTime())" << endl; if(haveToUpdate) { emit playlistChanged(); } kdDebug() << "...ArtsPlayer::syncYammi2Player() done" << endl; return; } bool ArtsPlayer::jumpTo(int value) { kdDebug() << "ArtsPlayer::jumpTo\n"; if( !m_currentPlay) { return false; } if( value < 0 || value > getTotalTime() ) { return false; } status = getStatus(); Arts::poTime t; t.seconds = value / 1000; t.ms = value % 1000; m_currentPlay->seek( t ); return true; } QString ArtsPlayer::getCurrentFile() { if( m_currentSong ) { return model->checkAvailability( m_currentSong ); } else { return ""; } } int ArtsPlayer::getCurrentTime() { if( m_currentPlay ) { return m_currentPlay->currentTime().seconds * 1000 + m_currentPlay->currentTime().ms; } return 0; } int ArtsPlayer::getTotalTime() { if( m_currentPlay ) { return m_currentPlay->overallTime().seconds * 1000 + m_currentPlay->overallTime().ms; } return 0; } void ArtsPlayer::quit() { if(m_currentPlay) { if(m_currentPlay->state() != Arts::posIdle ) { m_currentPlay->halt( ); } delete m_currentPlay; m_currentPlay = 0; } } };