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

QMediaPlayer, QMediaPlaylist, QStandardItemModel, 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 будут недоступны.

#-------------------------------------------------
#
# 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 треки и прослушать их.

Скачать Qt Audio Player

Видеоурок

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Поддержать автора 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." Но что конкретно из этого стоит вынести, не ясно.
Благодарен за внимание.

Комментарии

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

Здравствуйте, уважаемые пользователи EVILEG !!!

Если сайт вам помог, то поддержите разработку сайта финансово, пожалуйста.

Вы можете сделать это следующими способами:

Спасибо, Евгений Легоцкой

A
6 апреля 2020 г. 5:24
Alexey

C++ - Тест 001. Первая программа и типы данных

  • Результат:86баллов,
  • Очки рейтинга6
R
5 апреля 2020 г. 14:32
Roman

C++ - Тест 002. Константы

  • Результат:91баллов,
  • Очки рейтинга8
AP
5 апреля 2020 г. 14:31
Alexander Peshkov

C++ - Тест 001. Первая программа и типы данных

  • Результат:60баллов,
  • Очки рейтинга-1
Последние комментарии
3 апреля 2020 г. 8:06
Konstantin Grudnitskiy

Я надеюсь вы уже разобрались в чем дело, но если вдруг нет, то проблема состоит в том, что вы пытаетесь запустить программу из интерпретатора питона. Файл main.py это уже готова…
3 апреля 2020 г. 6:18
Konstantin Grudnitskiy

>>> text = 'hello world'>>> ' '.join(word for word in text.split()[:-1])'hello'>>> def remove_last_word(text):... return text and ' '.join(word for word in text.s…
27 марта 2020 г. 14:40
Евгений Легоцкой

Добрый день. В конце пятой статьи скачать можете.
27 марта 2020 г. 14:28
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
27 марта 2020 г. 4:36
Евгений Легоцкой

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set
Сейчас обсуждают на форуме
6 апреля 2020 г. 4:19
Евгений Легоцкой

Попробуй не переустанавливать материал, а просто менять цвет
6 апреля 2020 г. 3:39
Евгений Легоцкой

Добрый день. Это всё работает, вот только если есть переопределения каких-то методов, то нет гарантии, что что-то не сломается. Думаю, что нужно допиливать стилевоё оформление в прокси…
5 апреля 2020 г. 11:38
Михаиллл

Так работает windeployqt --qmldir E:\QTProject\testQmlAndCpp E:\test\build-testQmlAndCpp-Desktop_Qt_5_14_1_MinGW_32_bit-Release
5 апреля 2020 г. 2:35
Михаиллл

Так работает console.log(textEmail.text) var str = textEmail.text; var n = str.search(/^((([0-9A-Za-z]{1}[-0-9A-z\.]{1,}[0-9A-Za-z]{1})|([0-9А-Яа-я]{1}[-0-9А-я\.]{1,}[…
3 апреля 2020 г. 8:48
Intruder

Евгений, добрый день. Спасибо!
EVILEG
О нас
Услуги
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB