C++/Qt实现网络音乐播放器(二)

实现本地音乐播放

基本逻辑

1.点击导入歌曲按钮,弹出文件选择界面设置只能选择mp3文件,得到此音乐文件的路径并利用ffmpeg解析音乐的详细信息
2.点击播放全部则发送一个信号到主界面参数为音乐信息的链表
3.双击则发送添加歌曲到播放列表的一个信号参数是该选中音乐的所有信息
(此处会做判断,判断是否当前播放列表含有该歌曲,如果有则无需添加,直接播放该首歌曲,若无则添加在播放列表最后面,播放器直接播放该首歌曲)

代码

localwget.h

#ifndef LOCALWGET_H
#define LOCALWGET_H
#include <QWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QFileDialog>
#include <QStringList>
#include <QDir>
#include <QLabel>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
}
class LocalWget :public QWidget
{
Q_OBJECT
public:
    explicit LocalWget(QWidget *parent = 0);
    ~LocalWget();
     QTableWidget * songTableWidget;
     QPushButton * m_pButPlayAllSong;
     QPushButton* m_pButInputSong;
     QPushButton* m_pButMoreCtor;
private:
     struct findResult
     {
         QString hash;
         QString songName;
         QString singername;
         QString album_name;
         QString filesize;
         QString playPath;
         QString timelength;
         QImage image;
         QString imagePath;
     }stResultList;
     //
     QList<findResult> m_listResult;
signals:
     void playAllLocalMusic(QList<findResult>);
     void addOneSongInLIst(findResult);
private slots:
     void importSongs();
     void mainWgetplayAllLocalMusic();
     void changeMusicPlayList(int);
private:
     void getMusicInfo(QString filename);
     QMap<QString,QString> m_InfoMap;
     AVFormatContext *m_AVFormatContext;
     QString initialName;
};
#endif // LOCALWGET_H

localwget.cpp

#include "localwget.h"
#include <QLabel>
#include <QDebug>
#include <QMapIterator>
#include "mydatabase.h"
LocalWget::LocalWget(QWidget *parent):
    QWidget(parent)
{
    //
    m_AVFormatContext = nullptr;
    //
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
    setFixedSize(800,500); //819,527
    setAutoFillBackground(true);
    songTableWidget = new QTableWidget(0, 5, this);
    songTableWidget->setStyleSheet("border-color:white;\
                                   border-style:solid;");
    songTableWidget->setAutoFillBackground(true);
    QStringList TableHeader;
    TableHeader << QStringLiteral("歌曲") << QStringLiteral("歌手")<< QStringLiteral("专辑")<< QStringLiteral("时间");
    songTableWidget->setHorizontalHeaderLabels(TableHeader);
    songTableWidget->setFixedSize(760, 460);
    songTableWidget->move(40, 40);
    //songTableWidget->setPalette(QPalette(QColor(120, 214, 255, 255)));
    songTableWidget->setShowGrid(false);
    songTableWidget->setColumnWidth(0, 300);
    songTableWidget->setColumnWidth(1, 160);
    songTableWidget->setColumnWidth(2, 160);
    songTableWidget->setColumnWidth(3, 100);
    songTableWidget->setColumnHidden(4,true);
    songTableWidget->setEditTriggers(QTableWidget::NoEditTriggers);
    songTableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    // 设置只能选择单行
    songTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    songTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//整行选中
    // 设置不显示网格
    songTableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
    songTableWidget->setShowGrid(false);
    connect(songTableWidget, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(changeMusicPlayList(int)));
    this->setStyleSheet("QPushButton {	\
                        color:black;	\
                        border-radius:12px;\
                        border-width:1;\
                        border-color:black;\
                        border-style:solid;;\
                        background-color:rgba(0,0,0,0); \
                        }\
                        QPushButton:hover {	\
                        color:red;	\
                        border-radius:12px;\
                        border-width:1;\
                        border-color:red;\
                        border-style:solid;;\
                        background-color:rgba(0,0,0,0); \
                        }");

    //
    QLabel *lab = new  QLabel(this);
    lab->setText("▋ 本地音乐");
    lab->setGeometry(40,10,100,28);
    //
    m_pButPlayAllSong = new QPushButton(this);
    m_pButPlayAllSong->setText("►播放全部");
    m_pButPlayAllSong->setGeometry(474,10,92,24);
    QObject::connect(m_pButPlayAllSong,SIGNAL(clicked(bool)),this,SLOT(mainWgetplayAllLocalMusic()));
    //
    m_pButInputSong =   new QPushButton(this);
    m_pButInputSong->setText("导入歌曲");
    m_pButInputSong->setGeometry(576,10,92,24);
    QObject::connect(m_pButInputSong,SIGNAL(clicked(bool)),this,SLOT(importSongs()));
    //
    m_pButMoreCtor=   new QPushButton(this);
    m_pButMoreCtor->setText("┄ 更多操作");
    m_pButMoreCtor->setGeometry(678,10,92,24);
}

LocalWget::~LocalWget()
{
    delete songTableWidget;
    delete m_pButPlayAllSong;
    delete m_pButInputSong;
    delete m_pButMoreCtor;

}

void LocalWget::importSongs()
{
    QStringList pathList = QFileDialog::getOpenFileNames(this, QStringLiteral("选择文件"), initialName, tr("(*.mp3)"));
    for (int i = 0; i < pathList.size(); ++i)
    {
        QString path = QDir::toNativeSeparators(pathList.at(i));
        if (!path.isEmpty())
        {
            //m_musicPlayList->addMedia(QUrl::fromLocalFile(path));
            getMusicInfo(path);
        }
    }
   // MyDatabase::getInstance().selectAll(QString("t_mylocal"));
    //MyDatabase::getInstance().deleteAll(QString("t_mylocal"));
    if (pathList.size() != 0)
    {
        //initialName = pathList.at(0).left(pathList.at(0).lastIndexOf('/', -1));
    }
}


void LocalWget::mainWgetplayAllLocalMusic()
{
    emit playAllLocalMusic(m_listResult);
}

void LocalWget::changeMusicPlayList(int row)
{
    if (row >= songTableWidget->rowCount())
        return;
   emit addOneSongInLIst(m_listResult.at(row));
}

void LocalWget::getMusicInfo(QString filename)
{
    int result = avformat_open_input(&m_AVFormatContext, filename.toLocal8Bit().data(), nullptr, nullptr);
    if (result != 0 || m_AVFormatContext == nullptr)
        return ;

    // 查找流信息,把它存入AVFormatContext中
     if (avformat_find_stream_info(m_AVFormatContext, nullptr) < 0)
        return ;

   // int streamsCount = m_AVFormatContext->nb_streams;
    m_InfoMap.clear();
    // 读取详细信息
    AVDictionaryEntry *tag = nullptr;
    while (tag = av_dict_get(m_AVFormatContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))
    {
        QString keyString = tag->key;
        QString valueString = QString::fromUtf8(tag->value);
        m_InfoMap.insert(keyString, valueString);
    }
    //插入
    int duration_s = m_AVFormatContext->duration/1000000;
    int rownum = songTableWidget->rowCount();
    songTableWidget->insertRow(rownum);
    songTableWidget->setItem(rownum, 0, new QTableWidgetItem(m_InfoMap.value("title","未知")));
    songTableWidget->setItem(rownum, 1, new QTableWidgetItem(m_InfoMap.value("artist","未知")));
    songTableWidget->setItem(rownum, 2, new QTableWidgetItem(m_InfoMap.value("album","未知")));
    songTableWidget->setItem(rownum, 3, new QTableWidgetItem(QString("%1:%2").arg(duration_s/60).arg(duration_s%60,2,10,QChar('0'))));
    songTableWidget->setItem(rownum, 4, new QTableWidgetItem(QDir::toNativeSeparators(filename)));
    findResult tmpInfo;
    int streamsCount = m_AVFormatContext->nb_streams;
    for (int i=0; i<streamsCount; ++i)
    {
        if (m_AVFormatContext->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC)
        {
            AVPacket pkt = m_AVFormatContext->streams[i]->attached_pic;
            tmpInfo.image = QImage::fromData((uchar*)pkt.data, pkt.size);
        }
    }
    tmpInfo.songName =m_InfoMap.value("artist","未知")+"-"+m_InfoMap.value("title","未知");
    tmpInfo.singername =m_InfoMap.value("artist","未知");
    tmpInfo.hash ="";
    tmpInfo.playPath =  QUrl::fromLocalFile(filename).toString();;
    tmpInfo.timelength =QString("%1:%2").arg(duration_s/60).arg(duration_s%60,2,10,QChar('0'));
    tmpInfo.album_name = m_InfoMap.value("album","未知") ;
    m_listResult.append(tmpInfo);

    //
//    QStringList list;
//    list.append(QString("%1").arg(rownum));
//    list.append(m_InfoMap.value("title","未知"));
//    list.append(m_InfoMap.value("artist","未知"));
//    list.append(m_InfoMap.value("album","未知"));
//    list.append(QString("%1:%2").arg(duration_s/60).arg(duration_s%60,2,10,QChar('0')));
//    list.append(filename);
//    MyDatabase::getInstance().addMusicInfo(list);
    //关闭
    if(m_AVFormatContext)
        avformat_close_input(&m_AVFormatContext);
}

主界面处理
qt提供的多媒体类:

//播放控制
    QMediaPlayer * m_musicPlayer;
    QMediaPlaylist*  m_musicPlayList=nullptr;

注:如果要使用该类除需要添加相应的头文件外还需要在pro文件中添加

QT       +=  multimedia 
void MainWindow::slotPlayAllSong(QList<findResult> playlist)
{
    m_musicPlayList->clear();
    m_listResult.clear();
   // int lenth =playlist.length();
    ui->m_pLabPlayingSongSize->setText("0");
    while ( ui->m_playingLisTableWidget->rowCount())
    {
         ui->m_playingLisTableWidget->removeRow(0);
    }
    for(int i=0;i<playlist.length();i++)
    {
        if(playlist.at(i).playPath.isEmpty())
        {
           // --lenth;
            playlist.removeAt(i);
            continue;
        }
        m_musicPlayList->addMedia(QUrl(playlist.at(i).playPath));
//        qDebug() <<playlist.at(i).songName;
//        qDebug() <<playlist.at(i).playPath;
        int rownum = ui->m_playingLisTableWidget->rowCount();
        ui->m_playingLisTableWidget->insertRow(rownum);
        ui->m_playingLisTableWidget->setItem(rownum, 0, new QTableWidgetItem(playlist.at(i).songName));
        ui->m_playingLisTableWidget->setItem(rownum, 1, new QTableWidgetItem(playlist.at(i).timelength));
    }
    ui->m_pLabPlayingSongSize->setText( QString("%1").arg(playlist.length()));
    if(m_musicPlayList->isEmpty())
        return;
    m_listResult = playlist;
    m_musicPlayer->play();
    ui->m_pButSongPlay->setText("😕");
    ui->m_pButSongPlay->setToolTip("暂停");
}

void MainWindow::slotAddOneSongInList(findResult songinfo)
{
    if(songinfo.playPath.isEmpty())
        return;
    if(m_listResult.isEmpty())
    {
        m_musicPlayList->addMedia(QUrl(songinfo.playPath));
        m_listResult.append(songinfo);
        int rownum = ui->m_playingLisTableWidget->rowCount();
        ui->m_playingLisTableWidget->insertRow(rownum);
        ui->m_playingLisTableWidget->setItem(rownum, 0, new QTableWidgetItem(songinfo.songName));
        ui->m_playingLisTableWidget->setItem(rownum, 1, new QTableWidgetItem(songinfo.timelength));
        m_musicPlayList->setCurrentIndex(0);
    }
    else
    {
        for(int i=0;i<m_listResult.length();i++)
        {
            if(songinfo.playPath == m_listResult.at(i).playPath || songinfo.songName ==  m_listResult.at(i).songName)
            {
                m_musicPlayList->setCurrentIndex(i);
                break;
            }
            else if(songinfo.playPath != m_listResult.at(i).playPath&&i ==m_listResult.length()-1 )
            {
                m_musicPlayList->addMedia(QUrl(songinfo.playPath));
                m_listResult.append(songinfo);
                int rownum = ui->m_playingLisTableWidget->rowCount();
                ui->m_playingLisTableWidget->insertRow(rownum);
                ui->m_playingLisTableWidget->setItem(rownum, 0, new QTableWidgetItem(songinfo.songName));
                ui->m_playingLisTableWidget->setItem(rownum, 1, new QTableWidgetItem(songinfo.timelength));
                m_musicPlayList->setCurrentIndex(rownum-1);
            }
        }
    }
    ui->m_pLabPlayingSongSize->setText( QString("%1").arg(m_listResult.length()));
    m_musicPlayer->play();
    ui->m_pButSongPlay->setText("😕");
    ui->m_pButSongPlay->setToolTip("暂停");
}

播放模式控制

//单曲循环
void MainWindow::on_m_pButSingleCycle_clicked()
{
    ui->WidgetMode->hide();
    if(m_musicPlayList == nullptr)
        return ;
    ui->m_pButChosePlayMode->setText("₪¹");
    ui->m_pButChosePlayMode->setToolTip(QStringLiteral("单曲循环"));
    m_musicPlayList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
}

void MainWindow::on_m_pButRandomn_clicked()
{
    ui->WidgetMode->hide();
    if(!m_musicPlayList)
        return ;
    ui->m_pButChosePlayMode->setText("≈");
    ui->m_pButChosePlayMode->setToolTip(QStringLiteral("随机播放"));
    m_musicPlayList->setPlaybackMode(QMediaPlaylist::Random);
}

void MainWindow::on_m_pButAllCycle_clicked()
{
    ui->WidgetMode->hide();
    if(!m_musicPlayList)
        return ;
    ui->m_pButChosePlayMode->setToolTip(QStringLiteral("列表循环"));
    ui->m_pButChosePlayMode->setText("⇄");
    m_musicPlayList->setPlaybackMode(QMediaPlaylist::Loop);
}

void MainWindow::on_m_pButSequential_clicked()
{
    ui->WidgetMode->hide();
    if(!m_musicPlayList)
        return ;
    ui->m_pButChosePlayMode->setText("⇉");
    ui->m_pButChosePlayMode->setToolTip(QStringLiteral("顺序播放"));
    m_musicPlayList->setPlaybackMode(QMediaPlaylist::Sequential);

}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值