1 /***************************************************************************
2 * Copyright (C) 2007 by Pino Toscano <pino@kde.org> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 ***************************************************************************/
10 #include "audioplayer.h"
11 #include "audioplayer_p.h"
18 #include <Phonon/Path>
19 #include <phonon/audiooutput.h>
20 #include <phonon/abstractmediastream.h>
21 #include <phonon/mediaobject.h>
28 using namespace Okular
;
30 // helper class used to store info about a sound to be played
34 explicit SoundInfo( const Sound
* s
= 0, const SoundAction
* ls
= 0 )
35 : sound( s
), volume( 0.5 ), synchronous( false ), repeat( false ),
40 volume
= ls
->volume();
41 synchronous
= ls
->synchronous();
42 repeat
= ls
->repeat();
59 : m_mediaobject( 0 ), m_output( 0 ), m_buffer( 0 )
67 m_buffer
->open( QIODevice::ReadOnly
);
69 m_mediaobject
->play();
74 m_mediaobject
->stop();
80 Phonon::MediaObject
* m_mediaobject
;
81 Phonon::AudioOutput
* m_output
;
87 AudioPlayerPrivate::AudioPlayerPrivate( AudioPlayer
* qq
)
90 QObject::connect( &m_mapper
, SIGNAL( mapped( int ) ), q
, SLOT( finished( int ) ) );
93 AudioPlayerPrivate::~AudioPlayerPrivate()
98 int AudioPlayerPrivate::newId() const
101 QHash
< int, PlayData
* >::const_iterator it
;
102 QHash
< int, PlayData
* >::const_iterator itEnd
= m_playing
.constEnd();
105 newid
= KRandom::random();
106 it
= m_playing
.constFind( newid
);
107 } while ( it
!= itEnd
);
111 bool AudioPlayerPrivate::play( const SoundInfo
& si
)
114 PlayData
* data
= new PlayData();
115 data
->m_output
= new Phonon::AudioOutput( Phonon::NotificationCategory
);
116 data
->m_output
->setVolume( si
.volume
);
117 data
->m_mediaobject
= new Phonon::MediaObject();
118 Phonon::createPath(data
->m_mediaobject
, data
->m_output
);
122 switch ( si
.sound
->soundType() )
124 case Sound::External
:
126 QString url
= si
.sound
->url();
127 kDebug(OkularDebug
) << "External," << url
;
128 if ( !url
.isEmpty() )
131 m_mapper
.setMapping( data
->m_mediaobject
, newid
);
133 if ( KUrl::isRelativeUrl( url
) )
135 newurl
= m_currentDocument
;
136 newurl
.setFileName( url
);
142 data
->m_mediaobject
->setCurrentSource( newurl
);
143 m_playing
.insert( newid
, data
);
148 case Sound::Embedded
:
150 QByteArray filedata
= si
.sound
->data();
151 kDebug(OkularDebug
) << "Embedded," << filedata
.length();
152 if ( !filedata
.isEmpty() )
154 kDebug(OkularDebug
) << "Mediaobject:" << data
->m_mediaobject
;
156 m_mapper
.setMapping( data
->m_mediaobject
, newid
);
157 data
->m_buffer
= new QBuffer();
158 data
->m_buffer
->setData( filedata
);
159 data
->m_mediaobject
->setCurrentSource( Phonon::MediaSource( data
->m_buffer
) );
160 m_playing
.insert( newid
, data
);
173 QObject::connect( data
->m_mediaobject
, SIGNAL( finished() ), &m_mapper
, SLOT( map() ) );
174 kDebug(OkularDebug
) << "PLAY";
180 void AudioPlayerPrivate::stopPlayings()
182 qDeleteAll( m_playing
);
186 void AudioPlayerPrivate::finished( int id
)
188 QHash
< int, PlayData
* >::iterator it
= m_playing
.find( id
);
189 if ( it
== m_playing
.end() )
192 SoundInfo si
= it
.value()->m_info
;
193 // if the sound must be repeated indefinitely, then start the playback
194 // again, otherwise destroy the PlayData as it's no more useful
202 m_playing
.erase( it
);
204 kDebug(OkularDebug
) << "finished," << m_playing
.count();
208 AudioPlayer::AudioPlayer()
209 : QObject(), d( new AudioPlayerPrivate( this ) )
213 AudioPlayer::~AudioPlayer()
218 AudioPlayer
* AudioPlayer::instance()
220 static AudioPlayer ap
;
224 void AudioPlayer::playSound( const Sound
* sound
, const SoundAction
* linksound
)
226 // we can't play null pointers ;)
230 // we don't play external sounds for remote documents
231 if ( sound
->soundType() == Sound::External
&& !d
->m_currentDocument
.isLocalFile() )
235 SoundInfo
si( sound
, linksound
);
237 // if the mix flag of the new sound is false, then the currently playing
238 // sounds must be stopped.
245 void AudioPlayer::stopPlaybacks()
250 #include "audioplayer.moc"