《QT6/C++开发指南》多媒体/播放音频/案例16-1

效果图

在这里插入图片描述

知识点

在这里插入图片描述

.pro(环境QT6)

在这里插入图片描述

.cpp

在这里插入图片描述

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include    <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 1、new一个对象
    player = new QMediaPlayer(this);
    QAudioOutput *audioOutput = new QAudioOutput(this);   //音频输出,指向默认的音频输出设备
    // 2、使播放器有输出设备
    player->setAudioOutput(audioOutput);    //设置音频输出设备(安装喇叭)
    // 3、写一些连接函数
    // 当播放器播放到不同位置时,有相应的函数处理
    connect(player,&QMediaPlayer::positionChanged,      //播放位置发生变化
            this, &MainWindow::do_positionChanged);

    connect(player,&QMediaPlayer::durationChanged,      //播放源长度发生变化
            this, &MainWindow::do_durationChanged);

    connect(player, &QMediaPlayer::sourceChanged,       //播放源发生变化
            this, &MainWindow::do_sourceChanged);

    connect(player, &QMediaPlayer::playbackStateChanged,    //播放器状态发生变化
            this,  &MainWindow::do_stateChanged);

    connect(player, &QMediaPlayer::metaDataChanged,     //元数据发生变化
            this,  &MainWindow::do_metaDataChanged);
    // 4、完成按钮的功能

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::do_stateChanged(QMediaPlayer::PlaybackState state)
{//播放器状态变化时执行,更新按钮状态,或播放下一曲
    ui->btnPlay->setEnabled(state!=QMediaPlayer::PlayingState);
    ui->btnPause->setEnabled(state==QMediaPlayer::PlayingState);
    ui->btnStop->setEnabled(state==QMediaPlayer::PlayingState);

    //播放完一曲后停止了,如果loopPlay为true,自动播放下一曲
    if (loopPlay && (state ==QMediaPlayer::StoppedState))
    {
        int count=ui->listWidget->count(); // 拿:列表中的歌数目
        int curRow=ui->listWidget->currentRow(); // 拿:当前第几行
        curRow++;
        curRow= curRow>=count? 0:curRow;
        ui->listWidget->setCurrentRow(curRow);
        //player->setSource(getUrlFromItem(ui->listWidget->currentItem())); // 拿:地址
        player->play(); // 播放
    }
}

void MainWindow::do_sourceChanged(const QUrl &media)
{//播放的文件发生变化时的响应“曲目”
    ui->labCurMedia->setText(media.fileName()); // media.fileName()获取曲目名称
}

void MainWindow::do_durationChanged(qint64 duration)
{//播放源时长变化时执行,更新进度显示(切换下一曲)
    ui->sliderPosition->setMaximum(duration);

    int   secs=duration/1000;  //秒
    int   mins=secs/60;        //分钟
    secs=secs % 60;            //余数秒
    durationTime=QString::asprintf("%d:%d",mins,secs);
    ui->labRatio->setText(positionTime+"/"+durationTime);
}

void MainWindow::do_positionChanged(qint64 position)
{//播放位置变化时执行,更新进度显示
    if (ui->sliderPosition->isSliderDown())     //滑条正被鼠标拖动
        return;
    // 如果没有正在被拖动,则设置进度条到新的position
    ui->sliderPosition->setSliderPosition(position);
    // 时间转换为分和秒
    int   secs=position/1000;   //秒
    int   mins=secs/60;         //分钟
    secs=secs % 60;             //余数秒
    // 当前时间
    positionTime=QString::asprintf("%d:%d",mins,secs);
    // 进度labRatio
    ui->labRatio->setText(positionTime+"/"+durationTime);
}

void MainWindow::do_metaDataChanged()
{//元数据变化时执行,显示歌曲图片
    QMediaMetaData metaData=player->metaData();     //元数据对象
    QVariant  metaImg= metaData.value(QMediaMetaData::ThumbnailImage);  //获取ThumbnailImage元数据
    if (metaImg.isValid())
    {
        QImage img= metaImg.value<QImage>();        //QVariant转换为QImage
        QPixmap musicPixmp= QPixmap::fromImage(img); // 格式转换
        // 判断区域大小
        if (ui->scrollArea->width() <musicPixmp.width())
            ui->labPic->setPixmap(musicPixmp.scaledToWidth(ui->scrollArea->width()-30));
        else
            ui->labPic->setPixmap(musicPixmp); // 直接显示图片
    }
    else
        ui->labPic->clear();
}

QUrl MainWindow::getUrlFromItem(QListWidgetItem *item)
{
    QVariant itemData= item->data(Qt::UserRole);    //获取用户数据
    QUrl source =itemData.value<QUrl>();    //QVariant转换为QUrl类型
    return source;
}

void MainWindow::on_btnAdd_clicked()
{//"添加"按钮,添加文件
    QString curPath=QDir::homePath();  //获取系统当前目录
    QString dlgTitle="选择音频文件";
    QString filter="音频文件(*.mp3 *.wav *.wma);;所有文件(*.*)";   //文件过滤器
    // 1、获取列表
    QStringList fileList=QFileDialog::getOpenFileNames(this,dlgTitle,curPath,filter);
    if (fileList.count()<1)
        return;
    // 2、遍历列表
    for (int i=0; i<fileList.size();i++)
    {
        QString  aFile=fileList.at(i);
        QFileInfo  fileInfo(aFile);
        // 2.1 拿出每一项
        QListWidgetItem *aItem =new QListWidgetItem(fileInfo.fileName());
        // 2.2 设置图标
        aItem->setIcon(QIcon(":/images/images/musicFile.png"));
        aItem->setData(Qt::UserRole, QUrl::fromLocalFile(aFile));  //设置用户数据,QUrl对象
        // 2.3 放入每一项
        ui->listWidget->addItem(aItem);
    }

    if (player->playbackState() != QMediaPlayer::PlayingState)
    {  //当前没有在播放,就播放第1个文件
        ui->listWidget->setCurrentRow(0);
        QUrl source= getUrlFromItem(ui->listWidget->currentItem());
        player->setSource(source);
    }
    player->play();
}

void MainWindow::on_btnRemove_clicked()
{//"移除"按钮,移除列表中的当前项
    int index =ui->listWidget->currentRow(); // 2 拿到索引
    if (index>=0)
    {
        // 1 拿到需要删除的item  需要索引index
        QListWidgetItem *item= ui->listWidget->takeItem(index);
        delete item;
    }
}

void MainWindow::on_btnClear_clicked()
{//"清空"按钮,清空播放列表
    loopPlay=false;     //防止do_stateChanged()里切换曲目
    ui->listWidget->clear();
    player->stop();
}

void MainWindow::on_btnPlay_clicked()
{//开始播放
    if (ui->listWidget->currentRow()<0)   // 3、判断:没有选择文件,就播放第1个
        ui->listWidget->setCurrentRow(0);
    player->setSource(getUrlFromItem(ui->listWidget->currentItem())); // 2、获取源
    player->play(); // 1、播放
    loopPlay=ui->btnLoop->isChecked();  //是否循环播放
}


void MainWindow::on_btnPause_clicked()
{//暂停播放
    player->pause();
}


void MainWindow::on_btnStop_clicked()
{//停止播放
    loopPlay=false;
    player->stop();
}


void MainWindow::on_btnPrevious_clicked()
{//前一曲
    // 2 获取行号并--
    int curRow=ui->listWidget->currentRow();
    curRow--;
    // 3 判断并更新行
    curRow= curRow<0? 0:curRow;
    ui->listWidget->setCurrentRow(curRow);  //更新当前行

    loopPlay=false;     //暂时设置为false,防止do_stateChanged()里切换曲目
    // 4 获取播放源
    player->setSource(getUrlFromItem(ui->listWidget->currentItem()));
    player->play(); // 1 播放
    loopPlay=ui->btnLoop->isChecked();

    //    if(ui->btnLoop->isChecked())
    //    {
    //        loopPlay=false;     //暂时设置为false,防止do_stateChanged()里切换曲目
    //        player->setSource(getUrlFromItem(ui->listWidget->currentItem()));
    //        player->play();
    //        loopPlay=true;
    //    }
}


void MainWindow::on_btnNext_clicked()
{//下一曲
    int count=ui->listWidget->count();
    int curRow=ui->listWidget->currentRow();
    curRow++;
    curRow= curRow>=count? count-1:curRow;
    ui->listWidget->setCurrentRow(curRow);

    loopPlay=false;     //暂时设置为false,防止do_stateChanged()里切换曲目
    player->setSource(getUrlFromItem(ui->listWidget->currentItem()));
    player->play();
    loopPlay=ui->btnLoop->isChecked();

    //    if(ui->btnLoop->isChecked())
    //    {
    //        loopPlay=false;     //暂时设置为false,防止do_stateChanged()里切换曲目
    //        player->setSource(getUrlFromItem(ui->listWidget->currentItem()));
    //        player->play();
    //        loopPlay=true;
    //    }
}


void MainWindow::on_doubleSpinBox_valueChanged(double arg1)
{//"倍速" DoubleSpinbox
    player->setPlaybackRate(arg1);
}



void MainWindow::on_btnLoop_clicked(bool checked)
{//"循环" 按钮
    loopPlay=checked;
}


void MainWindow::on_btnSound_clicked()
{//静音控制
    bool mute=player->audioOutput()->isMuted();
    player->audioOutput()->setMuted(!mute);
    if (mute)
        ui->btnSound->setIcon(QIcon(":/images/images/volumn.bmp"));
    else
        ui->btnSound->setIcon(QIcon(":/images/images/mute.bmp"));
}


// valueChanged
void MainWindow::on_sliderVolumn_valueChanged(int value)
{//调整音量
    player->audioOutput()->setVolume(value/100.0);        //0~ 1之间
}

// valueChanged
void MainWindow::on_sliderPosition_valueChanged(int value)
{//播放进度调控
    player->setPosition(value);
}

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include    <QtMultimedia>
#include    <QListWidgetItem>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    // 1、定义数据
    QMediaPlayer  *player;      //播放器
    bool    loopPlay=true;      //是否循环播放
    QString  durationTime;      //文件总长度,mm:ss字符串
    QString  positionTime;      //当前播放到位置,mm:ss字符串

    QUrl getUrlFromItem(QListWidgetItem *item);         //获取item的用户数据

    //QUrl getUrlFromItem(QListWidgetItem *item);         //获取item的用户数据
    //bool eventFilter(QObject *watched, QEvent *event);  //事件过滤处理

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
private slots:
    // 2、自定义槽函数
    void do_stateChanged(QMediaPlayer::PlaybackState state);    //播放器状态发生变化

    void do_sourceChanged(const QUrl &media);   //文件发生变化

    void do_durationChanged(qint64 duration);   //文件长度发生变化

    void do_positionChanged(qint64 position);   //播放位置发生变化

    void do_metaDataChanged();          //元数据发生变化
    void on_btnAdd_clicked();
    void on_btnRemove_clicked();
    void on_btnClear_clicked();
    void on_btnPlay_clicked();
    void on_btnPause_clicked();
    void on_btnStop_clicked();
    void on_btnPrevious_clicked();
    void on_btnNext_clicked();
    void on_doubleSpinBox_valueChanged(double arg1);
    void on_btnLoop_clicked(bool checked);
    void on_btnSound_clicked();
    void on_sliderVolumn_valueChanged(int value);
    void on_sliderPosition_valueChanged(int value);
};
#endif // MAINWINDOW_H

ui界面

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值