コード例 #1
0
ファイル: mediaobject.cpp プロジェクト: Camelek/qtmoko
void MediaObject::controlAvailable(QString const& name)
{
    if (name == QMediaControl::name() && !d->valid) {
        d->control = new QMediaControl(d->content);
        connect(d->control, SIGNAL(playerStateChanged(QtopiaMedia::State)), SLOT(playerStateChanged(QtopiaMedia::State)));
        connect(d->control, SIGNAL(lengthChanged(quint32)), SLOT(lengthChanged(quint32)));

        d->valid = true;

        // Connect peers
        foreach (MediaNode* peer, d->peers)
            peer->setContent(d->content);

        switch (d->requiredState) {
        case QtopiaMedia::Playing:
            d->control->start();
            break;
        default:
            ;
        }
    }

    bool hasVideo = d->content->controls().contains(QMediaVideoControl::name());

    if (hasVideo != d->hasVideo)
        emit hasVideoChanged(d->hasVideo = hasVideo);
}
コード例 #2
0
ファイル: PlayerWidget.cpp プロジェクト: HenryHu/lumina
PlayerWidget::PlayerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::PlayerWidget()){
  ui->setupUi(this); //load the designer form
  PLAYER = new QMediaPlayer(this);
    PLAYER->setVolume(100);
    PLAYER->setNotifyInterval(1000); //1 second interval (just needs to be a rough estimate)
  PLAYLIST = new QMediaPlaylist(this);
    PLAYLIST->setPlaybackMode(QMediaPlaylist::Sequential);
    PLAYER->setPlaylist(PLAYLIST);
	
  configMenu = new QMenu(this);
    ui->tool_config->setMenu(configMenu);
  addMenu = new QMenu(this);
    ui->tool_add->setMenu(addMenu);
	
  updatinglists = false; //start off as false
	
  LoadIcons();
  playerStateChanged(); //update button visibility
  currentSongChanged();
  //Connect all the signals/slots
  //connect(infoTimer, SIGNAL(timeout()), this, SLOT(rotateTrackInfo()) );
  connect(PLAYER, SIGNAL(positionChanged(qint64)),this, SLOT(updateProgress(qint64)) );
  connect(PLAYER, SIGNAL(durationChanged(qint64)), this, SLOT(updateMaxProgress(qint64)) );
  connect(PLAYLIST, SIGNAL(mediaChanged(int, int)), this, SLOT(playlistChanged()) );
  connect(PLAYER, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged()) );
  connect(PLAYLIST, SIGNAL(currentMediaChanged(const QMediaContent&)), this, SLOT(currentSongChanged()) );
  connect(ui->combo_playlist, SIGNAL(currentIndexChanged(int)), this, SLOT(userlistSelectionChanged()) );
  connect(ui->tool_play, SIGNAL(clicked()), this, SLOT(playClicked()) );
  connect(ui->tool_pause, SIGNAL(clicked()), this, SLOT(pauseClicked()) );
  connect(ui->tool_stop, SIGNAL(clicked()), this, SLOT(stopClicked()) );
  connect(ui->tool_next, SIGNAL(clicked()), this, SLOT(nextClicked()) );
  connect(ui->tool_prev, SIGNAL(clicked()), this, SLOT(prevClicked()) );
  
}
コード例 #3
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::playTheMusic(QString listName, int index)
{
    currentList = listName;
    this->setCurrentIndex(index);
    player.play();
    emit playerStateChanged(PLAYING);
}
コード例 #4
0
ファイル: MultimediaWidget.cpp プロジェクト: trueos/lumina
MultimediaWidget::MultimediaWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MultimediaWidget){
  ui->setupUi(this); //load the designer file

  //Add in the special QMultimediaWidgets
  mediaObj = new QMediaPlayer(this);
    mediaObj->setVolume(100);
    mediaObj->setNotifyInterval(500); //only every 1/2 second update
  videoDisplay = new QVideoWidget(this);
    videoDisplay->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    ui->videoLayout->addWidget(videoDisplay);
    mediaObj->setVideoOutput(videoDisplay);
    videoDisplay->setVisible(false);

  UpdateIcons();
  UpdateText();

  //Connect the special signals/slots for the media object
  connect(mediaObj, SIGNAL(durationChanged(qint64)), this, SLOT(playerDurationChanged(qint64)) );
  connect(mediaObj, SIGNAL(seekableChanged(bool)), ui->playerSlider, SLOT(setEnabled(bool)) );
  connect(mediaObj, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(playerStatusChanged(QMediaPlayer::MediaStatus)) );
  connect(mediaObj, SIGNAL(positionChanged(qint64)), this, SLOT(playerTimeChanged(qint64)) );
  connect(mediaObj, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged(QMediaPlayer::State)) );
  connect(mediaObj, SIGNAL(videoAvailableChanged(bool)), this, SLOT(playerVideoAvailable(bool)) );
  connect(mediaObj, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(playerError()) );

  //Disable some of the initial states
  ui->tool_player_stop->setEnabled(false); //nothing to stop yet
  ui->tool_player_pause->setVisible(false); //nothing to pause yet
  ui->playerSlider->setEnabled(false); //nothing to seek yet
}
コード例 #5
0
void PlaybinSession::start()
{
    if (d->playbin != 0) {
        if (gst_element_set_state(d->playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
            qWarning() << "GStreamer; Unable to play -" << d->url.toString();
            emit playerStateChanged(QtopiaMedia::Error);
        }
    }
}
コード例 #6
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::removeAllMusics(QString listName)
{
    list[listName].clear();
    if (list[currentList].size() == 0)
    {
        player.stop();
        emit musicNotAvailable();
        emit playerStateChanged(NOMUSIC);
    }
}
コード例 #7
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::removeTheMusic(QString listName, int index)
{
    list[listName].removeAt(index);
    if (listName == currentList && index == currentindex)
    {
        player.stop();
        emit musicNotAvailable();
        emit playerStateChanged(NOMUSIC);
    }
}
コード例 #8
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::playNext(QMediaPlayer::MediaStatus state)
{
    if (!(state == QMediaPlayer::EndOfMedia))
        return;
    switch (playMode)
    {
        case CurrentItemOnce:
            player.stop();
            emit playerStateChanged(PAUSE);
            break;
        case CurrentItemInLoop:
            player.play();
            emit playerStateChanged(PLAYING);
            break;
        case Sequential:
            currentindex++;
            if (currentindex < list[currentList].size())
            {
                setCurrentIndex(currentindex);
                player.play();
                emit playerStateChanged(PLAYING);
            }
            else
            {
                currentindex--;
                player.stop();
                emit playerStateChanged(PAUSE);
            }
            break;
        case Loop:
            currentindex++;
            if (currentindex < list[currentList].size())
            {
                setCurrentIndex(currentindex);
                player.play();
                emit playerStateChanged(PLAYING);
            }
            else
            {
                currentindex = 0;
                setCurrentIndex(currentindex);
                player.play();
                emit playerStateChanged(PLAYING);
            }
            break;
        case Random:
            QTime time;
            time = QTime::currentTime();
            qsrand(time.msec()+time.second()*1000);
            currentindex = qrand()%list[currentList].size();
            setCurrentIndex(currentindex);
            player.play();
            emit playerStateChanged(PLAYING);
            break;
    }
}
コード例 #9
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
bool MyPlayer::playNext()
{
    if (this->mediaCount() == 0)
        return false;
    int index = this->getCurrentIndex();
    if(++index == this->mediaCount())
        index=0;
    this->setCurrentIndex(index);
    player.play();
    emit playerStateChanged(PLAYING);
    return true;
}
コード例 #10
0
// Set QtopiaMedia state
void PlaybinSession::setQtState(QtopiaMedia::State state)
{
    if(state == d->state)
        return;
    
#if DEBUG_SESSION
    qDebug() << "PlaybinSession::setQtState " << qtStateName(d->state) << "->" << qtStateName(state);
#endif
    
    d->state = state;
    emit playerStateChanged(state);
}
コード例 #11
0
QompQtMultimediaPlayer::QompQtMultimediaPlayer() :
	QompPlayer(),
	player_(new QMediaPlayer(this)),
	resolver_(0/*new QompTagLibMetaDataResolver(this)*/),
	watcher_(0)
{
	connect(player_, SIGNAL(positionChanged(qint64)), SIGNAL(currentPositionChanged(qint64)));
	connect(player_, SIGNAL(volumeChanged(int)), SLOT(volumeChanged(int)));
	connect(player_, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
	connect(player_, SIGNAL(durationChanged(qint64)), SIGNAL(currentTuneTotalTimeChanged(qint64)));
	connect(player_, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(playerStateChanged(QMediaPlayer::State)));
	connect(player_, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));

	//connect(resolver_, SIGNAL(tuneUpdated(Tune*)), SIGNAL(tuneDataUpdated(Tune*)), Qt::QueuedConnection);
}
コード例 #12
0
// Set gst playbin element state
bool PlaybinSession::setGstState(GstState state)
{
#if DEBUG_SESSION
    qDebug() << "PlaybinSession::setGstState " << gst_element_state_get_name(state);
#endif
    
    if(d->playbin == 0)
        return false;
    
    if(gst_element_set_state(d->playbin, state) != GST_STATE_CHANGE_FAILURE)
        return true;

    qWarning() << "setGstState failed, state=" << gst_element_state_get_name(state) << ", url=" << d->url.toString();
    emit playerStateChanged(QtopiaMedia::Error);
    return false;
}
コード例 #13
0
ファイル: mididecoder.cpp プロジェクト: Camelek/qtmoko
void MidiDecoder::start()
{
    if (!d->initialized)
    {
        QIODevice::open(QIODevice::ReadWrite | QIODevice::Unbuffered);

        d->options.rate        = d->outputInfo.frequency;
        d->options.format      = MID_AUDIO_S16LSB;  // 16
        d->options.channels    = d->outputInfo.channels;
        d->options.buffer_size = MIDI_BUFFER_SIZE / (16 * 2 / 8);

        d->midiStream = mid_istream_open_callbacks(midiReadCallback,
                                                  midiCloseCallback,
                                                  this);

        d->song = mid_song_load(d->midiStream, &d->options);

        if (d->song != 0)
        {
            d->state = QtopiaMedia::Playing;

            d->length = mid_song_get_total_time(d->song);
            emit lengthChanged(d->length);

            mid_song_set_volume(d->song, d->muted ? 0 : d->volume * 2);

            mid_song_start(d->song);

            d->initialized = true;
        }
        else {
            qLog(Media) << "MidiDecoder::start(); Failed to load MIDI file";
            d->state = QtopiaMedia::Error;
        }
    }
    else
        d->state = QtopiaMedia::Playing;

    if (d->initialized) {
        emit readyRead();
        emit playerStateChanged(d->state);
    }
}
コード例 #14
0
TypingTimeLord::TypingTimeLord(std::shared_ptr<AudioPlayer> player,
                               QObject* parent) :
  QObject(parent),
  m_player(player) {

  QObject::connect(m_player.get(), SIGNAL(stateChanged()),
                   this,           SLOT(playerStateChanged()));

  // Load the timeout values
  QSettings settings;
  settings.beginGroup(CFG_GROUP);
  m_wait_timeout = settings.value(CFG_WAITING, m_wait_timeout).toUInt();
  m_type_timeout = settings.value(CFG_TYPING,  m_type_timeout).toUInt();
  settings.endGroup();

  // Initialize the timers to single shot timers and connect them to their
  // respective fallbacks;
  m_wait_timer.setSingleShot(true);
  m_type_timer.setSingleShot(true);
  connect(&m_wait_timer, SIGNAL(timeout()), this, SLOT(waitTimeout()));
  connect(&m_type_timer, SIGNAL(timeout()), this, SLOT(typeTimeout()));
}
コード例 #15
0
ファイル: mididecoder.cpp プロジェクト: Camelek/qtmoko
//private:
qint64 MidiDecoder::readData(char *data, qint64 maxlen)
{
    if (d->state != QtopiaMedia::Playing)
        return 0;

    qint64      rc = 0;

    if (maxlen > 0) {
        quint32 position = (mid_song_get_time(d->song) / 1000) * 1000;
        if (d->position != position) {
            d->position = position;
            emit positionChanged(d->position);
        }

        if ((rc = (qint64) mid_song_read_wave(d->song, data, maxlen)) == 0) {
            seek(0);
            mid_song_start(d->song);
            emit playerStateChanged(d->state = QtopiaMedia::Stopped);
        }
    }

    return rc;
}
コード例 #16
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::play()
{
    player.play();
    emit playerStateChanged(PLAYING);
}
コード例 #17
0
ファイル: myplayer.cpp プロジェクト: AndyQsmart/QtMusic-1.0
void MyPlayer::pause()
{
    player.pause();
    emit playerStateChanged(PAUSE);
}
コード例 #18
0
ファイル: wavdecoder.cpp プロジェクト: Camelek/qtmoko
qint64 WavDecoder::readData(char *data, qint64 maxlen)
{
    qint64      rc = 0;
    if (maxlen > 0)
    {
        if(d->header.wave.audioFormat == 1) {
            if (d->state == QtopiaMedia::Playing)
            {
                quint32 position = quint32((double(d->rawDataRead) /
                            (double(d->outputInfo.frequency) *
                             d->outputInfo.channels *
                             (d->outputInfo.bitsPerSample / 8))) * 1000);

                if (d->position != position)
                {
                    d->position = position;
                    emit positionChanged(d->position);
                }

                rc = d->inputDevice->read(data, maxlen);

                if (rc == 0)
                    emit playerStateChanged(d->state = QtopiaMedia::Stopped);
                else
                    d->rawDataRead += rc;
            }
        }
#ifdef WAVGSM_SUPPORTED
        else if(d->header.wave.audioFormat == 49) {
            if (d->state == QtopiaMedia::Playing)
            {
                quint32 position = d->rawDataRead*1000/d->header.wave.sampleRate*64/13;
                if((int)position > 0)
                    if (d->position != position)
                    {
                        d->position = position;
                        emit positionChanged(d->position);
                    }

                if(d->output_length > (int)maxlen) {
                    memcpy(data,d->output_data,(int)maxlen);
                    memmove(d->output_data,d->output_data+(int)maxlen,
                            d->output_length-(int)maxlen);
                    d->output_length -= (int)maxlen;
                    return maxlen;
                }

                //First top up input buffer with data
                rc = d->inputDevice->read(d->input_data+d->input_length,
                        WAV_DECODER_BUFFER-d->input_length);
                d->input_length +=rc;
                d->input_pos=d->input_data;
                rc=0;

                // decode and fill output buffer with data
                d->output_pos=d->output_data+d->output_length;
                int pos = 0;
                while (((pos + 65) <= d->input_length) && (d->output_length + 640 < WAV_DECODER_BUFFER*5)) {
                    // decode first half of 65 byte GSM frame
                    gsm_decode( d->gsmhandle, (gsm_byte*)(d->input_pos), d->gsmsamples );
                    // decode second half of 65 byte GSM frame
                    gsm_decode( d->gsmhandle, (gsm_byte*)(d->input_pos+33),d->gsmsamples + 160 );
                    pos += 65;
                    d->input_pos += 65;
                    d->rawDataRead += 65;

                    for(int i=0;i<320;i++) {
                        unsigned char *c = (unsigned char *)&d->gsmsamples[i];
                        *d->output_pos++ = *c;
                        *d->output_pos++ = *(c+1);
                        d->output_length+=2;
                        if(d->outputInfo.channels==2) {
                            *d->output_pos++ = *c;
                            *d->output_pos++ = *(c+1);
                            d->output_length+=2;
                        }
                    }
                }

                // Move the unprocessed input data to the start point
                memmove(d->input_data, d->input_data + pos, d->input_length - pos);
                d->input_length -= pos;

                // Copy output data out
                if(d->output_length > (int)maxlen) {
                    memcpy(data,d->output_data,(int)maxlen);
                    memmove(d->output_data,d->output_data+(int)maxlen,
                            d->output_length-(int)maxlen);
                    d->output_length -= (int)maxlen;
                    rc = (int)maxlen;
                } else {
                    rc = d->output_length;
                    memcpy(data,d->output_data,d->output_length);
                    d->output_length = 0;
                }
                if (rc == 0)
                    emit playerStateChanged(d->state = QtopiaMedia::Stopped);
            }
        }
#endif
    }
    return rc;
}
コード例 #19
0
ファイル: wavdecoder.cpp プロジェクト: Camelek/qtmoko
void WavDecoder::pause()
{
    emit playerStateChanged(d->state = QtopiaMedia::Paused);
}
コード例 #20
0
ファイル: wavdecoder.cpp プロジェクト: Camelek/qtmoko
void WavDecoder::stop()
{
    emit playerStateChanged(d->state = QtopiaMedia::Stopped);
    seek(0);
}
コード例 #21
0
ファイル: wavdecoder.cpp プロジェクト: Camelek/qtmoko
void WavDecoder::start()
{
    if (!d->initialized)
    {
        if (QIODevice::open(QIODevice::ReadWrite | QIODevice::Unbuffered))
        {
            if (d->inputDevice->read((char*)&d->header, sizeof(CombinedHeader)) == sizeof(CombinedHeader))
            {
                if (memcmp(&d->header.riff.descriptor.id, riffId, 4) == 0 &&
                    memcmp(&d->header.riff.type, waveId, 4) == 0 &&
                    memcmp(&d->header.wave.descriptor.id, fmtId, 4) == 0)
                {
                    if (d->header.wave.audioFormat == 1)
                    {
                        d->outputInfo.type = QMediaDevice::Info::PCM;
                        d->outputInfo.frequency = qFromLittleEndian<quint32>(d->header.wave.sampleRate);
                        d->outputInfo.bitsPerSample = qFromLittleEndian<quint16>(d->header.wave.bitsPerSample);
                        d->outputInfo.channels = qFromLittleEndian<quint16>(d->header.wave.numChannels);
                        d->outputInfo.volume = d->muted ? 0 : d->volume;

                        d->length = quint32((double(d->header.riff.descriptor.size) /
                                        d->outputInfo.frequency /
                                        d->outputInfo.channels /
                                        (d->outputInfo.bitsPerSample / 8)) * 1000);

                        qLog(Media) << "WavDecoder::start(); Info" <<
                                    d->outputInfo.frequency <<
                                    d->outputInfo.bitsPerSample <<
                                    d->outputInfo.channels <<
                                    "length:" << d->length;

                        emit lengthChanged(d->length);

                        d->initialized = true;
#ifdef WAVGSM_SUPPORTED
                    } else if(d->header.wave.audioFormat == 49) {
                        d->inputDevice->seek(60);
                        d->input_data = (char *)malloc(WAV_DECODER_BUFFER);
                        d->input_pos = d->input_data;
                        d->input_length = 0;
                        d->output_data = (char *)malloc(WAV_DECODER_BUFFER*6);
                        d->output_pos = d->output_data;
                        d->output_length = 0;
                        d->gsmhandle = gsm_create();
                        int value = 1;
                        gsm_option( d->gsmhandle, GSM_OPT_WAV49, &value );

                        d->outputInfo.type = QMediaDevice::Info::PCM;
                        d->outputInfo.frequency = qFromLittleEndian<quint32>(d->header.wave.sampleRate);
                        d->outputInfo.bitsPerSample = 16;
                        d->outputInfo.channels = qFromLittleEndian<quint16>(d->header.wave.numChannels);
                        d->outputInfo.volume = d->volume;
                        d->length = d->inputDevice->dataType().dataSize*1000/d->header.wave.sampleRate*64/13;
                        qLog(Media) << "WavDecoder::start(); Info" <<
                                    d->outputInfo.frequency <<
                                    d->outputInfo.bitsPerSample <<
                                    d->outputInfo.channels <<
                                    "length:" << d->length;

                        emit lengthChanged(d->length);
                        d->initialized = true;
#endif
                    } else {
                        qWarning("WAV file is in %d audio format, not supported!",d->header.wave.audioFormat);
                    }
                }
            }
        }
    }

    if (d->initialized)
    {
        if (d->state == QtopiaMedia::Stopped)
            seek(0);

        d->state = QtopiaMedia::Playing;

        emit readyRead();
        emit playerStateChanged(d->state);
    }
}
コード例 #22
0
void PlaybinSession::busMessage(Message const& msg)
{
    GstMessage* gm = msg.rawMessage();

    if (gm == 0)
    {   // Null message, query current position
        GstFormat   format = GST_FORMAT_TIME;
        gint64      position = 0;

        if (gst_element_query_position(d->playbin, &format, &position) == TRUE)
        {
            quint32 pos = position / 1000000;

            if (pos != d->position)
            {
                d->position = pos;
                emit positionChanged(d->position);
            }
        }
    }
    else if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(d->playbin))
    {
        switch (GST_MESSAGE_TYPE(gm))
        {
        case GST_MESSAGE_DURATION:
            break;

        case GST_MESSAGE_STATE_CHANGED:
            {
                GstState    oldState;
                GstState    newState;
                GstState    pending;

                gst_message_parse_state_changed(gm, &oldState, &newState, &pending);

                switch (newState)
                {
                    case GST_STATE_VOID_PENDING:
                    case GST_STATE_NULL:
                    case GST_STATE_READY:
                    case GST_STATE_PAUSED:
                        break;
                    case GST_STATE_PLAYING:
                        if (oldState == GST_STATE_PAUSED)
                            getStreamsInfo();

                        if (d->state != QtopiaMedia::Playing)
                            emit playerStateChanged(d->state = QtopiaMedia::Playing);
                        break;
                }
            }
            break;

        case GST_MESSAGE_EOS:
            if (d->state != QtopiaMedia::Stopped)
                emit playerStateChanged(d->state = QtopiaMedia::Stopped);
            break;

        case GST_MESSAGE_STREAM_STATUS:
        case GST_MESSAGE_UNKNOWN:
        case GST_MESSAGE_ERROR:
        case GST_MESSAGE_WARNING:
        case GST_MESSAGE_INFO:
        case GST_MESSAGE_TAG:
        case GST_MESSAGE_BUFFERING:
        case GST_MESSAGE_STATE_DIRTY:
        case GST_MESSAGE_STEP_DONE:
        case GST_MESSAGE_CLOCK_PROVIDE:
        case GST_MESSAGE_CLOCK_LOST:
        case GST_MESSAGE_NEW_CLOCK:
        case GST_MESSAGE_STRUCTURE_CHANGE:
        case GST_MESSAGE_APPLICATION:
        case GST_MESSAGE_ELEMENT:
        case GST_MESSAGE_SEGMENT_START:
        case GST_MESSAGE_SEGMENT_DONE:
        case GST_MESSAGE_LATENCY:
        case GST_MESSAGE_ANY:
            break;
        }
    }
}
コード例 #23
0
SmoozikSimplestClientWindow::SmoozikSimplestClientWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SmoozikSimplestClientWindow)
{
    ui->setupUi(this);

    // Initialize SmoozikManager
    smoozikManager = new SmoozikManager(APIKEY, SECRET, SmoozikManager::XML, false, this);
    smoozikPlaylist = new SmoozikPlaylist;
    connect(smoozikManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetworkReply(QNetworkReply*)));

    // Initialize music directory
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    _dirName = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
#else
    _dirName = QStandardPaths::writableLocation(QStandardPaths::MusicLocation);
#endif

    // Initialize playlist filler
    ui->setupUi(this);
    smoozikPlaylistFillerThread = new QThread();
    smoozikPlaylistFiller = new SmoozikPlaylistFiller(smoozikPlaylist);
    smoozikPlaylistFiller->moveToThread(smoozikPlaylistFillerThread);
    connect(smoozikPlaylistFiller, SIGNAL(trackFound(QString,QString,QString,QString,uint)), this, SLOT(addTrackToPlaylist(QString,QString,QString,QString,uint)));
    connect(smoozikPlaylistFiller, SIGNAL(tracksRetrieved()), this, SIGNAL(tracksRetrieved()));
    connect(smoozikPlaylistFiller, SIGNAL(noTrackRetrieved()), this, SLOT(noTrackRetrievedMessage()));
    connect(smoozikPlaylistFiller, SIGNAL(maxPlaylistSizeReached()), this, SLOT(maxPlaylistSizeReachedMessage()));
    connect(smoozikPlaylistFillerThread, SIGNAL(started()), smoozikPlaylistFiller, SLOT(fillPlaylist()));
    connect(smoozikPlaylistFiller, SIGNAL(finished()), smoozikPlaylistFillerThread, SLOT(quit()), Qt::DirectConnection);

    // Initialize player
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    player = new Phonon::MediaObject(this);
    Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    Phonon::createPath(player, audioOutput);
    connect(player, SIGNAL(currentSourceChanged(Phonon::MediaSource)), this, SLOT(updateTrackLabels()));
    connect(player, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(playerStateChanged()));
#else
    player = new QMediaPlayer(this);
    player->setPlaylist(new QMediaPlaylist(player));
    player->playlist()->setPlaybackMode(QMediaPlaylist::Sequential);
    connect(player, SIGNAL(currentMediaChanged(QMediaContent)), this, SLOT(updateTrackLabels()));
    connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged()));
#endif
    connect(ui->playButton, SIGNAL(clicked()), player, SLOT(play()));
    connect(ui->pauseButton, SIGNAL(clicked()), player, SLOT(pause()));
    connect(this, SIGNAL(currentTrackSet()), this, SLOT(updateTrackLabels()));
    connect(this, SIGNAL(nextTrackSet()), this, SLOT(updateTrackLabels()));

    // Initialize main state machine which controls what is displayed
    QStateMachine *mainStateMachine = new QStateMachine(this);
    QState *mainState = new QState(mainStateMachine);
    QState *loginState = new QState(mainState);
    QState *startPartyState = new QState(mainState);
    QState *connectedState = new QState(mainState);
    QState *retrieveTracksState = new QState(connectedState);
    QState *sendPlaylistState = new QState(connectedState);
    QState *getTopTracksState = new QState(connectedState);
    QState *partyState = new QState(connectedState);
    QState *waitingState = new QState(partyState);
    QState *sendCurrentTrackState = new QState(partyState);
    QState *sendNextTrackState = new QState(partyState);

    QStateMachine *playerStateMachine = new QStateMachine(this);
    QState *playerState = new QState(playerStateMachine);
    QState *playingState = new QState(playerState);
    QState *pausedState = new QState(playerState);

    // Define state initial states and transitions
    mainStateMachine->setInitialState(mainState);
    mainState->setInitialState(loginState);
    connectedState->setInitialState(retrieveTracksState);
    partyState->setInitialState(waitingState);
    playerStateMachine->setInitialState(playerState);
    playerState->setInitialState(pausedState);

    mainState->addTransition(this, SIGNAL(disconnected()), loginState);
    loginState->addTransition(this, SIGNAL(loggedIn()), startPartyState);
    startPartyState->addTransition(this, SIGNAL(partyStarted()), connectedState);
    connectedState->addTransition(ui->changePlaylistButton, SIGNAL(clicked()), retrieveTracksState);
    retrieveTracksState->addTransition(this, SIGNAL(tracksRetrieved()), sendPlaylistState);
    sendPlaylistState->addTransition(this, SIGNAL(playlistSent()), getTopTracksState);
    getTopTracksState->addTransition(this, SIGNAL(currentTrackSet()), sendCurrentTrackState);
    sendCurrentTrackState->addTransition(this, SIGNAL(currentTrackSent()), getTopTracksState);
    getTopTracksState->addTransition(this, SIGNAL(nextTrackSet()), sendNextTrackState);
    sendNextTrackState->addTransition(this, SIGNAL(nextTrackSent()), waitingState);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    waitingState->addTransition(player, SIGNAL(currentSourceChanged(Phonon::MediaSource)), sendCurrentTrackState);
#else
    waitingState->addTransition(player, SIGNAL(currentMediaChanged(QMediaContent)), sendCurrentTrackState);
#endif

    playerState->addTransition(this, SIGNAL(playing()), playingState);
    playerState->addTransition(this, SIGNAL(paused()), pausedState);

    // Define state properties
    loginState->assignProperty(this, "state", Login);
    loginState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->loginPage));
    loginState->assignProperty(ui->loginButton, "enabled", true);
    loginState->assignProperty(ui->disconnectButton, "visible", false);
    loginState->assignProperty(ui->changePlaylistButton, "visible", false);
    loginState->assignProperty(ui->usernameLineEdit, "enabled", true);
    loginState->assignProperty(ui->passwordLineEdit, "enabled", true);
    loginState->assignProperty(ui->loginStateLabel, "text", QString());

    startPartyState->assignProperty(this, "state", StartParty);
    startPartyState->assignProperty(ui->loginStateLabel, "text", tr("Starting party..."));
    startPartyState->assignProperty(ui->disconnectButton, "visible", false);
    startPartyState->assignProperty(ui->changePlaylistButton, "visible", false);

    connectedState->assignProperty(ui->disconnectButton, "visible", true);

    retrieveTracksState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->loadingPage));
    retrieveTracksState->assignProperty(ui->loginStateLabel, "text", tr("Connected"));
    retrieveTracksState->assignProperty(ui->loadingLabel, "text", tr("Retrieving tracks..."));
    retrieveTracksState->assignProperty(ui->changePlaylistButton, "visible", false);

    sendPlaylistState->assignProperty(this, "state", SendPlaylist);
    sendPlaylistState->assignProperty(ui->loadingLabel, "text", tr("Sending playlist..."));
    sendPlaylistState->assignProperty(ui->changePlaylistButton, "visible", true);

    getTopTracksState->assignProperty(this, "state", GetTopTracks);
    getTopTracksState->assignProperty(ui->loadingLabel, "text", tr("Get top tracks..."));
    getTopTracksState->assignProperty(ui->nextButton, "enabled", false);
    getTopTracksState->assignProperty(ui->changePlaylistButton, "visible", true);

    partyState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->playerPage));
    partyState->assignProperty(ui->changePlaylistButton, "visible", true);

    sendCurrentTrackState->assignProperty(this, "state", SendCurrentTrack);
    sendCurrentTrackState->assignProperty(ui->nextButton, "enabled", false);

    sendNextTrackState->assignProperty(this, "state", SendNextTrack);
    sendNextTrackState->assignProperty(ui->nextButton, "enabled", false);

    waitingState->assignProperty(ui->nextButton, "enabled", true);

    playingState->assignProperty(ui->playButton, "visible", false);
    playingState->assignProperty(ui->pauseButton, "visible", true);

    pausedState->assignProperty(ui->playButton, "visible", true);
    pausedState->assignProperty(ui->pauseButton, "visible", false);

    // Connect states and actions
    connect(startPartyState, SIGNAL(entered()), this, SLOT(startParty()));
    connect(retrieveTracksState, SIGNAL(entered()), this, SLOT(retrieveTracksDialog()));
    connect(sendPlaylistState, SIGNAL(entered()), this, SLOT(sendPlaylist()));
    connect(getTopTracksState, SIGNAL(entered()), this, SLOT(getTopTracks()));
    connect(sendCurrentTrackState, SIGNAL(entered()), this, SLOT(sendCurrentTrack()));
    connect(sendNextTrackState, SIGNAL(entered()), this, SLOT(sendNextTrack()));

    // Connect gui and actions
    connect(ui->usernameLineEdit, SIGNAL(returnPressed()), this, SLOT(submitLogin()));
    connect(ui->passwordLineEdit, SIGNAL(returnPressed()), this, SLOT(submitLogin()));
    connect(ui->loginButton, SIGNAL(clicked()), this, SLOT(submitLogin()));
    connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(nextTrack()));
    connect(ui->disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));

    // Start state machine
    mainStateMachine->start();
    playerStateMachine->start();
}