編程練習:MP3播放器

來源:互聯網
上載者:User

標籤:c++   音頻播放   

功能介紹:

MP3播放器

構思過程:滿足基本的播放要求(播放/暫停,快進,快退),帶有歌詞顯示,標籤顯示,帶曲目列表,支援中文

用到的工具(平台:Windows XP SP3):

程式設計語言:C++

表徵圖製作:Photo shop

音頻檔案標籤庫:mediaInfo(第三方庫)

標籤編碼轉換:sqlite3資料庫及sqlite3 C++庫(提前已經將對應的unicode和gbk編碼用C++錄入sqlite3資料庫,過程如果遇到需要,則直接查表調用即可)


檔案目錄:

程式運行介面:

初始狀態


添加多個檔案狀態

列表橫向擺放


主要代碼部分

/* *功能: 音頻播放器 * KAKASI ([email protected]) *時間: 2014-6-1 *版本: V1.0 * */#include "musicPlayer.h"#include <QHBoxLayout>#include <QVBoxLayout>#include <QGridLayout>#include <QPixmap>#include <QBitmap>#include <QPainter>#include <QIcon>#include <QFile>#include <QTextStream>#include <QPushButton>#include <QMediaMetaData>#include <QDebug>#include <QLibrary>#include <stdio.h>#include <QFileInfo>#include <QFileDialog>#include <QLocale>#include <iostream>#include <QByteArray>#include <iostream>#include <QByteArray>#include <string.h>#include <stdlib.h>#include <locale.h>#include <bitset>#include <iomanip>#include <QTextCodec>#include "QMediaInfo.h"using namespace std;#define cout qDebug()MusicPlayer::MusicPlayer(QWidget *parent)    :QWidget(parent){    //some information init    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);    isMouseDown = false;    QPushButton *listBtn = new QPushButton("L");    listBtn->setMaximumSize(20,20);    connect(listBtn, SIGNAL(clicked()), SLOT(showList()));    listBtn->setStyleSheet("background:gray");    QPushButton *loadBtn = new QPushButton("O");    loadBtn->setMaximumSize(20,20);    connect(loadBtn, SIGNAL(clicked()), SLOT(loadMusics()));    loadBtn->setStyleSheet("background:gray");    QPushButton *minBtn = new QPushButton("-");    minBtn->setMaximumSize(20,20);    connect(minBtn, SIGNAL(clicked()), SLOT(setMin()));    minBtn->setStyleSheet("background:gray");    QPushButton *exitBtn = new QPushButton("X");    exitBtn->setMaximumSize(30,20);    connect(exitBtn, SIGNAL(clicked()),SLOT(close()));    exitBtn->setStyleSheet("background:gray; text-align:top");    QHBoxLayout *titleLayout = new QHBoxLayout;    titleLayout->addStretch();    titleLayout->addWidget(listBtn,0,Qt::AlignTop);    titleLayout->addWidget(loadBtn,0,Qt::AlignTop);    titleLayout->addWidget(minBtn,0,Qt::AlignTop);    titleLayout->addWidget(exitBtn,0,Qt::AlignTop);    titleLayout->setSpacing(0);    titleLayout->setContentsMargins(0, 0, 0, 0);    //layout    musicNameLabel = new MyLabel();    musicNameLabel->setMinimumWidth(200);    musicNameLabel->setText("Take Me Away");    musicNameLabel->setStyleSheet("font-size:23px; font-family: 隸書; color:white");    authorLabel = new MyLabel();    authorLabel->setText("Avril");    authorLabel->setStyleSheet("font-size:14px; font-family:隸書; color:white");    timeLabel = new MyLabel();    totalTime = 302;    timeLabel->setText(tr("T: <span style='color:Coral'>%1</span> / %2").arg(getTimeStr(0)).arg(getTimeStr(totalTime)));    timeLabel->setStyleSheet("font-size:14px; font-family:隸書;color:white");    volLabel = new MyLabel;    volLabel->setText(tr("V:%1").arg("30%"));    volLabel->setStyleSheet("font-size:14px; font-family:隸書; color:white");    QHBoxLayout *timeAndVolLabel = new QHBoxLayout;    timeAndVolLabel->addWidget(volLabel);    timeAndVolLabel->addStretch();    timeAndVolLabel->addWidget(timeLabel);    prevLabel = new MyLabel;    playOrPauseLabel = new MyLabel;    nextLabel = new MyLabel;    connect(playOrPauseLabel, SIGNAL(clicked()), SLOT(playOrPause()));    connect(nextLabel, SIGNAL(clicked()), SLOT(next()));    connect(prevLabel, SIGNAL(clicked()), SLOT(prev()));    QPixmap img1("images/prev3.png");    QPixmap img2("images/play.png");    QPixmap img3("images/next3.png");    prevLabel->setPixmap(img1.scaled(40,40));    playOrPauseLabel->setPixmap(img2.scaled(60,60));    nextLabel->setPixmap(img3.scaled(40,40));    prevLabel->resize(40,40);    playOrPauseLabel->resize(60,60);    nextLabel->resize(40,40);    prevLabel->setStyleSheet("border-style:flat;");    playOrPauseLabel->setStyleSheet("border-style:flat");    nextLabel->setStyleSheet("border-style:flat");    QString smallStyleStr = "width:40px; height:40px; ";    QString bigStyleStr = "width:60px; height:60px; ";    prevLabel->setStyleSheet(smallStyleStr);    playOrPauseLabel->setStyleSheet(bigStyleStr);    nextLabel->setStyleSheet(smallStyleStr);    picLabel = new MyLabel();    picLabel->resize(85,85);    picLabel->setStyleSheet("margin-left:6px;margin-right:10px;");    QPixmap pic("images/logo.png");    picLabel->setPixmap(pic);    QHBoxLayout *picLayout = new QHBoxLayout;    picLayout->addWidget(picLabel);    space = new MyLabel;    space->setText("<hr>");    currentLRC = new MyLabel("<center> </center>");    currentLRC->setStyleSheet("font-size:25px; font-family:隸書;color:DeepSkyBlue;");    nextLRC = new MyLabel("<center> </center>");    nextLRC->setStyleSheet("font-size:15px; font-family:隸書; color:LightGrey;");    progressSlider = new QSlider(Qt::Horizontal);    progressSlider->setRange(0,totalTime);    connect(progressSlider, SIGNAL(sliderMoved(int)), SLOT(setPosition(int)));    connect(progressSlider, SIGNAL(sliderReleased()), SLOT(setPosition()));    volSlider = new QSlider(Qt::Horizontal);    volSlider->setRange(0,100);    volSlider->setValue(30);    connect(volSlider, SIGNAL(valueChanged(int)), SLOT(changeVol(int)));    QFile file("qss/style1.qss");    file.open(QFile::ReadOnly);    volSlider->setStyleSheet(file.readAll());    file.close();    file.setFileName("qss/style2.qss");    file.open(QFile::ReadOnly);    progressSlider->setStyleSheet(file.readAll());    progressSlider->setMinimumWidth(240);    QHBoxLayout *slider = new QHBoxLayout;    slider->addWidget(volSlider);    slider->addStretch();    slider->addWidget(progressSlider);    QVBoxLayout *midLayout = new QVBoxLayout();    midLayout->addWidget(musicNameLabel);    midLayout->addWidget(authorLabel);    midLayout->addLayout(timeAndVolLabel);    QHBoxLayout *operationLayout = new QHBoxLayout();    operationLayout->addWidget(prevLabel, 0,Qt::AlignRight);    operationLayout->addWidget(playOrPauseLabel, 0, Qt::AlignRight);    operationLayout->addWidget(nextLabel, 0, Qt::AlignRight);    QHBoxLayout *topLayout = new QHBoxLayout;    topLayout->addLayout(midLayout);    topLayout->addLayout(operationLayout);    QVBoxLayout *rightLayout = new QVBoxLayout;    rightLayout->addLayout(topLayout);    rightLayout->addLayout(slider);    QVBoxLayout *lrcLayout = new QVBoxLayout;    lrcLayout->addWidget(currentLRC);    lrcLayout->addWidget(nextLRC);    QHBoxLayout *mainLayout1 = new QHBoxLayout();    mainLayout1->addLayout(picLayout);    mainLayout1->addLayout(rightLayout);    QVBoxLayout *mainLayout2 = new QVBoxLayout();    mainLayout2->addLayout(titleLayout);    mainLayout2->addLayout(mainLayout1);    mainLayout2->addWidget(space);    mainLayout2->addLayout(lrcLayout);    mainLayout2->setSpacing(0);    mainLayout2->setContentsMargins(5,0,15,15);    this->setLayout(mainLayout2);    this->resize(this->sizeHint()); //important for setRounded(bool)    setAttribute(Qt::WA_TranslucentBackground, true);    setRounded(true);    isPlaying = false;    listUi = 0;    list = new QStringList;    playerList = new QMediaPlaylist;    playerList->setCurrentIndex(0);    playerList->setPlaybackMode(QMediaPlaylist::Loop);    player = new QMediaPlayer;    player->setPlaylist(playerList);    connect(player,SIGNAL(positionChanged(qint64)), SLOT(positionChange(qint64)));    connect(player,SIGNAL(durationChanged(qint64)), SLOT(durationChange(qint64)));    volSlider->setValue(player->volume());    createActions();    lrc = new QMap<int,QString>;    updateInfo();}void MusicPlayer::closeEvent(QCloseEvent *event){    if (listUi != 0)        listUi->close();    event->accept();}//顯示曲目列表void MusicPlayer::showList(){    if (listUi == 0)    {        listUi = new MediaList(this->sizeHint(), this->pos(), this);        listUi->show();        return;    }    if (listUi->isHidden())    {        listUi->show();    }    else    {        listUi->hide();    }}//開啟音頻檔案void MusicPlayer::loadMusics(){    QStringList files = QFileDialog::getOpenFileNames(                            this,                            "Select one or more files to open",                            "/home",                            "musics (*.mp3 *.wma *.wav)");    int begin = list->length();    if (!files.isEmpty())    {        QString str;        foreach (str, files)        {            list->append(str);            playerList->addMedia(QUrl::fromLocalFile(list->last()));        }        playerList->setCurrentIndex(begin);        updateInfo();        if (listUi == 0)        {            listUi = new MediaList(this->sizeHint(), this->pos(), this);        }        if (listUi != 0)        {            listUi->addFiles(files);        }    }    //歌詞初始化    initLrc();    player->play();    QPixmap img(("images/pause.png"));    playOrPauseLabel->setPixmap(img.scaled(60,60));}//任意地區右鍵菜單void MusicPlayer::contextMenuEvent(QContextMenuEvent *event){    menu->clear();    menu->addAction(openAction);    menu->addAction(exitAction);    menu->exec(QCursor::pos());    event->accept();}//void MusicPlayer::createActions(){    menu = new QMenu(this);    openAction = new QAction("open",this);    exitAction = new QAction("exit",this);}//更新介面資訊void MusicPlayer::updateInfo(){    QString title;    QString author;    QFileInfo f;    if (!list->empty())    {        QString fileName = list->at(playerList->currentIndex());        info = new QMediaInfo(fileName);        f.setFile(fileName);        if (f.suffix().toUpper() == "MP3")        {            title = info->getInfo("Title",true);            author = info->getInfo("Performer",true);        }        else        {            title = info->getInfo("Title");            author = info->getInfo("Performer");        }        title = f.baseName();        //cout << title << author;        delete info;    }    title.truncate(8);    if (title.length() > 8)        title += "..";    if (title.isEmpty())        title = "Title:Unknown";    if (author.isEmpty())        author = "Author:Unknown";    musicNameLabel->setText(title);    authorLabel->setText(author);    curLrc = "";    nextLrcStr = "";    currentLRC->setText("<center>" + curLrc +"</center>");    nextLRC->setText("<center>" + nextLrcStr +"</center>");    //歌詞初始化    initLrc();}//下一首void MusicPlayer::next(){    playerList->next();    //qDebug()<<playerList->currentIndex();    updateInfo();    //歌詞初始化    initLrc();}//上一首void MusicPlayer::prev(){    playerList->previous();    updateInfo();    //歌詞初始化    initLrc();}//時間更新void MusicPlayer::durationChange(qint64 duration){    totalTime = duration;    progressSlider->setRange(0, duration);    timeLabel->setText(tr("T: <span style='color:Coral'>%1</span> / %2").arg(getTimeStr(0)).arg(getTimeStr(totalTime)));}//進度更新void MusicPlayer::positionChange(qint64 pos){    if (!progressSlider->isSliderDown())        progressSlider->setValue(pos);    timeLabel->setText(tr("T: <span style='color:Coral'>%1</span> / %2").arg(getTimeStr(pos)).arg(getTimeStr(totalTime)));    //更新歌詞顯示getTimeStr(pos)    if (lrc->empty())        return;    int key = pos / 1000;    QMap<int, QString>::iterator it;    if (lrc->contains(key))    {        curLrc = lrc->value(key);        it = lrc->find(key);        if (it++ != lrc->end())        {            nextLrcStr = it.value();        }    }    curLrc = curLrc.trimmed();    curLrc.truncate(15);    if (curLrc.length() > 15)        curLrc += "...";    nextLrcStr = nextLrcStr.trimmed();    nextLrcStr.truncate(15);    if(nextLrcStr.length() > 15)        nextLrcStr += "...";    currentLRC->setText("<center>" + curLrc +"</center>");    nextLRC->setText("<center>" + nextLrcStr +"</center>");    //cout << pos << curLrc;}//初始化歌詞void MusicPlayer::initLrc(){    if (lrc != 0)        lrc->clear();    if (list == 0)        return;    curLrc = "";    nextLrcStr = "";    //思路,用一個map儲存10-》string的格式,然後時間到後載入,等待下一個時間    if (list->isEmpty())        return ;    if (playerList == 0)        return;    QString fileNames = list->at(playerList->currentIndex());    QString lrcNames = fileNames;    int n = lrcNames.lastIndexOf('.');    lrcNames.replace(n,lrcNames.length() - n,".lrc");    QFile file(lrcNames);    QString line;    if (file.open(QIODevice::ReadOnly | QIODevice::Text))    {        QTextStream stream(&file);        while(!stream.atEnd())        {            line = stream.readLine();            int num = line.count('[');            int last = line.lastIndexOf(']');            QString str = line.right(line.length() - last -1);            int begin = 0;            while(num-- >0)            {                QString strs = line.mid(begin,10);                begin += 10;                strs.replace("[","");                strs.replace("]","");                int s = getSeconds(strs);                if (s > 0)                {                    lrc->insert(s,str.trimmed());                    //cout << s << "=" << lrc->value(s);                }            }        }    }}void MusicPlayer::setPosition(int pos){    currentPos = pos;}void MusicPlayer::setPosition(){    player->setPosition(currentPos);}//play or pausevoid MusicPlayer::playOrPause(){    QPixmap img(("images/play.png"));    if (!isPlaying)    {        isPlaying = true;        player->play();        img.load("images/pause.png");    }    else    {        isPlaying = false;        player->pause();        img.load("images/play.png");    }    playOrPauseLabel->setPixmap(img.scaled(60,60));}//時間字串00:00:00得到毫秒/秒,依賴作業系統qint32 MusicPlayer::getSeconds(QString &timeStr){    QStringList strs = timeStr.split(":");    QString s;    if (strs.size() > 0)    {        int m = strs.at(0).toDouble();        int s = strs.at(1).toDouble();        //cout << "m" << m;        //cout << "s" << s;        return m * 60 + s;    }    return 0;}//從時,分,秒擷取總數秒qint32 MusicPlayer::getSeconds(qint32 seconds_, qint32 minutes_, qint32 hours_){    return seconds_ + minutes_ * 60 + hours_ * 3600;}//從duuation擷取字串QString MusicPlayer::getTimeStr(qint32 seconds_){    seconds_ /= 1000;    qint32 minutes = seconds_ % 3600 / 60;    qint32 seconds = seconds_ % 3600 % 60;    minutes = minutes > 99 ? 99 : minutes + 100;    seconds = seconds + 100;    return QString::number(minutes).right(2).append(":").append(QString::number(seconds).right(2));}//改變時間提示//void MusicPlayer::changeTime(qint64 time)//{//    timeLabel->setText(tr("T: <span style='color:Coral'>%1</span> / %2").arg(getTimeStr(time/1000)).arg(getTimeStr(totalTime)));//}//最小void MusicPlayer::setMin(){    if (!this->isMinimized())    {        this->showMinimized();    }}//改變音量提示void MusicPlayer::changeVol(int vol){    volLabel->setText(tr("V:%1%").arg(QString::number(vol)));    player->setVolume(vol);}//表單透明程度void MusicPlayer::paintEvent(QPaintEvent *event){    QPainter painter(this);    painter.fillRect(this->rect(), QColor(100, 100, 100, 255));  //QColor最後一個參數80代表背景的透明度}//圓角表單void MusicPlayer::setRounded(bool b){    if (!bmp)    {        delete bmp;        bmp = 0L;    }    if (!p)    {        delete p;        p = 0L;    }    bmp = new QBitmap(this->size());    bmp->fill();             //fills the pixmap with white (default value) color    p = new QPainter(bmp);    p->setPen(Qt::NoPen);    p->setBrush(Qt::black);    if (b)        p->drawRoundedRect(bmp->rect(),15,15);    else        p->drawRoundedRect(bmp->rect(),0,0);    setMask(*bmp);//設定表單遮罩}//移動表單相關void MusicPlayer::mousePressEvent(QMouseEvent *event){    if (event->button() == Qt::LeftButton)    {        isMouseDown = true;        oldLocation = event->globalPos() - this->pos();    }    event->ignore();}//移動表單相關void MusicPlayer::mouseMoveEvent(QMouseEvent *event){    if (isMouseDown)    {        this->move(event->globalPos() - oldLocation);        if (listUi != 0)        {            listUi->moves(this->sizeHint(), this->pos());        }    }    event->ignore();}//移動表單相關void MusicPlayer::mouseReleaseEvent(QMouseEvent *event){    isMouseDown = false;    event->ignore();}

(轉載請註明作者和出處, 未經允許請勿用於商業用途)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.