《二十二》Qt 音频编程实战---做一个音频播放器

1.UI界面制作

作为一个音乐播放器,最基础的肯定就是播放、暂停、上一首以及下一首,为了使这个界面好看一点,还加入了音量控制、进度条、歌曲列表等内容,至于这种配色和效果好不好看,我也不知道,个人审美一如既往的不达标。

QT设计界面有两种方式,一种是直接通过纯代码的方式实现,将各种控件以及布局通过代码的方式编排成一个完整的UI界面,但是这种方式较为麻烦也比较复杂,代码量也比较大,还有一种就是通过UI文件拖拽QT控件,来对整个布局进行排版的效果,我这里为了省事采用的就是这种方式,至于实际效果怎么样那就要看个人审美了。

整个UI界面内部使用到的基础控件有以下几种:

控件名称 控件类 控件功能
PushButton QPushButton 用来控制添加、删除、清空歌曲列表的功能
horizontalSlider QSlider 用来控制播放进度、音量等功能
listWidget QListWidget 歌单列表,内部存入添加的歌曲
groupBox QgroupBox 内部放入播放列表
label Qlabel 标签,可以用来显示提示信息以及图片

2.加入播放器类

UI界面设计完成之后就是加入播放器类。QT中使用播放器类需要加入对应的链接模块,通过查询QT的帮助手册可以查到,然后在项目的pro文件中加上即可。

加入链接模块后,需要添加我们需要使用到的一些相关的播放器类头文件

cpp 复制代码
#include<QMediaPlayer>
#include<QMediaPlaylist>
#include<QFileDialog>

3.播放器初始化

首先在头文件先定义出我们所需要的成员以及槽函数,定义一个QMediaPlayer类以及QMediaPlaylist类,还需要记录歌曲时长,以及位置,方便我们拖动进度条。

QMediaPlaylist类,可以为QMediaPlayer提供一个播放列表,它其实是QMediaContent对象的列表,QMediaPlayer通过函数setPlaylist来设置一个播放列表。QMediaPlaylist通过函数addMedia向播放列表添加一个媒体文件。QMediaplaylist类的播放模式:PlaybackMode

cpp 复制代码
private:
    Ui::MainWindow *ui;

    QMediaPlayer *player;
    QMediaPlaylist *playlist;

    QString drtTime;//歌曲时长
    QString pstTime;//播放位置

private slots:
    void Onstatechg(QMediaPlayer::State state);//按钮切换状态
    void Onplaylishchg(int pos);//播放列表
    void OnDrtchg(qint64 drt);//歌曲总时间长度
    void Onpstchg(qint64 pos);//播放歌曲当前位置

对于槽函数Onstatechg()的实现,我们对state状态进行比较,从而对按钮:播放,暂停,停止按钮进行处理。

cpp 复制代码
void MainWindow::Onstatechg(QMediaPlayer::State state)//按钮切换状态
{
    ui->pushButton_player->setEnabled(!(state==QMediaPlayer::PlayingState));
    ui->pushButton_puse->setEnabled(state==QMediaPlayer::PlayingState);
    ui->pushButton_stop->setEnabled(state==QMediaPlayer::PlayingState);
}
复制代码
槽函数Onplaylishchg() 的实现,获取listWidget中的项目,来显示到下方歌曲名称的label中
cpp 复制代码
void MainWindow::Onplaylishchg(int pos)//播放列表
{
    ui->listWidget->setCurrentRow(pos);
    QListWidgetItem *item=ui->listWidget->currentItem();
    if(item){
        ui->label_name->setText(item->text());
    }
}

槽函数**OnDrtchg()**的实现,先获取进度条的最大长度,根据获取的歌曲时间,转化成分,秒。放到歌曲时间label中

cpp 复制代码
void MainWindow::OnDrtchg(qint64 drt)//歌曲总时间长度
{
    ui->horizontalSlider_speed->setMaximum(drt);
    int sec=drt/1000;//总共多少秒
    int min=sec/60;//分
    sec=sec%60;//秒

    drtTime=QString::asprintf("%d:%d",min,sec);
    ui->label_time->setText(pstTime+"/"+drtTime);
}

调整进度条,Onpstchg() 与上面方法类似,目的就是更新位置

cpp 复制代码
void MainWindow::Onpstchg(qint64 pos)//播放歌曲当前位置,更新变化
{
    if(ui->horizontalSlider_speed->isSliderDown()){
        return;
    }
    ui->horizontalSlider_speed->setSliderPosition(pos);

    int sec=pos/1000;
    int min=sec/60;
    sec=sec%60;

    pstTime=QString::asprintf("%d:%d",min,sec);
    ui->label_time->setText(pstTime+"/"+drtTime);
}

接着就是槽函数链接了:

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    player=new QMediaPlayer(this);
    playlist=new QMediaPlaylist(this);

    playlist->setPlaybackMode(QMediaPlaylist::Loop);//循环模式
    player->setPlaylist(playlist);

    connect(player,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(Onstatechg(QMediaPlayer::State)));
    connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(Onpstchg(qint64 )));
    connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(OnDrtchg(qint64 )));
    connect(playlist,SIGNAL(currentIndexChanged(int)),this,SLOT(Onplaylishchg(int)));
}

4.功能控件

再接着我们来实现各种按钮以及拖动进度条事件的槽函数:

这些都是我们要实现的槽函数:

先从打开文件开始:

cpp 复制代码
void MainWindow::on_pushButton_open_clicked()
{
    //添加歌曲
    QString currentpath=QDir::homePath();//当前位置
    QString dlgtitle="请选择音频文件:";//文件对话框标题
    QString strfilter="所有文件(*.*);;音频文件(*.mp3);;mp3文件(*.mp3)";//文件过滤器
    QStringList filelist=QFileDialog::getOpenFileNames(this,dlgtitle,currentpath,strfilter);
    if(filelist.count()<1){
        return;
    }
    for(int i=0;i<filelist.count();i++){
        QString afile=filelist.at(i);
        playlist->addMedia(QUrl::fromLocalFile(afile));//添加文件

        QFileInfo fileinfo(afile);
        ui->listWidget->addItem(fileinfo.fileName());//将文件添加到界面listwidget控件
    }
    if(player->state()!=QMediaPlayer::PlayingState){
        playlist->setCurrentIndex(0);
    }
    player->play();
}

首先要获取到位置,通过文件过滤来找到我们所需要的mp3文件,根据选中的文件数量依次添加到listWidget中,

剩下的 就比较简单了,我们全放出来:

cpp 复制代码
void MainWindow::on_pushButton_player_clicked()
{
    if(playlist->currentIndex()<0){
        playlist->setCurrentIndex(0);
    }
    player->play();
}

void MainWindow::on_pushButton_puse_clicked()
{
    player->pause();
}

void MainWindow::on_pushButton_stop_clicked()
{
    player->stop();
}

void MainWindow::on_pushButton_prev_clicked()
{
    playlist->previous();
}

void MainWindow::on_pushButton_next_clicked()
{
    playlist->next();
}

void MainWindow::on_pushButton_volumn_clicked()
{
    bool mutex=player->isMuted();
    player->setMuted(!mutex);
    if(mutex){
        ui->pushButton_volumn->setIcon(QIcon(":/icon/sound.png"));
    }else{
        ui->pushButton_volumn->setIcon(QIcon(":/icon/mute.png"));
    }
}


void MainWindow::on_horizontalSlider_Volumn_valueChanged(int value)
{
    player->setVolume(value);
}

void MainWindow::on_horizontalSlider_speed_valueChanged(int value)
{
    player->setPosition(value);
}

以及图标我们可以创建一个资源文件,来放图标:

后续在ui文件中导入:

5. 总结

到这里基本是一个简单的音乐播放器就基本实现了,虽然里面有很多功能写的不是很详细,也有一部分操作我没有做,但是基本能实现播放、暂停、切换等基本功能。

如果后期需要对播放器的功能进行添加可以自行添加,比方说,QT有自带的视频播放功能,可以将中间的GIF图片换成播放歌曲的MV,还可以添加一个comboBox控件来选择当前播放器的播放模式,QT有内置的宏可以直接设置,我这里是直接选择的循环播放。

还有就是好像可以实现从网络获取歌曲的方法,这种的话就可以不用提前下载好歌曲了,大家可以自己去找一下,不要问我为什么没做这种,问就是我是菜鸡,我不会。

好了,差不多到这里也要结束了,作为一个QT的初学者,里面有很多设置方法在各位大佬看来可能很笨,但是目前就只有这种水平了,而且大家如果对各种基础控件的样式不满意,可以去自己找一下各种样式表,自己设置一下,我这里就没有做太多这种操作了。

相关推荐
RTC实战笔记2 天前
实时互动数字人怎么做,才不是一个只会说话的视频?
音视频·数字人·rtc·数字人接入
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
RTC实战笔记14 天前
Android 实时音视频接入教程:媒体补充增强信息(SEI)
音视频·媒体·rtc