Media player not working for multiple videos
-
@jsulm
I am not using mediaPlayer as global variable . Here is my updated codeMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->listWidget->setFlow(QListView::LeftToRight); ui->listWidget->setMinimumSize(760,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(); //player = new QMediaPlayer(this,QMediaPlayer::VideoSurface); //player = new QVector<QMediaPlayer*>(); //playlist = new QMediaPlaylist; // playlist->addMedia(QUrl::fromLocalFile(finfo.absoluteFilePath())); //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); scene->addItem(videoItem); mediaPlayer->setVideoOutput(videoItem); player.append(mediaPlayer); 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)); m_positionSlider = new QSlider(Qt::Horizontal); m_positionSlider->setRange(0, 0); connect(m_playButton, &QAbstractButton::clicked, this, &MainWindow::play); connect(m_positionSlider, &QAbstractSlider::sliderMoved,this, &MainWindow::setPosition); 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(); } bool MainWindow::isPlayerAvailable() const { QMediaPlayer *mediaPlayer = player[1]; return mediaPlayer->isAvailable(); } 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; } }); } void MainWindow::mediaStateChanged(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; } } 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); }
-
@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; } });
-
@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);
-
@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; } });
-
@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.
-
@jsulm
Here is the codeMainWindow::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); }
-
@Devopia53 No, it can:
auto l = [this]() { // use members of this here }
-
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 codeQSlider *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); });
-
@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 rangem_positionSlider->setRange(0, 0);
You can use http://doc.qt.io/qt-5/qmediaplayer.html#duration-prop to set the range.
-
I know that well(as
[&]
or[=]
). But what I have described is that you have captured the member variables of thethis
object directly. Take a look at his source code. here:connect(mediaPlayer, &QMediaPlayer::stateChanged, [m_playButton, this](QMediaPlayer::State state)
Am_playButton
is a member of thethis
. -