- 1. Структура проекта
- 2. widget.ui
- 3. SimplePlayer.pro
- 4. віджет.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
віджет.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".
А он анализирует уровень звука по частотам, как эквайлайзер? Я просто подумал, что вам как в аналоговом эквалайзере нужно...