Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- qandroidmediaplayer.h
- #ifndef QANDROIDMEDIAPLAYER_H
- #define QANDROIDMEDIAPLAYER_H
- #include <QtCore>
- #include <SLES/OpenSLES.h>
- #include <SLES/OpenSLES_Android.h>
- class QAndroidMediaPlayer : public QObject
- {
- Q_OBJECT
- Q_ENUMS(State)
- Q_ENUMS(MediaStatus)
- Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
- Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
- Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged)
- Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
- Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged)
- Q_PROPERTY(State state READ state NOTIFY stateChanged)
- friend void GlobalCallbackPositionChanged(SLPlayItf caller, void *pContext, SLuint32 playevent);
- public:
- explicit QAndroidMediaPlayer(QObject *parent = 0);
- ~QAndroidMediaPlayer();
- enum State {
- StoppedState = 0,
- PlayingState = 1,
- PausedState = 2
- };
- enum MediaStatus {
- EndOfMedia = 7
- };
- bool isMuted() const;
- void setMuted(bool);
- int volume() const;
- void setVolume(int);
- qint64 position() const;
- void setPosition(qint64);
- qint64 duration() const;
- int notifyInterval() const;
- void setNotifyInterval(int);
- State state() const;
- signals:
- void mutedChanged(bool);
- void volumeChanged(int);
- void positionChanged(qint64);
- void durationChanged(qint64);
- void notifyIntervalChanged(int);
- void mediaStatusChanged(int);
- void stateChanged(int);
- public slots:
- void setMedia(const QUrl& media);
- void play();
- void pause();
- void stop();
- private:
- static void checkResult(const SLresult&);
- static void openMusicProfile();
- //void closeMusicProfile();
- void openAudioPlayer(const QUrl& url);
- void closeAudioPlayer();
- void callbackPositionChanged(SLuint32 playevent);
- static SLObjectItf m_engineObj;
- static SLEngineItf m_engineItf;
- static SLObjectItf m_outputObj;
- SLObjectItf m_playerObject;
- SLPlayItf m_playItf;
- SLSeekItf m_SeekItf;
- int m_notifyInterval;
- QAndroidMediaPlayer::State m_state;
- };
- #endif // QANDROIDMEDIAPLAYER_H
- qandroidmediaplayer.cpp
- #include "qandroidmediaplayer.h"
- void GlobalCallbackPositionChanged(SLPlayItf, void *pContext, SLuint32 playevent)
- {
- qDebug() << "GlobalCallbackPositionChanged";
- QAndroidMediaPlayer* player = qobject_cast<QAndroidMediaPlayer*>(pContext);
- if (player) {
- player->callbackPositionChanged(playevent);
- }
- }
- SLObjectItf QAndroidMediaPlayer::m_engineObj = NULL;
- SLEngineItf QAndroidMediaPlayer::m_engineItf = NULL;
- SLObjectItf QAndroidMediaPlayer::m_outputObj = NULL;
- QAndroidMediaPlayer::QAndroidMediaPlayer(QObject *parent) :
- QObject(parent),
- m_playerObject(NULL),
- m_playItf(NULL),
- m_SeekItf(NULL),
- m_notifyInterval(1000)
- {
- qDebug() << "Load started";
- if (m_engineObj == NULL) {
- openMusicProfile();
- }
- qDebug() << "Load finished";
- qDebug() << "Append finished";
- }
- QAndroidMediaPlayer::~QAndroidMediaPlayer()
- {
- this->closeAudioPlayer();
- //this->closeMusicProfile();
- }
- void QAndroidMediaPlayer::setMedia(const QUrl& url)
- {
- qDebug() << "setMedia AndoidPlayer";
- this->openAudioPlayer(url);
- }
- // stub
- bool QAndroidMediaPlayer::isMuted() const
- {
- return false;
- }
- // stub
- void QAndroidMediaPlayer::setMuted(bool)
- {
- }
- // stub
- int QAndroidMediaPlayer::volume() const
- {
- return 0;
- }
- // stub
- void QAndroidMediaPlayer::setVolume(int)
- {
- }
- int QAndroidMediaPlayer::notifyInterval() const
- {
- if (m_playItf == NULL) return m_notifyInterval;
- SLresult res;
- SLmillisecond interval;
- res = (*m_playItf)->GetPositionUpdatePeriod(m_playItf, &interval);
- checkResult(res);
- return (int)interval;
- }
- void QAndroidMediaPlayer::setNotifyInterval(int val)
- {
- m_notifyInterval = val;
- if (m_playItf == NULL) return;
- SLresult res;
- SLmillisecond interval;
- res = (*m_playItf)->GetPositionUpdatePeriod(m_playItf, &interval);
- checkResult(res);
- if (val != (int)interval) {
- res = (*m_playItf)->SetPositionUpdatePeriod(m_playItf, (SLmillisecond)val);
- checkResult(res);
- emit notifyIntervalChanged(val);
- }
- }
- qint64 QAndroidMediaPlayer::position() const
- {
- if (m_playItf == NULL) return 0;
- SLresult res;
- SLmillisecond position;
- res = (*m_playItf)->GetPosition(m_playItf, &position);
- checkResult(res);
- return (qint64)position;
- }
- void QAndroidMediaPlayer::setPosition(qint64 pos)
- {
- if (m_SeekItf == NULL) return;
- // [TODO]: REVIEW SET POSITION
- SLuint32 seekMode = SL_SEEKMODE_ACCURATE; //SL_SEEKMODE_FAST
- SLresult res;
- res = (*m_SeekItf)->SetPosition(m_SeekItf, (SLuint32)pos, seekMode);
- if (res != SL_RESULT_FEATURE_UNSUPPORTED) {
- checkResult(res);
- }
- // [TODO] CHECK IS THIS REQUIRED!!!
- positionChanged(pos);
- }
- qint64 QAndroidMediaPlayer::duration() const
- {
- if (m_playItf == NULL) return 0;
- SLresult res;
- SLmillisecond duration;
- res = (*m_playItf)->GetDuration(m_playItf, &duration);
- checkResult(res);
- return (qint64)duration;
- }
- QAndroidMediaPlayer::State QAndroidMediaPlayer::state() const
- {
- return m_state;
- }
- void QAndroidMediaPlayer::checkResult(const SLresult & res)
- {
- if (res != SL_RESULT_SUCCESS) {
- qDebug() << "Error result!!! Exiting...";
- exit(1);
- }
- }
- void QAndroidMediaPlayer::openMusicProfile()
- {
- SLresult res;
- // API will be thread-safe
- SLEngineOption engineOption[2] = {{ (SLuint32) SL_ENGINEOPTION_THREADSAFE,
- (SLuint32) SL_BOOLEAN_TRUE }};
- // Create SLObjectItf
- res = slCreateEngine(&m_engineObj, 1, engineOption, 0, NULL, NULL);
- checkResult(res);
- // Realizing OpenSL Engine in synchronous mode
- res = (*m_engineObj)->Realize(m_engineObj, SL_BOOLEAN_FALSE);
- checkResult(res);
- // Get SL Engine interface
- res = (*m_engineObj)->GetInterface(m_engineObj, SL_IID_ENGINE, &m_engineItf);
- checkResult(res);
- // Create Output Mix object to be used by player. SLVolumeItf on OutputMix is absent on Android :(
- res = (*m_engineItf)->CreateOutputMix(m_engineItf, &m_outputObj, 0, NULL, NULL);
- checkResult(res);
- // Realizing Output Mix
- res = (*m_outputObj)->Realize(m_outputObj, SL_BOOLEAN_FALSE);
- checkResult(res);
- }
- //void QAndroidMediaPlayer::closeMusicProfile()
- //{
- // // Shutdown Output Mix object
- // if (m_outputObj != NULL) {
- // (*m_outputObj)->Destroy(m_outputObj);
- // m_outputObj = NULL;
- // }
- // // Shutdown OpenSL Engine
- // if (m_engineObj != NULL) {
- // (*m_engineObj)->Destroy(m_engineObj);
- // m_engineObj = NULL;
- // m_engineItf = NULL;
- // }
- //}
- void QAndroidMediaPlayer::openAudioPlayer(const QUrl& url)
- {
- qDebug() << "openAudioPlayer";
- SLresult res;
- // Close old AudioPlayer
- this->closeAudioPlayer();
- // configure audio source
- // (requires the INTERNET permission depending on the uri parameter)
- SLDataLocator_URI loc_uri = { SL_DATALOCATOR_URI, (SLchar *) url.toString().toUtf8().constData() };
- SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
- SLDataSource audioSrc = { &loc_uri, &format_mime };
- // configure audio sink
- SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, m_outputObj};
- SLDataSink audioSnk = {&loc_outmix, NULL};
- // create audio player
- const SLInterfaceID ids[1] = {SL_IID_SEEK};
- const SLboolean req[1] = {SL_BOOLEAN_TRUE};
- res = (*m_engineItf)->CreateAudioPlayer(m_engineItf, &m_playerObject, &audioSrc,
- &audioSnk, 1, ids, req);
- // note that an invalid URI is not detected here, but during prepare/prefetch on Android,
- // or possibly during Realize on other platforms
- checkResult(res);
- // realize the player
- res = (*m_playerObject)->Realize(m_playerObject, SL_BOOLEAN_FALSE);
- checkResult(res);
- // get the play interface
- res = (*m_playerObject)->GetInterface(m_playerObject, SL_IID_PLAY, &m_playItf);
- checkResult(res);
- // set notify interval
- res = (*m_playItf)->SetPositionUpdatePeriod(m_playItf, (SLmillisecond)m_notifyInterval);
- checkResult(res);
- // get the seek interface
- res = (*m_playerObject)->GetInterface(m_playerObject, SL_IID_SEEK, &m_SeekItf);
- checkResult(res);
- // //[TODO] ADD REGISTER TICK CALLBACK
- // res = (*m_playItf)->RegisterCallback(m_playItf, &GlobalCallbackPositionChanged, this);
- // checkResult(res);
- }
- void QAndroidMediaPlayer::closeAudioPlayer()
- {
- // destroy player
- if (m_playerObject != NULL) {
- (*m_playerObject)->Destroy(m_playerObject);
- m_playerObject = NULL;
- m_playItf = NULL;
- m_SeekItf = NULL;
- }
- }
- void QAndroidMediaPlayer::play()
- {
- SLresult res;
- // make sure the URI audio player was created
- if (NULL != m_playItf) {
- // check current state
- SLuint32 playState;
- res = (*m_playItf)->GetPlayState(m_playItf, &playState);
- checkResult(res);
- if (playState != SL_PLAYSTATE_PLAYING) {
- // set the player's state
- res = (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING);
- checkResult(res);
- m_state = QAndroidMediaPlayer::PausedState;
- emit stateChanged(m_state);
- }
- }
- }
- void QAndroidMediaPlayer::pause()
- {
- SLresult res;
- // make sure the URI audio player was created
- if (NULL != m_playItf) {
- // check current state
- SLuint32 playState;
- res = (*m_playItf)->GetPlayState(m_playItf, &playState);
- checkResult(res);
- if (playState == SL_PLAYSTATE_PLAYING) {
- // set the player's state
- res = (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PAUSED);
- checkResult(res);
- m_state = QAndroidMediaPlayer::PlayingState;
- emit stateChanged(m_state);
- }
- }
- }
- void QAndroidMediaPlayer::stop()
- {
- SLresult res;
- // make sure the URI audio player was created
- if (NULL != m_playItf) {
- // check current state
- SLuint32 playState;
- res = (*m_playItf)->GetPlayState(m_playItf, &playState);
- checkResult(res);
- if (playState != SL_PLAYSTATE_STOPPED) {
- // set the player's state
- res = (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
- checkResult(res);
- m_state = QAndroidMediaPlayer::StoppedState;
- emit stateChanged(m_state);
- }
- }
- }
- void QAndroidMediaPlayer::callbackPositionChanged(SLuint32 playevent)
- {
- qDebug() << "callbackPositionChanged" + QString::number(playevent);
- switch (playevent) {
- // At the end of file
- case SL_PLAYEVENT_HEADATEND:
- this->stop();
- m_state = QAndroidMediaPlayer::StoppedState;
- emit stateChanged(m_state);
- emit mediaStatusChanged(QAndroidMediaPlayer::EndOfMedia);
- break;
- case SL_PLAYEVENT_HEADATMARKER:
- break;
- // At the new pos
- case SL_PLAYEVENT_HEADATNEWPOS:
- emit positionChanged(position());
- break;
- case SL_PLAYEVENT_HEADMOVING:
- break;
- case SL_PLAYEVENT_HEADSTALLED:
- break;
- default:
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement