Evgenii Legotckoi
29 июня 2016 г. 19:06

Qt/C++ - Урок 051. QMediaPlayer - Аудио плеер на Qt

Предлагаю написать простенький аудио плеер для mp3 файлов с использованием Qt/C++, который будет иметь плейлист, возможность запуска/паузы/остановки треков, а также пролистывания треков.

Для реализации данной задумки в Qt имеются классы QMediaPlayer и QMediaPlaylist, которые относятся к модулю multimedia. А для отображения плейлиста воспользуемся QStandardItemModel и QTableView.

Статьи данного цикла:

Структура проекта

  • SimplePlayer.pro - профайл проекта;
  • main.cpp - файл с функцией main;
  • widget.ui - файл формы окна приложения;
  • widget.h - заголовочный файл окна приложения;
  • widget.cpp - файл исходных кодов окна приложения;
  • buttons.qrc - ресурсный файл иконок кнопок приложения.

widget.ui

Интерфейс приложения сделаем с использованием графического дизайнера, и выглядеть он должен будет следующим образом.

В состав интерфейса приложения входят следующие элементы:

  • btn_add (QToolButton*) - отвечает за добавление треков в плейлист;
  • btn_next (QToolButton*) - отвечает за пролистывание плейлиста вперёд;
  • btn_previous (QToolButton*) - отвечает за пролистывание плейлиста назад;
  • btn_play (QToolButton*) - отвечает за воспроизведение трека;
  • btn_pause (QToolButton*) - отвечает за постановку трека на паузу;
  • btn_stop (QToolButton*) - отвечает за остановку трека;
  • currentTrack (QLabel*) - лейбл, в котором будет отображаться текущий трек;
  • playlistView (QTableView*) - таблица, отвечающая за отображение плейлиста.

SimplePlayer.pro

В профайле проекта не забудьте подключить модуль multimedia, иначе классы QMediaPlayer и QMediaPlaylist будут недоступны.

  1. #-------------------------------------------------
  2. #
  3. # Project created by QtCreator 2016-06-29T11:25:56
  4. #
  5. #-------------------------------------------------
  6.  
  7. QT += core gui multimedia
  8.  
  9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  10.  
  11. TARGET = SimplePlayer
  12. TEMPLATE = app
  13.  
  14.  
  15. SOURCES += main.cpp\
  16. widget.cpp
  17.  
  18. HEADERS += widget.h
  19.  
  20. FORMS += widget.ui
  21.  
  22. RESOURCES += \
  23. buttons.qrc

widget.h

Для реализации отображения плейлиста, придется использовать QStandardItemModel. В неё будут помещаться пути к аудио файлам, а также имена аудио файлов. В первой колонке будет имя аудио файла, а во второй будет полный путь, но данная колонка будет скрыта в объекте QTableView, который будет отвечать за отображение плейлиста.

Также пути к файлом в качестве медиа источников необходимо будет поместить в объект QMediaPlaylist, который будет помещён в QMediaPlayer.

Указатели на эти объекты помещаются в заголовочном файле окна приложения. Также здесь присутствует автогенерированый через дизайнер интерфейсов слот для обработки нажатия по кнопке добавления треков в плейлист.

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <QStandardItemModel>
  6. #include <QMediaPlayer>
  7. #include <QMediaPlaylist>
  8.  
  9. namespace Ui {
  10. class Widget;
  11. }
  12.  
  13. class Widget : public QWidget
  14. {
  15. Q_OBJECT
  16.  
  17. public:
  18. explicit Widget(QWidget *parent = 0);
  19. ~Widget();
  20.  
  21. private slots:
  22. void on_btn_add_clicked(); // Слот для обработки добавления треков через диалоговое окно
  23.  
  24. private:
  25. Ui::Widget *ui;
  26. QStandardItemModel *m_playListModel; // Модель данных плейлиста для отображения
  27. QMediaPlayer *m_player; // Проигрыватель треков
  28. QMediaPlaylist *m_playlist; // Плейлиста проигрывателя
  29. };
  30.  
  31. #endif // WIDGET_H

widget.cpp

Для реализации плеера необходимо инициализировать объекты QMediaPlayer, QMediaPlaylist и QStandardItemModel, которые были объявлены в заголовочном файле окна приложения. В первой половине конструктора производится настройка внешнего вида таблицы для отображения плейлиста, тогда как во второй настройка самого плеера. Управление плеером осуществляется через кнопки, которые подключены к управляющим слотам m_playlist (для навигации) и m_player (для запуска/паузы/остановки).

При изменении текущего трека, плеер автоматически завершает воспроизведение того, трека который был до изменения, и запускает на воспроизведение новый трек.

В силу того, что QMediaPlaylist не имеет модели для отображения в таблице, мы воспользуемся классом QStandardItemModel, поэтому придётся добавлять данные о путях к файлам и туда, и туда.

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include <QFileDialog>
  4. #include <QDir>
  5.  
  6. Widget::Widget(QWidget *parent) :
  7. QWidget(parent),
  8. ui(new Ui::Widget)
  9. {
  10. ui->setupUi(this);
  11. // Настройка таблицы плейлиста
  12. m_playListModel = new QStandardItemModel(this);
  13. ui->playlistView->setModel(m_playListModel); // Устанавливаем модель данных в TableView
  14. // Устанавливаем заголовки таблицы
  15. m_playListModel->setHorizontalHeaderLabels(QStringList() << tr("Audio Track")
  16. << tr("File Path"));
  17. ui->playlistView->hideColumn(1); // Скрываем колонку, в которой хранится путь к файлу
  18. ui->playlistView->verticalHeader()->setVisible(false); // Скрываем нумерацию строк
  19. ui->playlistView->setSelectionBehavior(QAbstractItemView::SelectRows); // Включаем выделение строк
  20. ui->playlistView->setSelectionMode(QAbstractItemView::SingleSelection); // Разрешаем выделять только одну строку
  21. ui->playlistView->setEditTriggers(QAbstractItemView::NoEditTriggers); // Отключаем редактирование
  22. // Включаем подгонку размера последней видимой колонки к ширине TableView
  23. ui->playlistView->horizontalHeader()->setStretchLastSection(true);
  24.  
  25. m_player = new QMediaPlayer(this); // Инициализируем плеер
  26. m_playlist = new QMediaPlaylist(m_player); // Инициализируем плейлист
  27. m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер
  28. m_player->setVolume(70); // Устанавливаем громкость воспроизведения треков
  29. m_playlist->setPlaybackMode(QMediaPlaylist::Loop); // Устанавливаем циклический режим проигрывания плейлиста
  30.  
  31. // подключаем кнопки управления к слотам управления
  32. // Здесь отметим, что навигация по плейлисту осуществляется именно через плейлист
  33. // а запуск/пауза/остановка через сам плеер
  34. connect(ui->btn_previous, &QToolButton::clicked, m_playlist, &QMediaPlaylist::previous);
  35. connect(ui->btn_next, &QToolButton::clicked, m_playlist, &QMediaPlaylist::next);
  36. connect(ui->btn_play, &QToolButton::clicked, m_player, &QMediaPlayer::play);
  37. connect(ui->btn_pause, &QToolButton::clicked, m_player, &QMediaPlayer::pause);
  38. connect(ui->btn_stop, &QToolButton::clicked, m_player, &QMediaPlayer::stop);
  39.  
  40. // При даблклике по треку в таблице устанавливаем трек в плейлисте
  41. connect(ui->playlistView, &QTableView::doubleClicked, [this](const QModelIndex &index){
  42. m_playlist->setCurrentIndex(index.row());
  43. });
  44.  
  45. // при изменении индекса текущего трека в плейлисте, устанавливаем название файла в специальном лейбле
  46. connect(m_playlist, &QMediaPlaylist::currentIndexChanged, [this](int index){
  47. ui->currentTrack->setText(m_playListModel->data(m_playListModel->index(index, 0)).toString());
  48. });
  49. }
  50.  
  51. Widget::~Widget()
  52. {
  53. delete ui;
  54. delete m_playListModel;
  55. delete m_playlist;
  56. delete m_player;
  57. }
  58.  
  59. void Widget::on_btn_add_clicked()
  60. {
  61. // С помощью диалога выбора файлов делаем множественный выбор mp3 файлов
  62. QStringList files = QFileDialog::getOpenFileNames(this,
  63. tr("Open files"),
  64. QString(),
  65. tr("Audio Files (*.mp3)"));
  66.  
  67. // Далее устанавливаем данные по именам и пути к файлам
  68. // в плейлист и таблицу отображающую плейлист
  69. foreach (QString filePath, files) {
  70. QList<QStandardItem *> items;
  71. items.append(new QStandardItem(QDir(filePath).dirName()));
  72. items.append(new QStandardItem(filePath));
  73. m_playListModel->appendRow(items);
  74. m_playlist->addMedia(QUrl(filePath));
  75. }
  76. }

Итог

После того, как приложение запустится, Вы сможете открыть mp3 треки и прослушать их.

Скачать Qt Audio Player

Видеоурок

Рекомендуемые статьи по этой тематике

По статье задано1вопрос(ов)

8

Вам это нравится? Поделитесь в социальных сетях!

S
  • 10 июня 2017 г. 13:26

Скажите, пожалуйста, как на линуксе исправить ошибку , связанную с непраильной схемой пути к файлу - "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
  • 10 июня 2017 г. 20:35

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

DV
  • 28 апреля 2021 г. 1:40

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

Evgenii Legotckoi
  • 2 июля 2021 г. 15:09

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

АГ
  • 21 июня 2022 г. 15:48

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

нет

АГ
  • 21 июня 2022 г. 16:07

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

Evgenii Legotckoi
  • 21 июня 2022 г. 16:26
  • (ред.)

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

Р5
  • 13 сентября 2022 г. 18:54

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

juvf
  • 25 ноября 2022 г. 12:14

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

Evgenii Legotckoi
  • 12 декабря 2022 г. 15:05

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

juvf
  • 12 декабря 2022 г. 15:06

Спасибо.

juvf
  • 17 января 2023 г. 9:18

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

Evgenii Legotckoi
  • 7 февраля 2023 г. 16:32

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

AK
  • 1 апреля 2025 г. 11:41
  • (ред.)

Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поскольку в 6 версии вырезали QMediaPlaylist .

Нашел класс QAudioOutput , но абсолютно не понимаю, как связать его с QMediaPlayer , поскольку в нем есть только метод SetVideoOutput . Может кто-по подсказать решение? Гуглеж, поиск по форуму Qt и документации ничего не дали, даже ChatGPT выдает решение с несуществующими классами и методами

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь