- 1. Структура проекта
- 2. widget.ui
- 3. SimplePlayer.pro
- 4. widget.h
- 5. widget.cpp
- 6. Итог
- 7. Видеоурок
Предлагаю написать простенький аудио плеер для 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 будут недоступны.
- #-------------------------------------------------
- #
- # 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
Для реализации отображения плейлиста, придется использовать QStandardItemModel. В неё будут помещаться пути к аудио файлам, а также имена аудио файлов. В первой колонке будет имя аудио файла, а во второй будет полный путь, но данная колонка будет скрыта в объекте QTableView, который будет отвечать за отображение плейлиста.
Также пути к файлом в качестве медиа источников необходимо будет поместить в объект QMediaPlaylist, который будет помещён в QMediaPlayer.
Указатели на эти объекты помещаются в заголовочном файле окна приложения. Также здесь присутствует автогенерированый через дизайнер интерфейсов слот для обработки нажатия по кнопке добавления треков в плейлист.
- #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(); // Слот для обработки добавления треков через диалоговое окно
- private:
- Ui::Widget *ui;
- QStandardItemModel *m_playListModel; // Модель данных плейлиста для отображения
- QMediaPlayer *m_player; // Проигрыватель треков
- QMediaPlaylist *m_playlist; // Плейлиста проигрывателя
- };
- #endif // WIDGET_H
widget.cpp
Для реализации плеера необходимо инициализировать объекты QMediaPlayer, QMediaPlaylist и QStandardItemModel, которые были объявлены в заголовочном файле окна приложения. В первой половине конструктора производится настройка внешнего вида таблицы для отображения плейлиста, тогда как во второй настройка самого плеера. Управление плеером осуществляется через кнопки, которые подключены к управляющим слотам m_playlist (для навигации) и m_player (для запуска/паузы/остановки).
При изменении текущего трека, плеер автоматически завершает воспроизведение того, трека который был до изменения, и запускает на воспроизведение новый трек.
В силу того, что QMediaPlaylist не имеет модели для отображения в таблице, мы воспользуемся классом QStandardItemModel, поэтому придётся добавлять данные о путях к файлам и туда, и туда.
- #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); // Устанавливаем модель данных в TableView
- // Устанавливаем заголовки таблицы
- 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); // Отключаем редактирование
- // Включаем подгонку размера последней видимой колонки к ширине TableView
- ui->playlistView->horizontalHeader()->setStretchLastSection(true);
- m_player = new QMediaPlayer(this); // Инициализируем плеер
- m_playlist = new QMediaPlaylist(m_player); // Инициализируем плейлист
- m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер
- m_player->setVolume(70); // Устанавливаем громкость воспроизведения треков
- m_playlist->setPlaybackMode(QMediaPlaylist::Loop); // Устанавливаем циклический режим проигрывания плейлиста
- // подключаем кнопки управления к слотам управления
- // Здесь отметим, что навигация по плейлисту осуществляется именно через плейлист
- // а запуск/пауза/остановка через сам плеер
- 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);
- // При даблклике по треку в таблице устанавливаем трек в плейлисте
- connect(ui->playlistView, &QTableView::doubleClicked, [this](const QModelIndex &index){
- m_playlist->setCurrentIndex(index.row());
- });
- // при изменении индекса текущего трека в плейлисте, устанавливаем название файла в специальном лейбле
- 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()
- {
- // С помощью диалога выбора файлов делаем множественный выбор mp3 файлов
- QStringList files = QFileDialog::getOpenFileNames(this,
- tr("Open files"),
- QString(),
- tr("Audio Files (*.mp3)"));
- // Далее устанавливаем данные по именам и пути к файлам
- // в плейлист и таблицу отображающую плейлист
- 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));
- }
- }
Итог
После того, как приложение запустится, Вы сможете открыть mp3 треки и прослушать их.
Скажите, пожалуйста, как на линуксе исправить ошибку , связанную с непраильной схемой пути к файлу - "Error: "Invalid URI ...."" и далее соответственно GSteamer; unable to pause...
Ответил на форуме
Добрый вечер. Хотел бы получить консультацию по работе с проектом на Mac OS. Открыл проект в QT и собрал его. Проблема в том, что он не воспроизводит треки и их названия зацикленно мелькают в поле текущего трека. По системе:
- Mac OS 10.14
- QT 5.15.2
- XCode 10.2
С чем это может быть связано. Заранее благодарен.
С Mac OS опыта работы не имею на данный момент
можно ли из этого плеера сделать многоканалов воспроизведения ?
нет
есть такая вообще возможность ?
Не думаю, QMediaPlayer в один поток проигрывает. Если вам нужно одновременное воспроизведение нескольких аудиоисточников, то вам нужна Bass audio library , насколько знаю, её обычно используют для подобных вещей.
Здравствуйте. Подскажите пожалуйста, как решить проблему
multimedia модуль не распознается
Добрый день.
Подскажите, как можно перехватить в Qt или Qml уровень воспроизводимого звука? Т.е. требуется сделать виртуальный винтажный индикатор (стрелочный или светодиодный), который бы показывал уровень звука. И желательно без усилиения. Т.е. в файле mp3 допустим записана синусоида 1000 кГц, амплитудой 0.5 (минимальный уровень 0.0, макс 1.0), то на индикаторе должно быть 0.5, в независимости от того, как выкручена громкость на регуляторе звука плеера, винды/линукса, калонок или внешнего УМ. Как такое возможно реализовать (желательно кроссплатформено с помощью qt/qml)? Куда копать? Как-то перехватывать декодирование mp3 и допустим раз в 100 мс обновлять виджет "Индикатор"?
Qt не располагает средствами для визуализации формы звукового сигнала в файле. То есть из модуля Qt multimedia вы не сможете забрать график звука а потом его обработать так, чтобы вы получали нужный вам результат. Это нужно реализовывать с помощью сторонних библиотек, а потом отрисовывать уже в Qt/Qml. Возможно Bass Dll может в этом помочь.
Спасибо.
PS. Почти дописал плеер на QML. Уперся в ограничения QML. Переписываю плеер на с++/qt, а графика останится в qml. Нашел то, что мне надо, а именно индикатор звука. Qt может перехватывать аудиопоток и анализировать уровень звука. Кому интересно - подробно в примерах в QtCreator "Media Player Example".
А он анализирует уровень звука по частотам, как эквайлайзер? Я просто подумал, что вам как в аналоговом эквалайзере нужно...
Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поскольку в 6 версии вырезали QMediaPlaylist .
Нашел класс QAudioOutput , но абсолютно не понимаю, как связать его с QMediaPlayer , поскольку в нем есть только метод SetVideoOutput . Может кто-по подсказать решение? Гуглеж, поиск по форуму Qt и документации ничего не дали, даже ChatGPT выдает решение с несуществующими классами и методами