Евгений Легоцкой29 июня 2016 г. 9: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 будут недоступны.

#-------------------------------------------------
#
# 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." Но что конкретно из этого стоит вынести, не ясно.
Благодарен за внимание.

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

DV

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

Комментарии

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

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг
L

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

  • Результат:80баллов,
  • Очки рейтинга4
ДЦ

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

  • Результат:46баллов,
  • Очки рейтинга-6
СБ

Qt - Тест 001. Сигналы и слоты

  • Результат:94баллов,
  • Очки рейтинга8
Популярные публикации за последние 90 дней
Последние комментарии
ЯО

Как соответствовать новым требованиям Google Play

Ку всем! Вопрос! Как с помощью JNI вызвать оплату на android устройстве? Попробовал Qt Purchasing вроде пошло... но android пишет что библиотека устарела. В qt6 пока поддержки purchasing нет. Р…

Django - Урок 014. Вывод списка популярных статей на Django

Я как понял, этот метод создает статистику каждый день (на каждый день), не удаляя старые данные за день и выводит все данные за сегодняшние просмотры у всех статей?

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Изменить запрос при создании модели.
L
  • Livis
  • 30 мая 2021 г. 13:18

Django - Урок 001. Развёртывание сайта на Django + PostgreSQL + Gunicorn + Nginx

Отвечал на все команды после sudo service supervisor start Исправил таким образом sudo killall supervisordsudo supervisord -c /etc/supervisor/supervisord.conf
D

Django - Урок 001. Развёртывание сайта на Django + PostgreSQL + Gunicorn + Nginx

Это на какую команду так отвечает?
Сейчас обсуждают на форуме
v
  • vika
  • 17 июня 2021 г. 0:19

Вопрос новичка ui-форма

все получилось. создала обьект, исправила ошибки и все заработало. спасибо, что есть с кем поговорить.
s

Ключевое слово class

Разобрался,на стаковерфлоу нашел топик и понял почему так происходило .
KM

Django как воспользоваться результатом метода?

Priv = 2020 Now = 2021 Next = 2022 Rok = ( (None, "Nie wybran"), (Priv, '2020'), (Now, '2021'), (Next, '2022') ) Rok = models.IntegerField(choices=Rok, de…

QScrollArea dynamically add QCheckBoxes

Всё правильно. Это просто спамер, который отправился в вечный бан.

Папка с шаблоном сайта

Есть проект с поддержкой динамического создания поддоменов. Как назначить разные пути к шаблонам в templates from django.shortcuts import renderfrom horticulture.utilities import get_horticu…
О нас
Услуги
© EVILEG 2015-2021
Рекомендует хостинг TIMEWEB