Media player not working for multiple videos


  • Moderators

    @Kinesis
    your still not doing what @jsulm suggested.

    this

    void MainWindow::play()
    {
        QMediaPlayer *mediaPlayer = player[1];
        connect(m_playButton, &QAbstractButton::clicked, [mediaPlayer]() {
        switch (mediaPlayer->state()) {
        case QMediaPlayer::PlayingState:
            mediaPlayer->pause();
            break;
        default:
            mediaPlayer->play();
            break;
        }
    });
    }
    

    is wrong and at the wrong place

    delete that function all together

    and in your loop replace

    connect(m_playButton, &QAbstractButton::clicked, this, &MainWindow::play);
    

    with

    @jsulm said in Media player not working for multiple videos:

    connect(m_playButton, &QAbstractButton::clicked, [mediaPlayer]() {
        switch (mediaPlayer->state()) {
        case QMediaPlayer::PlayingState:
            mediaPlayer->pause();
            break;
        default:
            mediaPlayer->play();
            break;
    }
    });

  • Qt Champions 2018

    @Kinesis You should think about the code you're writing and you should read what I'm writing more carefully. To be honest I'm tired of writing code for you and then see that you're not trying it but doing something else. The code you posted now is NOT what I suggested (again).

    void MainWindow::play()
    {
        QMediaPlayer *mediaPlayer = player[1];
    

    Do you really think this code can work correctly? You always try to use SECOND player! How is it going to work?!
    I post here my code once more, but for the last time:

    for(const QFileInfo & finfo: directory.entryInfoList()){
        QMediaPlayer *mediaPlayer = new QMediaPlayer(); // DO NOT USE GLOBAL mediaPlayer!
        mediaPlayer->setMedia(QUrl::fromLocalFile(finfo.absoluteFilePath()));
    ...
        connect(m_playButton, &QAbstractButton::clicked, [mediaPlayer]() {
            switch (mediaPlayer->state()) {
            case QMediaPlayer::PlayingState:
                mediaPlayer->pause();
                break;
            default:
                mediaPlayer->play();
                break;
        }
        });
    ...
        mediaPlayer->setVideoOutput(m_videoItem);
        m_mediaPlayer.append(mediaPlayer);
    


  • @jsulm
    I got it now . Sorry for wasting your time . Now I can play both videos . Do I need to replace the button state change into loop? Because button state(Icon) is not changing correctly and linking with other media players.


  • Qt Champions 2018

    @Kinesis You need to change all your other slots for mediaPlayer in the same way as play():

    connect(mediaPlayer, &QMediaPlayer::stateChanged, [m_playButton, this](QMediaPlayer::State state) {
        switch(state) {
        case QMediaPlayer::PlayingState:
            m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
            break;
        default:
            m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
            break;
        }
    });
    


  • @jsulm
    I got a lambda issue for "m_playButton" . The message is " m_play Button in capture list does not name a variable.


  • Qt Champions 2018

    @Kinesis Please show your code...
    You need to put the code I shown AFTER you created m_playButton.


  • Qt Champions 2018

    @Kinesis I will tell you my insights from reading this thread: you should really take a C++ book and start with simple examples.

    you are lacking simple programming knowledge, sorry. most of your problems are not related to Qt.

    So please, start learning C++. it will help you a lot.



  • @aha_1980
    Thanks for your suggestion . I am learning c++ now . I also like to try writing UI that's why I am approaching QT .



  • @jsulm
    Here is the code

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        
        ui->listWidget->setFlow(QListView::LeftToRight);
        ui->listWidget->setMinimumSize(1200,350);
        ui->listWidget->setGridSize(QSize(360, 360));
        ui->listWidget->setResizeMode(QListView::Adjust);
        ui->listWidget->setViewMode(QListView::ListMode);
        ui->listWidget->setWrapping(true);
        
        QDir directory = QFileDialog::getExistingDirectory(this, tr("Open Directory"),"/home",
                                                           
                                                           QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);
        
        directory.setNameFilters({"*.mp4" , "*.avi" , "*.flv" , "*.mwv"});
        
        for(const QFileInfo & finfo: directory.entryInfoList()){
            QMediaPlayer *mediaPlayer = new QMediaPlayer();
            mediaPlayer->setMedia(QUrl::fromLocalFile(finfo.absoluteFilePath()));
            // mediaPlayer->setMedia(playlist);
            videoItem = new QGraphicsVideoItem;
            videoItem->setSize(QSize(320,240));
            QGraphicsScene *scene = new QGraphicsScene(this);
            QGraphicsView *graphicsView = new QGraphicsView(scene);
            
            
            
            
            mediaPlayer->setVideoOutput(videoItem);
            player.append(mediaPlayer);
            scene->addItem(videoItem);
            
            connect(mediaPlayer, &QMediaPlayer::stateChanged, this, &MainWindow::mediaStateChanged);
            
            connect(mediaPlayer, &QMediaPlayer::positionChanged, this, &MainWindow::positionChanged);
            connect(mediaPlayer, &QMediaPlayer::durationChanged, this, &MainWindow::durationChanged);
            
            m_playButton = new QPushButton;
            m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
            
            connect(m_playButton, &QAbstractButton::clicked, [mediaPlayer]() {
                switch (mediaPlayer->state()) {
                case QMediaPlayer::PlayingState:
                    mediaPlayer->pause();
                    break;
                default:
                    mediaPlayer->play();
                    break;
                }
            });
            
            connect(mediaPlayer, &QMediaPlayer::stateChanged, [m_playButton, this](QMediaPlayer::State state) {
                switch(state) {
                case QMediaPlayer::PlayingState:
                    m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
                    break;
                default:
                    m_playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
                    break;
                }
            });
            
            
            //connect(m_playButton, &QAbstractButton::clicked, this, &MainWindow::play);
            //connect(m_positionSlider, &QAbstractSlider::sliderMoved,this, &MainWindow::setPosition);
            
            
            
            m_positionSlider = new QSlider(Qt::Horizontal);
            m_positionSlider->setRange(0, 0);
            
            
            auto    item = new QListWidgetItem("", ui->listWidget);
            auto    widget = new QWidget;
            auto    label = new QLabel(finfo.fileName());
            auto    vb = new QVBoxLayout;
            
            QBoxLayout *controlLayout = new QHBoxLayout;
            controlLayout->setMargin(0);
            controlLayout->addWidget(m_playButton);
            controlLayout->addWidget(m_positionSlider);
            
            vb->addWidget(label,1);
            vb->addWidget(graphicsView,9);
            vb->addLayout(controlLayout);
            widget->setLayout(vb);
            widget->setMinimumSize(340, 340);
            ui->listWidget->setItemWidget(item,widget);
            
            
        }
            
    }
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    QSize MainWindow::sizeHint() const
    {
        return (videoItem->size() * qreal(3) / qreal(2)).toSize();
    }
    
    void MainWindow::positionChanged(qint64 position)
    {
        m_positionSlider->setValue(position);
    }
    
    void MainWindow::durationChanged(qint64 duration)
    {
        m_positionSlider->setRange(0, duration);
    }
    
    void MainWindow::setPosition(int position)
    {
        QMediaPlayer *mediaPlayer = player[1];
        mediaPlayer->setPosition(position);
    }
    

  • Qt Champions 2018

    @Kinesis And exactly this code does not build?



  • @Kinesis

    Declare QPushButton as a local variable like a mediaPlayer. A lambda function can not capture member variables of this.


  • Qt Champions 2018

    @Devopia53 No, it can:

    auto l = [this]() {
      // use members of this here
    }
    


  • @jsulm - Yes it does not work
    @Devopia53 - When I declare local variable , it works.
    @aha_1980 - I will also try like U said .
    Sorry for replying in the same reply . Because I am a new user . I can only post per every 600s



  • I still have a question . I replaced the slider slots into loop but I can't control the sliders and sliders are not moving when the videos are running .
    Here is the slider code

    QSlider *m_positionSlider = new QSlider(Qt::Horizontal);
            m_positionSlider->setRange(0, 0);
    
           
            connect(mediaPlayer, &QMediaPlayer::positionChanged ,[m_positionSlider, this](qint64 position){
    
                m_positionSlider->setValue(position);
            });
    
            connect(mediaPlayer, &QMediaPlayer::durationChanged ,[m_positionSlider, this](qint64 duration){
    
                m_positionSlider->setRange(0,duration);
            });
    
    
            connect(mediaPlayer , &QMediaPlayer::setPosition, [mediaPlayer ,this] (int position){
    
                mediaPlayer->setPosition(position);
            });
    
    

  • Qt Champions 2018

    @Kinesis What is this:

    connect(mediaPlayer , &QMediaPlayer::setPosition, [mediaPlayer ,this] (int position){
    
                mediaPlayer->setPosition(position);
            });
    

    ?
    QMediaPlayer::setPosition() is a slot not a signal.
    I think you need to change the range

    m_positionSlider->setRange(0, 0);
    

    You can use http://doc.qt.io/qt-5/qmediaplayer.html#duration-prop to set the range.



  • @aha_1980

    I know that well(as [&] or [=]). But what I have described is that you have captured the member variables of the this object directly. Take a look at his source code. here: connect(mediaPlayer, &QMediaPlayer::stateChanged, [m_playButton, this](QMediaPlayer::State state)
    A m_playButton is a member of the this.



  • @jsulm
    Thanks for your suggestion . Now the slider is running along with video.But to use it like skip slider how should I correct this "QMediaPlayer::setPosition() " which is a slot but not a signal ?By the way , sorry for late response .


  • Qt Champions 2018

    @Kinesis You don't need

    connect(mediaPlayer , &QMediaPlayer::setPosition, [mediaPlayer ,this] (int position){
    
                mediaPlayer->setPosition(position);
            });
    

    You're already using QMediaPlayer::positionChanged...



  • @jsulm
    I got this. It's done now. My code is working fully 100% now . Thanks a lot for helping me . I fell bad that I wasted your time . By the way should I upload my
    code ? It might help someone . Thanks.


  • Qt Champions 2018

    @Kinesis No need to feel bad - I'm helping here voluntary :-)
    I don't think you need to upload your code. If somebody has questions he/she can ask.