Qt/C++ - Lesson 051. QMediaPlayer – simple audio player

I suggest to write a simple audio player for mp3 files using Qt/C++, which will have a playlist, the ability to start / pause / stop tracks, as well as scroll through the tracks.

For the implementation of this ideas in Qt, classes are QMediaPlayer and QMediaPlaylist, which belong to the multimedia module. And to display the playlist and use QStandardItemModel QTableView.

Articles in this series:

Project structure

  • SimplePlayer.pro - the profile of the project;
  • main.cpp - the file with the main function;
  • widget.ui - form of application window;
  • widget.h - header file of the application window;
  • widget.cpp - file source code of the application window;
  • buttons.qrc - resource file application icon buttons.

widget.ui

The application interface is made using a graphic designer, and it have look as follows.

The application interface consists of the following elements:

  • btn_add (QToolButton*) - responsible for adding tracks to the playlist;
  • btn_next (QToolButton*) - responsible for flipping the playlist ahead;
  • btn_previous (QToolButton*) - responsible for flipping playlist ago;
  • btn_play (QToolButton*) - responsible for track playback;
  • btn_pause (QToolButton*) - responsible for setting the track is paused;
  • btn_stop (QToolButton*) - responsible for track stop;
  • currentTrack (QLabel*) - label, which will display the current track;
  • playlistView (QTableView*) - table, which displays the playlist.

SimplePlayer.pro

The project profile that you connect the multimedia module, otherwise QMediaPlayer and QMediaPlaylist classes will be not available.

#-------------------------------------------------
#
# Project created by QtCreator 2016-06-29T11:25:56
#
#-------------------------------------------------

QT       += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = SimplePlayer
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

RESOURCES += \
    buttons.qrc

widget.h

To implement the playlist display, have to use QStandardItemModel. In it will be placed in the path of audio files and audio file names. The first column is the name of the audio file, and the second will be the full path, but this column will be hidden in a QTableView object, which will be responsible for mapping Playlist.

Also, the path to the file as a media source will need to be put in QMediaPlaylist object that will be placed in QMediaPlayer.

Pointers to these objects are placed in the header file of the application window. Also here there avtogenerirovany through designer interface slot to press the button add tracks to the playlist processing.

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QStandardItemModel>
#include <QMediaPlayer>
#include <QMediaPlaylist>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_btn_add_clicked();              // The slot for the processing of adding tracks through dialog

private:
    Ui::Widget *ui;
    QStandardItemModel  *m_playListModel;   // Data Model for Playlist
    QMediaPlayer        *m_player;          
    QMediaPlaylist      *m_playlist;       
};

#endif // WIDGET_H

widget.cpp

For realization of the player it is necessary to initialize the object QMediaPlayer , QMediaPlaylist and QStandardItemModel , which have been declared in the header file of the application window. In the first half of the designer made customize the appearance of the table to display the playlist, while the second setting of the player. player controlled via the buttons that are connected to the control slots m_playlist (for navigation) and m_player (to start / pause / stop).

If you change the current track, the player will automatically terminates playback of the track that was before the change, and starts to play a new track.

Due to the fact that QMediaPlaylist has no model to be displayed in the table, we use the QStandardItemModel class, so you have to add data about file paths and there and there.

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QDir>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_playListModel = new QStandardItemModel(this);
    ui->playlistView->setModel(m_playListModel);    
    m_playListModel->setHorizontalHeaderLabels(QStringList()  << tr("Audio Track")
                                                            << tr("File Path"));
    ui->playlistView->hideColumn(1);   
    ui->playlistView->verticalHeader()->setVisible(false);                  
    ui->playlistView->setSelectionBehavior(QAbstractItemView::SelectRows);  
    ui->playlistView->setSelectionMode(QAbstractItemView::SingleSelection); 
    ui->playlistView->setEditTriggers(QAbstractItemView::NoEditTriggers);  
    ui->playlistView->horizontalHeader()->setStretchLastSection(true);

    m_player = new QMediaPlayer(this);          // Init player
    m_playlist = new QMediaPlaylist(m_player);  // Init playlist
    m_player->setPlaylist(m_playlist);          
    m_player->setVolume(70);                    
    m_playlist->setPlaybackMode(QMediaPlaylist::Loop);  // Set circular play mode playlist

    // подключаем кнопки управления к слотам управления
    // Here we note that the navigation is done through the playlist playlist
    // and start / pause / stop via the player itself
    connect(ui->btn_previous, &QToolButton::clicked, m_playlist, &QMediaPlaylist::previous);
    connect(ui->btn_next, &QToolButton::clicked, m_playlist, &QMediaPlaylist::next);
    connect(ui->btn_play, &QToolButton::clicked, m_player, &QMediaPlayer::play);
    connect(ui->btn_pause, &QToolButton::clicked, m_player, &QMediaPlayer::pause);
    connect(ui->btn_stop, &QToolButton::clicked, m_player, &QMediaPlayer::stop);

    // When you doubleclick on the track in the table set the track in the playlist
    connect(ui->playlistView, &QTableView::doubleClicked, [this](const QModelIndex &index){
        m_playlist->setCurrentIndex(index.row());
    });

    // if the current track of the index change in the playlist, set the file name in a special label
    connect(m_playlist, &QMediaPlaylist::currentIndexChanged, [this](int index){
        ui->currentTrack->setText(m_playListModel->data(m_playListModel->index(index, 0)).toString());
    });
}

Widget::~Widget()
{
    delete ui;
    delete m_playListModel;
    delete m_playlist;
    delete m_player;
}

void Widget::on_btn_add_clicked()
{
    // Using the file selection dialog to make multiple selections of mp3 files
    QStringList files = QFileDialog::getOpenFileNames(this,
                                                      tr("Open files"),
                                                      QString(),
                                                      tr("Audio Files (*.mp3)"));

    // Next, set the data names and file paths
    // into the playlist and table displaying the playlist
    foreach (QString filePath, files) {
        QList<QStandardItem *> items;
        items.append(new QStandardItem(QDir(filePath).dirName()));
        items.append(new QStandardItem(filePath));
        m_playListModel->appendRow(items);
        m_playlist->addMedia(QUrl(filePath));
    }
}

Result

Once the app is started, you can open the mp3 tracks and listen to them.

Download Qt Audio Player

Video

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate
S

Скажите, пожалуйста, как на линуксе исправить ошибку , связанную с непраильной схемой пути к файлу - "Error: "Invalid URI ...."" и далее соответственно GSteamer; unable to pause...

На официальном форуме указано на то, что "when passing local file to the media player, you need to use the "file://" scheme so it knows it has to look in to the file system." Но что конкретно из этого стоит вынести, не ясно.
Благодарен за внимание.

Ответил на форуме

Comments

Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it
Donate

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways

PayPalYandex.Money
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
AS
May 26, 2020, 11:29 a.m.
Artem Sun-Dun-Chan

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
MN
May 25, 2020, 11:33 a.m.
Mitja Nagibin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
f
May 25, 2020, 5:05 a.m.
falcon

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
Last comments
May 28, 2020, 3:14 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Ну в моём примере, который в статье сработало так model->setData(model->index(1, 1), 7); Поскольку model->index(1, 0) - это индекс колонки id, которая скрыта, поэтому…
MA
May 28, 2020, 3:08 p.m.
Mihail A

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Спасибо, завтра првоерю. А model->setData(model->index(1, 0), 7); Тоже заработало?
May 28, 2020, 3:06 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Да, метод data всё-таки влиял, я переписал его так и заработало удаление QVariant TableModel::data(const QModelIndex &idx, int role) const{ if (role == Qt::BackgroundColorRole) {…
May 28, 2020, 2:49 p.m.
Evgenij Legotskoj

Django - Tutorial 011. Adding comments to the site based on Django

Он более функциональный и его функционал объективно лучше поддерживается Django. Из первого, что приходит на ум: Это наличие полей типа Array Поддержка полей для JSON …
May 28, 2020, 2:42 p.m.
progammist

Django - Tutorial 011. Adding comments to the site based on Django

а в чем явное преимущество postgresql над mysql?)
Now discuss on the forum
IP
May 29, 2020, 1:55 a.m.
Igor' Poroshin

QTablwView + QSqlQueryModel скрыть пустой столбец

Да, понятно. В данном случае лучше использовать серверную процедуру (если такие поддерживаются), в которой будет проверяться наличие всех пустых строк у нужного столбца и вызываться соответ…
RG
May 28, 2020, 6:21 p.m.
Rovshan Gurbanov

Сборка под старые версии Android

У меня SDK почти все версии есть, NDK есть версии 10, 17, 21. Но собирается приложение только с NDK v21 под Android версии 7.0 и выше Версия Qt у меня 5.14.2
May 28, 2020, 7:58 a.m.
Evgenij Legotskoj

Освобождение памяти QMainWindow::setCentralWidget

Да, соглашусь. Просто удаление происходит позже, а не сразу.
May 28, 2020, 5:43 a.m.
Mihailll

При подключении к git как указать пароль?

Нужно сделать ssh-keygen и потом полученый из файла код скопировать в ssh ключ в бикбакете
F
May 28, 2020, 1:42 a.m.
Fidan

QML

Да, проблема ушла, спасибо.
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB