Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

help to fix some problem in my QmediaPlayer



  • i made a palyer based on qmediaplayer

    here is the cpp file.

    
    #include "coreplayer.h"
    #include "ui_coreplayer.h"
    
    #include <QMediaService>
    #include <QVideoProbe>
    #include <QAudioProbe>
    #include <QMediaMetaData>
    #include <QtWidgets>
    #include <QVideoWidget>
    #include <QStandardItemModel>
    
    
    coreplayer::coreplayer(QWidget *parent):QWidget(parent),ui(new Ui::coreplayer)
       , playerState(QMediaPlayer::StoppedState)
    {
        qDebug() << "coreplayer opening";
        ui->setupUi(this);
    
        mModel = new QStandardItemModel(this);
        mNumberOfFiles = 0;
        ui->shortcut->setVisible(0);
        ui->folderLineEdit->setReadOnly(true);
        ui->medialist->setModel(mModel);
    
        player = new QMediaPlayer(this);
        connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
        connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
        connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
        connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int)));
        connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
        connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
    //    connect(player, &QMediaPlayer::stateChanged, this, &coreplayer::stateChanged);
    
        QVideoWidget *Vwidget = new QVideoWidget(this);
        player->setVideoOutput(Vwidget);
        ui->view->addWidget(Vwidget);
    
        if(isPlayerAvailable()){
            for (QPushButton *b : ui->navigation->findChildren<QPushButton*>()){
                b->setEnabled(false);
            }
            ui->playlist->setEnabled(true);
            ui->seekBar->setEnabled(false);
            ui->volume->setEnabled(false);
        }
    
        ui->seekBar->setRange(0, player->duration() / 1000);
        connect(ui->seekBar,SIGNAL(sliderMoved(int)),this,SLOT(seek(int)));
    
        if (!isPlayerAvailable()) {
            messageEngine(tr("The QMediaPlayer object does not have a valid service.\nPlease check the media service plugins are installed."),"Warning");
         }
    
        ui->numberOfFiles->setVisible(0);
    
        audioMimes();
        videoMimes();
        shotcuts();
    }
    
    coreplayer::~coreplayer()
    {
        qDebug()<<"corepalyer closing";
        delete ui;
    }
    
    void coreplayer::shotcuts(){
        QShortcut* shortcut;
    
        shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_O), this);
        connect(shortcut, &QShortcut::activated, this, &coreplayer::on_open_clicked);
        shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left), this);
        connect(shortcut, &QShortcut::activated, this, &coreplayer::on_next_clicked);
        shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right), this);
        connect(shortcut, &QShortcut::activated, this, &coreplayer::on_previous_clicked);
        shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Enter), this);
        connect(shortcut, &QShortcut::activated, this, &coreplayer::on_stop_clicked);
    //    shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Space), this);
    //    connect(shortcut, &QShortcut::activated, this, &coreplayer::on_play_clicked);
    //    shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_M), this);
    //    connect(shortcut, &QShortcut::activated, this, &coreplayer::on_mute_clicked);
    
        shortcut = new QShortcut(QKeySequence(Qt::Key_Left), this);
        connect(shortcut, SIGNAL(activated()), this, SLOT(seekLeft()));
        shortcut = new QShortcut(QKeySequence(Qt::Key_Right), this);
        connect(shortcut, SIGNAL(activated()), this, SLOT(seekRight()));
        shortcut = new QShortcut(QKeySequence(Qt::Key_Up), this);
        connect(shortcut, SIGNAL(activated()), this, SLOT(volumnUP()));
        shortcut = new QShortcut(QKeySequence(Qt::Key_Down), this);
        connect(shortcut, SIGNAL(activated()), this, SLOT(volumnDown()));
        //seekbar seeking(4s) by right left arrow
        //volumn up down by up down arrow
    }
    
    void coreplayer::closeEvent(QCloseEvent *event) {
        Q_UNUSED(event);
        on_stop_clicked();
    }
    
    void coreplayer::videoMimes() {
    
        QMimeDatabase mime;
        QList<QMimeType> d = mime.allMimeTypes();
    
        foreach (QMimeType s, d) {
            //Store for Video
            if (s.name().startsWith("video"))
                if (!s.preferredSuffix().isNull())
                    videomimes.append(s.name());
        }
    
    //    audiomimes.replace(audiomimes.indexOf("audio/mpeg"), "audio/mp3");//error
        videomimes.sort();
    }
    
    QStringList coreplayer::getVideos(const QString path) {
    
        QDir dir(path);
        QStringList videos;
        for (QString file : dir.entryList()) {
            if (file == "." || file == "..") {
                continue;
            }
                //for each video check the file.
                foreach (QString s, videomimes) {
                    if (QFileInfo(file).completeSuffix() == s.split("/").at(1) || QFileInfo(file).suffix() == s.split("/").at(1))
                        videos.append(path + "/" + file);
                }
        }
        return videos;
    }
    
    void coreplayer::audioMimes() {
    
        QMimeDatabase mime;
        QList<QMimeType> d = mime.allMimeTypes();
    
        foreach (QMimeType s, d) {
            //Store for Audio
            if (s.name().startsWith("audio"))
                if (!s.preferredSuffix().isNull())
                    audiomimes.append(s.name());
        }
    
        audiomimes.replace(audiomimes.indexOf("audio/mpeg"), "audio/mp3");
        audiomimes.sort();
    
    }
    
    QStringList coreplayer::getAudios(const QString path) {
    
        QDir dir(path);
        QStringList audios;
        for (QString file : dir.entryList()) {
            if (file == "." || file == "..") {
                continue;
            }
                //for each audio check the file.
                foreach (QString s, audiomimes) {
                    if ((QFileInfo(file).completeSuffix()) == (s.split("/").at(1)) || QFileInfo(file).suffix() == s.split("/").at(1))
                        audios.append(path + "/" + file);
                }
        }
        return audios;
    }
    
    bool coreplayer::isPlayerAvailable() const
    {
        return player->isAvailable();
    }
    
    void coreplayer::durationChanged(qint64 duration)
    {
        this->duration = duration/1000;
        ui->seekBar->setMaximum(duration / 1000);
    }
    
    void coreplayer::positionChanged(qint64 progress)
    {
        if (!ui->seekBar->isSliderDown()) {
            ui->seekBar->setValue(progress / 1000);
        }
        updateDurationInfo(progress / 1000);
    }
    
    void coreplayer::seek(int seconds)
    {
        player->setPosition(seconds * 1000);
    }
    
    void coreplayer::statusChanged(QMediaPlayer::MediaStatus status)
    {
        handleCursor(status);
    
        // handle status message
        switch (status) {
        case QMediaPlayer::UnknownMediaStatus:
        case QMediaPlayer::NoMedia:
        case QMediaPlayer::LoadedMedia:
        case QMediaPlayer::BufferingMedia:
        case QMediaPlayer::BufferedMedia:
    //        setStatusInfo(QString());
            break;
        case QMediaPlayer::LoadingMedia:
            messageEngine("Loading...", "Info");
            break;
        case QMediaPlayer::StalledMedia:
            messageEngine("Media Stalled", "Info");
            break;
        case QMediaPlayer::EndOfMedia:
            QApplication::alert(this);
            break;
        case QMediaPlayer::InvalidMedia:
            messageEngine("InvalidMedia", "Warning");
            break;
        }
    }
    
    void coreplayer::handleCursor(QMediaPlayer::MediaStatus status)
    {
    #ifndef QT_NO_CURSOR
        if (status == QMediaPlayer::LoadingMedia ||
            status == QMediaPlayer::BufferingMedia ||
            status == QMediaPlayer::StalledMedia)
            setCursor(QCursor(Qt::BusyCursor));
        else
            unsetCursor();
    #endif
    }
    
    void coreplayer::bufferingProgress(int progress)
    {
        messageEngine(tr("Buffering %4%").arg(progress), "Info");
    }
    
    void coreplayer::displayErrorMessage()
    {
        messageEngine(player->errorString(), "Warning");
    }
    
    void coreplayer::updateDurationInfo(qint64 currentInfo)
    {
        QString time;
        if (currentInfo || duration) {
            QTime currentTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000);
            QTime totalTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000);
            QString format = "mm:ss";
            if (duration > 3600)
                format = "hh:mm:ss";
            time = currentTime.toString(format) + " / " + totalTime.toString(format);
        }
        ui->duration->setText(time);
    }
    
    void coreplayer::openPlayer(const QString path) {
    
        QFileInfo sp(path);
        QString selectedFilePath;
        QModelIndex index = mModel->index(0, 0);
        sp.isDir() ? selectedFilePath = path : selectedFilePath = sp.path();
        mModel->clear();
        ui->folderLineEdit->setText(selectedFilePath);
        QStringList list1 = getAudios(selectedFilePath);
        QStringList list2 = getVideos(selectedFilePath);
        QStringList lists;
        lists.append(list1);
        lists.append(list2);
        list1.clear();
        list2.clear();
        lists = lists.toSet().toList();
        for (int i = 0; i < lists.count(); ++i) {
            mModel->appendRow((new QStandardItem(QFileInfo(lists.at(i)).fileName())));
            if (sp.isFile() && (sp.fileName() == mModel->index(i, 0).data().toString())) {
                index = mModel->index(i, 0);
            }
        }
        mModel->sort(0);
        mNumberOfFiles = lists.count();
        if(mNumberOfFiles > 0){
             ui->numberOfFiles->setVisible(1);
             ui->numberOfFiles->setText(QString("Included Files: %1").arg(mNumberOfFiles));
        }
        if(!path.isEmpty()){
            for (QPushButton *b : ui->navigation->findChildren<QPushButton*>()){
                b->setEnabled(true);
            }
            ui->seekBar->setEnabled(true);
            ui->volume->setEnabled(true);
            player->setMedia(QUrl::fromLocalFile(path));
            player->play();
            ui->play->setChecked(true);
            messageEngine("Playing", "Info");
        }
    
    }
    
    void coreplayer::on_open_clicked()
    {
        QFileDialog dialog(this, tr("Open Media File"));
        QStringList mimes;
        mimes.append(audiomimes);
        mimes.append(videomimes);
        dialog.setMimeTypeFilters(mimes);
        dialog.selectMimeTypeFilter("audio/mp3");
        if (dialog.exec() == QDialog::Accepted) { //if dialog pressed accept means open then do this.
            openPlayer(QFileInfo(dialog.selectedFiles().first()).path());
            messageEngine("Files Collected", "Info");
            for (QPushButton *b : ui->navigation->findChildren<QPushButton*>()){
                b->setEnabled(true);
            }
            ui->seekBar->setEnabled(true);
            ui->volume->setEnabled(true);
        } else {
            messageEngine("Files collection rejected", "Info");
        }
    }
    
    QMediaPlayer::State coreplayer::state() const
    {
        return playerState;
    }
    
    void coreplayer::setState(QMediaPlayer::State state)
    {
        if (state != playerState) {
            playerState = state;
    
            switch (state) {
            case QMediaPlayer::StoppedState:
                ui->play->setChecked(0);
                ui->stop->setChecked(1);
                break;
            case QMediaPlayer::PlayingState:
                ui->play->setChecked(1);
                ui->stop->setChecked(0);
                break;
            case QMediaPlayer::PausedState:
                ui->play->setChecked(0);
                ui->stop->setChecked(0);
                break;
            }
        }
    }
    
    void coreplayer::on_play_clicked(bool checked)
    {
        if (checked ){
            setState(QMediaPlayer::PlayingState);
            player->play();
            play(ui->medialist->currentIndex().row());
            messageEngine("Playing", "Info");
        }
        else if (!checked){
            setState(QMediaPlayer::PausedState);
            player->pause();
            messageEngine("Paused", "Info");
        }
    }
    
    void coreplayer::on_mute_clicked(bool checked)
    {
        if (checked){
            player->setMuted(true);
            messageEngine("Mute", "Info");
        }
        else{
            player->setMuted(false);
        }
    }
    
    void coreplayer::on_volume_valueChanged(int value)
    {
       player->setVolume(value);
       QString vol = QString::number(value);
       ui->volume->setValue(value);
       messageEngine(vol, "Info");
    }
    
    void coreplayer::on_stop_clicked()
    {
        ui->stop->setEnabled(false);
        player->stop();
        ui->play->setChecked(false);
        player->setPosition(0);
        player->setMedia(NULL);
        ui->duration->setText("00:00 / 00:00");
        ui->workingOn->setText("");
        messageEngine("Stop", "Info");
    }
    
    void coreplayer::on_next_clicked()
    {
        player->stop();
        play(ui->medialist->currentIndex().row() + 1);
    }
    
    void coreplayer::on_previous_clicked()
    {
        player->stop();
        play(ui->medialist->currentIndex().row() - 1);
    }
    
    void coreplayer::setCurrentIndex(int currentIndex)
    {
        ui->medialist->setCurrentIndex(mModel->index(currentIndex, 0));
    }
    
    void coreplayer::setFolder(const QString &foldername)
    {
        mModel->clear();
        ui->folderLineEdit->setText(foldername);
        QStringList list1 = getAudios(foldername);
        QStringList list2 = getVideos(foldername);
    
        for (int i = 0; i < list1.count(); ++i) {
            mModel->appendRow((new QStandardItem(QFileInfo(list1.at(i)).fileName())));
        }
    
        for (int i = 0; i < list2.count(); ++i) {
            mModel->appendRow((new QStandardItem(QFileInfo(list2.at(i)).fileName())));
        }
    
        mNumberOfFiles = list1.count() + list2.count();
        ui->numberOfFiles->setText(QString("Included Files: %1")
                                        .arg(mNumberOfFiles));
    }
    
    void coreplayer::play(int index)
    {
        auto mediaPlayerState = player->state();
        if (mediaPlayerState == QMediaPlayer::PausedState) {
            player->play();
            return;
        } else if (mediaPlayerState == QMediaPlayer::PlayingState) {
            return;
        }
        if (index == -1 || index >= mNumberOfFiles) {
            return;
        }
        auto filename = ui->folderLineEdit->text()
                + "/" + mModel->index(index, 0).data().toString();
        player->setMedia(QUrl::fromLocalFile(filename));
        player->play();
        ui->medialist->setCurrentIndex(mModel->index(index, 0));
        ui->medialist->currentIndex().data().toInt();
        ui->workingOn->setText(mModel->index(index, 0).data().toString());
    }
    
    void coreplayer::on_medialist_doubleClicked(const QModelIndex &index)
    {
        player->stop();
        play(index.row());
        ui->play->setChecked(true);
        messageEngine("Playing", "Info");
    }
    
    void coreplayer::seekLeft() {
        if (!(ui->seekBar->value() == 0))
        {seek(ui->seekBar->value() - 4);}
    }
    
    void coreplayer::seekRight() {
        if (!(ui->seekBar->value() == ui->seekBar->maximum()))
        {seek(ui->seekBar->value() + 4);}
    }
    
    void coreplayer::volumnDown() {
        int x = ui->volume->value() - 5;
        if (!(ui->volume->value() == 0))
        {on_volume_valueChanged(x);}
    }
    
    void coreplayer::volumnUP() {
        int x = ui->volume->value() + 5;
        if (!(x == ui->volume->maximum()))
        { on_volume_valueChanged(x); }
    }
    
    void coreplayer::on_playlist_clicked(bool checked)
    {
        if(checked){
            ui->shortcut->setVisible(1);
        }else{
            ui->shortcut->setVisible(0);
        }
    }
    
    

    here is header

    
    #ifndef COREPLAYER_H
    #define COREPLAYER_H
    
    #include <QWidget>
    #include <QAbstractItemView>
    #include <QVideoProbe>
    #include <QVideoWidget>
    #include <QAudioProbe>
    #include <QStandardItemModel>
    #include <QMediaPlayer>
    #include <QCloseEvent>
    #include <QModelIndex>
    #include <QMediaPlaylist>
    
    #include "../corebox/corebox.h"
    #include "../corebox/globalfunctions.h"
    
    
    namespace Ui {
    class coreplayer;
    }
    
    class QAbstractItemView;
    class QLabel;
    class QVideoProbe;
    class QVideoWidget;
    class QAudioProbe;
    class QStandardItemModel;
    
    
    class coreplayer : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit coreplayer(QWidget *parent = 0);
        ~coreplayer();
    
        void openPlayer(const QString path);
    
        bool isPlayerAvailable() const;
        QMediaPlayer::State state() const;
    
    protected:
        void closeEvent(QCloseEvent *event);
    
    public slots:
        void setState(QMediaPlayer::State state);
    
    private:
        Ui::coreplayer *ui;
    
        QStringList getAudios(const QString path);
        QStringList getVideos(const QString path);
        QStringList videomimes;
        QStringList audiomimes;
    
        void audioMimes();
        void videoMimes();
        void setTrackInfo(const QString &info);
        void setStatusInfo(const QString &info);
        void handleCursor(QMediaPlayer::MediaStatus status);
        void updateDurationInfo(qint64 currentInfo);
        void setFolder(const QString &foldername);
        void play(int index);
        void setCurrentIndex(int currentIndex);
        void shotcuts();
    
        int mNumberOfFiles;
        QMediaPlayer::State playerState;
        QMediaPlayer *player;
        QVideoProbe *videoProbe;
        QAudioProbe *audioProbe;
        QAbstractItemView *medialist;
        qint64 duration;
        QStandardItemModel *mModel;
    
    private slots:
        void seekLeft();
        void seekRight();
        void volumnUP();
        void volumnDown();
    
        void durationChanged(qint64 duration);
        void positionChanged(qint64 progress);
        void seek(int seconds);
        void statusChanged(QMediaPlayer::MediaStatus status);
        void bufferingProgress(int progress);
        void displayErrorMessage();
    
        void on_open_clicked();
        void on_previous_clicked();
        void on_play_clicked(bool checked);
        void on_mute_clicked(bool checked);
        void on_volume_valueChanged(int value);
        void on_stop_clicked();
        void on_next_clicked();
        void on_medialist_doubleClicked(const QModelIndex &index);
        void on_playlist_clicked(bool checked);
    };
    
    #endif // COREPLAYER_H
    
    

    here is the ui

    0_1526796754092_t.png

    here is the problems

    0 - after stop clicked player widget turns to white color
    0 - after stop ,play button dose not work .
    0 - while playing it refresh the video widget every frame or second.


  • Lifetime Qt Champion

    Hi
    set break points in start and stop
    single step the code and see what happens.
    Its the best way to find out why logic does not work.



  • ok . i found the problem for "after stop ,play button dose not work "
    ui->medialist->currentIndex().row() this giving -1 that's why .

    here is the fix

    void coreplayer::on_play_clicked(bool checked)
    {
        if (checked ){
            setState(QMediaPlayer::PlayingState);
            player->play();
            if(ui->medialist->currentIndex().row() != -1){play(ui->medialist->currentIndex().row());}
            else{play(0);}
            if(ui->shortcut->isVisible()){ui->shortcut->setVisible(false);}
            messageEngine("Playing", "Info");
        }
        else if (!checked){
            setState(QMediaPlayer::PausedState);
            player->pause();
            messageEngine("Paused", "Info");
        }
    }
    

    @mrjj any fix for the first and the third one ??


  • Lifetime Qt Champion

    @saber
    Im not really sure what turns to white means. Is it still alive ?

    • 0 - while playing it refresh the video widget every frame or second.
      refreshes in what way ? Dont it play by itself?


  • @mrjj
    when app starts video widget is black.
    when i stop the player, the video widget turns into white.
    pause state
    0_1526807874936_a2.png

    stop state
    0_1526807913139_a1.png

    0 - while playing it refresh the video widget every frame or second.

    means while it's playing the playback flickers . after every second videowidget shows a white page , like second picture.


  • Lifetime Qt Champion

    @saber
    Hi
    Did you try a small code sample and play the same video and check if is normal ?
    I have zero idea what the white thing u seen during play back is.


  • Lifetime Qt Champion

    Hi
    @saber said in help to fix some problem in my QmediaPlayer:

    if (checked ){
    //snip
    }
    else if (!checked){
    //snip
    }

    The second if is useless and even makes your code unclear. else is enough as checked is a boolean value.


Log in to reply