void MMF::MediaObject::createPlayer(const MediaSource &source) { TRACE_CONTEXT(MediaObject::createPlayer, EAudioApi); TRACE_ENTRY("state %d source.type %d", state(), source.type()); TRACE_ENTRY("source.type %d", source.type()); MediaType mediaType = MediaTypeUnknown; AbstractPlayer* oldPlayer = m_player.data(); const bool oldPlayerHasVideo = oldPlayer->hasVideo(); const bool oldPlayerSeekable = oldPlayer->isSeekable(); QString errorMessage; // Determine media type switch (source.type()) { case MediaSource::LocalFile: mediaType = fileMediaType(source.fileName()); break; case MediaSource::Url: { const QUrl url(source.url()); if (url.scheme() == QLatin1String("file")) { mediaType = fileMediaType(url.toLocalFile()); } else { // Streaming playback is generally not supported by the implementation // of the audio player API, so we use CVideoPlayerUtility for both // audio and video streaming. mediaType = MediaTypeVideo; } } break; case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: TRACE_0("Empty media source"); break; } if (oldPlayer) oldPlayer->close(); AbstractPlayer* newPlayer = 0; // Construct newPlayer using oldPlayer (if not 0) in order to copy // parameters (volume, prefinishMark, transitionTime) which may have // been set on oldPlayer. switch (mediaType) { case MediaTypeUnknown: TRACE_0("Media type could not be determined"); newPlayer = new DummyPlayer(oldPlayer); errorMessage = tr("Error opening source: media type could not be determined"); break; case MediaTypeAudio: newPlayer = new AudioPlayer(this, oldPlayer); break; case MediaTypeVideo: #ifdef PHONON_MMF_VIDEO_SURFACES newPlayer = SurfaceVideoPlayer::create(this, oldPlayer); #else newPlayer = DsaVideoPlayer::create(this, oldPlayer); #endif break; } if (oldPlayer) emit abstractPlayerChanged(0); m_player.reset(newPlayer); emit abstractPlayerChanged(newPlayer); if (oldPlayerHasVideo != hasVideo()) { emit hasVideoChanged(hasVideo()); } if (oldPlayerSeekable != isSeekable()) { emit seekableChanged(isSeekable()); } connect(m_player.data(), SIGNAL(totalTimeChanged(qint64)), SIGNAL(totalTimeChanged(qint64))); connect(m_player.data(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), SIGNAL(stateChanged(Phonon::State,Phonon::State))); connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished())); connect(m_player.data(), SIGNAL(bufferStatus(int)), SIGNAL(bufferStatus(int))); connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), SIGNAL(metaDataChanged(QMultiMap<QString,QString>))); connect(m_player.data(), SIGNAL(aboutToFinish()), SIGNAL(aboutToFinish())); connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(prefinishMarkReached(qint32))); connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SLOT(handlePrefinishMarkReached(qint32))); connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); // We need to call setError() after doing the connects, otherwise the // error won't be received. if (!errorMessage.isEmpty()) { Q_ASSERT(m_player); m_player->setError(errorMessage); } TRACE_EXIT_0(); }