Evgenii Legotckoi
Evgenii LegotckoiJune 29, 2016, 9:06 a.m.

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.

Do you like it? Share on social networks!

S
  • June 10, 2017, 3:26 a.m.

Скажите, пожалуйста, как на линуксе исправить ошибку , связанную с непраильной схемой пути к файлу - "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." Но что конкретно из этого стоит вынести, не ясно.
Благодарен за внимание.
Evgenii Legotckoi
  • June 10, 2017, 10:35 a.m.

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

DV
  • April 27, 2021, 3:40 p.m.

Добрый вечер. Хотел бы получить консультацию по работе с проектом на Mac OS. Открыл проект в QT и собрал его. Проблема в том, что он не воспроизводит треки и их названия зацикленно мелькают в поле текущего трека. По системе:
- Mac OS 10.14
- QT 5.15.2
- XCode 10.2
С чем это может быть связано. Заранее благодарен.

Evgenii Legotckoi
  • July 2, 2021, 5:09 a.m.

С Mac OS опыта работы не имею на данный момент

можно ли из этого плеера сделать многоканалов воспроизведения ?

нет

есть такая вообще возможность ?

Evgenii Legotckoi
  • June 21, 2022, 6:26 a.m.
  • (edited)

Не думаю, QMediaPlayer в один поток проигрывает. Если вам нужно одновременное воспроизведение нескольких аудиоисточников, то вам нужна Bass audio library , насколько знаю, её обычно используют для подобных вещей.

Р5
  • Sept. 13, 2022, 8:54 a.m.

Здравствуйте. Подскажите пожалуйста, как решить проблему
multimedia модуль не распознается

juvf
  • Nov. 25, 2022, 1:14 a.m.

Добрый день.
Подскажите, как можно перехватить в Qt или Qml уровень воспроизводимого звука? Т.е. требуется сделать виртуальный винтажный индикатор (стрелочный или светодиодный), который бы показывал уровень звука. И желательно без усилиения. Т.е. в файле mp3 допустим записана синусоида 1000 кГц, амплитудой 0.5 (минимальный уровень 0.0, макс 1.0), то на индикаторе должно быть 0.5, в независимости от того, как выкручена громкость на регуляторе звука плеера, винды/линукса, калонок или внешнего УМ. Как такое возможно реализовать (желательно кроссплатформено с помощью qt/qml)? Куда копать? Как-то перехватывать декодирование mp3 и допустим раз в 100 мс обновлять виджет "Индикатор"?

Evgenii Legotckoi
  • Dec. 12, 2022, 4:05 a.m.

Qt не располагает средствами для визуализации формы звукового сигнала в файле. То есть из модуля Qt multimedia вы не сможете забрать график звука а потом его обработать так, чтобы вы получали нужный вам результат. Это нужно реализовывать с помощью сторонних библиотек, а потом отрисовывать уже в Qt/Qml. Возможно Bass Dll может в этом помочь.

juvf
  • Dec. 12, 2022, 4:06 a.m.

Спасибо.

juvf
  • Jan. 16, 2023, 10:18 p.m.

PS. Почти дописал плеер на QML. Уперся в ограничения QML. Переписываю плеер на с++/qt, а графика останится в qml. Нашел то, что мне надо, а именно индикатор звука. Qt может перехватывать аудиопоток и анализировать уровень звука. Кому интересно - подробно в примерах в QtCreator "Media Player Example".

Evgenii Legotckoi
  • Feb. 7, 2023, 5:32 a.m.

А он анализирует уровень звука по частотам, как эквайлайзер? Я просто подумал, что вам как в аналоговом эквалайзере нужно...

Comments

Only authorized users can post comments.
Please, Log in or Sign up
B

C++ - Test 002. Constants

  • Result:16points,
  • Rating points-10
B

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

  • Result:46points,
  • Rating points-6
FL

C++ - Test 006. Enumerations

  • Result:80points,
  • Rating points4
Last comments
k
kmssrFeb. 9, 2024, 5:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVADec. 25, 2023, 9:30 p.m.
Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJoDec. 25, 2023, 7:38 p.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
GvozdikDec. 19, 2023, 8:01 a.m.
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
AC
Alexandru CodreanuJan. 19, 2024, 10:57 p.m.
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…
BlinCT
BlinCTDec. 27, 2023, 7:57 p.m.
Растягивать Image на парент по высоте Ну и само собою дял включения scrollbar надо чтобы был Flickable. Так что выходит как то так Flickable{ id: root anchors.fill: parent clip: true property url linkFile p…
Дмитрий
ДмитрийJan. 10, 2024, 3:18 p.m.
Qt Creator загружает всю оперативную память Проблема решена. Удалось разобраться с помощью утилиты strace. Запустил ее: strace ./qtcreator Начал выводиться весь лог работы креатора. В один момент он начал считывать фай…
Evgenii Legotckoi
Evgenii LegotckoiDec. 12, 2023, 5:48 p.m.
Побуквенное сравнение двух строк Добрый день. Там случайно не высылается этот сигнал textChanged ещё и при форматировани текста? Если решиать в лоб, то можно просто отключать сигнал/слотовое соединение внутри слота и …

Follow us in social networks