1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 用Qt写一个简单的音乐播放器(六):显示歌词(正则表达式)

用Qt写一个简单的音乐播放器(六):显示歌词(正则表达式)

时间:2023-12-29 14:51:43

相关推荐

用Qt写一个简单的音乐播放器(六):显示歌词(正则表达式)

一、前言

在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐。

在用Qt写一个简单的音乐播放器(二):增加界面(开始和暂停音乐)中,我们增加了播放音乐/暂停音乐的按钮。

在用Qt写一个简单的音乐播放器(三):增加界面(播放跳转与音量控制)中,我们加入了播放控制和音量控制。

在用Qt写一个简单的音乐播放器(四):歌曲浏览、上一曲、下一曲中,我们增加了歌曲选择的功能。

在用Qt写一个简单的音乐播放器(五):歌曲播放时间显示中,我们为歌曲播放增加播放时间显示。

那么第六篇文章来谈一谈如何显示歌词:

二、读取歌词文件

如图所示,首先将同名的歌词文件放入歌曲相同的路径中。

如上图所示,歌词文件的内容形式为一行一句,所以我们可以将歌词文件逐行读入,代码如下。

mainwindow.cpp中做如下修改

void MainWindow::on_lwMusicList_itemDoubleClicked(QListWidgetItem *item){m_PlayRow = ui->lwMusicList->row(item);m_mediaPlayer.stop();m_mediaPlayer.setMedia(QUrl::fromLocalFile(m_playPath+"/"+item->text()));m_mediaPlayer.play();QString name = item->text().left(item->text().lastIndexOf("."));if(!lyrics.readLyricsFile(m_playPath+"/"+name+".lrc")){ui->lblLyrics1->setText("未检测到歌词文件");ui->lblLyrics2->setText("请检查歌词文件是否存在");}lyricsID = 0;ui->hSliderPlayProgress->setValue(m_mediaPlayer.position());ui->btnPlay->setText("Pause");connect(timer, SIGNAL(timeout()), this, SLOT(setSliderValue()));connect(&m_mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(getduration()));connect(&m_mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(setPlayTime()));}

新建一个lyrics类文件,加入以下代码:

bool Lyrics::readLyricsFile(QString lyricsPath){QFile file(lyricsPath);file.open(QIODevice::ReadOnly | QIODevice::Text);QString line="";while((line=file.readLine())>0){qDebug()<<line;analysisLyricsFile(line);//解析歌词文件内容}return true;}

三、解析歌词(正则表达式的使用)

歌词读取一行,我们就对这个歌词进行解析。我这里将歌词分为了两部分:时间和内容。用正则表达式匹配后,将时间计算为毫秒存入listLyricsTime,将内容存入listLyricsText。

bool Lyrics::analysisLyricsFile(QString line){if(line == NULL || line.isEmpty()){qDebug()<<"thie line is empty!";return false;}QRegularExpression regularExpression("\\[(\\d+)?:(\\d+)?(\\.\\d+)?\\](.*)?");int index = 0;QRegularExpressionMatch match;match = regularExpression.match(line, index);if(match.hasMatch()) {int totalTime;totalTime = match.captured(1).toInt() * 60000 + match.captured(2).toInt() * 1000;/* 计算该时间点毫秒数 */QString currentText =QString::fromStdString(match.captured(4).toStdString());/* 获取歌词文本*/listLyricsText.push_back(currentText);listLyricsTime.push_back(totalTime);return true;}return false;}

四、歌词显示

1.控件

如图所示:拖两个label,一个用来显示播放当前歌词(设置为左对齐),一个用来显示下一句歌词(设置为右对齐)。

2.代码

在播放时间改变的时候,判断当前音乐的播放时间,是否大于歌词时间,若大于,则显示歌词。代码如下:

void MainWindow::setPlayTime(){if(!lyrics.getListLyricsTime().empty()&&m_mediaPlayer.position()>=lyrics.getListLyricsTime().at(lyricsID)){ui->lblLyrics1->setText(lyrics.getListLyricsText().at(lyricsID));ui->lblLyrics2->setText(lyrics.getListLyricsText().at(lyricsID+1));lyricsID++;}ui->lblPlayTime->setText(settime(m_mediaPlayer.position()));}

五、效果

六、完整代码

当然这个完整也只是相对完整,不过这个基本已经很全了。

1.歌词类

Lyrics.cpp

#include "lyrics.h"QList<QString> Lyrics::getListLyricsText() const{return listLyricsText;}QList<int> Lyrics::getListLyricsTime() const{return listLyricsTime;}Lyrics::Lyrics(QString lyricsPath){this->lyricsPath = lyricsPath;}Lyrics::Lyrics(){}bool Lyrics::readLyricsFile(QString lyricsPath){QFile file(lyricsPath);if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){listLyricsText.clear();listLyricsTime.clear();return false;}QString line="";while((line=file.readLine())>0){qDebug()<<line;analysisLyricsFile(line);}return true;}bool Lyrics::analysisLyricsFile(QString line){if(line == NULL || line.isEmpty()){qDebug()<<"thie line is empty!";return false;}QRegularExpression regularExpression("\\[(\\d+)?:(\\d+)?(\\.\\d+)?\\](.*)?");int index = 0;QRegularExpressionMatch match;match = regularExpression.match(line, index);if(match.hasMatch()) {int totalTime;totalTime = match.captured(1).toInt() * 60000 + match.captured(2).toInt() * 1000;/* 计算该时间点毫秒数 */QString currentText =QString::fromStdString(match.captured(4).toStdString());/* 获取歌词文本*/qDebug()<<totalTime;qDebug()<<currentText;listLyricsText.push_back(currentText);listLyricsTime.push_back(totalTime);return true;}return false;}

lyrics.h

#ifndef LYRICS_H#define LYRICS_H#include <QWidget>#include <QString>#include <QMap>#include <iostream>#include <QFile>#include <QDebug>#include <QRegExp>#include <QList>#include <QRegularExpression>#include <QRegularExpressionMatch>using namespace std;class Lyrics{private:QString lyricsPath;QList<QString> listLyricsText;QList<int> listLyricsTime;public:Lyrics(QString lyricsPath);Lyrics();bool readLyricsFile(QString lyricsPath);bool analysisLyricsFile(QString line);QList<QString> getListLyricsText() const;QList<int> getListLyricsTime() const;};#endif // LYRICS_H

2.mainwindow

mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);timer = new QTimer();timer->setInterval(2000);timer->start();ui->vSliderVolume->setVisible(false);QString fileName = "D:/music";QDir dir(fileName);QStringList nameFilters;nameFilters << "*.mp3";QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);ui->lwMusicList->addItems(files);m_playPath = fileName;}MainWindow::~MainWindow(){delete ui;}void MainWindow::on_btnPlay_clicked(){if(QMediaPlayer:: PlayingState == m_mediaPlayer.state()){m_mediaPlayer.pause();ui->btnPlay->setText("Play");}else{m_mediaPlayer.play();ui->btnPlay->setText("Pause");}}void MainWindow::on_hSliderPlayProgress_sliderMoved(int position){m_mediaPlayer.setPosition(m_mediaPlayer.duration()*position/100);}void MainWindow::setSliderValue(){ui->hSliderPlayProgress->setValue(m_mediaPlayer.position()*100/m_mediaPlayer.duration());if(m_mediaPlayer.position()>=m_mediaPlayer.duration()){on_btnNextMusic_clicked();}}void MainWindow::on_vSliderVolume_sliderMoved(int position){m_mediaPlayer.setVolume(position);}void MainWindow::on_lwMusicList_itemDoubleClicked(QListWidgetItem *item){m_PlayRow = ui->lwMusicList->row(item);m_mediaPlayer.stop();m_mediaPlayer.setMedia(QUrl::fromLocalFile(m_playPath+"/"+item->text()));m_mediaPlayer.play();QString name = item->text().left(item->text().lastIndexOf("."));if(!lyrics.readLyricsFile(m_playPath+"/"+name+".lrc")){ui->lblLyrics1->setText("未检测到歌词文件");ui->lblLyrics2->setText("请检查歌词文件是否存在");}lyricsID = 0;ui->hSliderPlayProgress->setValue(m_mediaPlayer.position());ui->btnPlay->setText("Pause");connect(timer, SIGNAL(timeout()), this, SLOT(setSliderValue()));connect(&m_mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(getduration()));connect(&m_mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(setPlayTime()));}void MainWindow::on_btnAddMusic_clicked(){QString fileName = QFileDialog::getExistingDirectory(NULL,"Select Music Dir",".",NULL);QDir dir(fileName);QStringList nameFilters;nameFilters << "*.mp3";QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);ui->lwMusicList->addItems(files);m_playPath = fileName;}void MainWindow::on_btnPreMusic_clicked(){if(m_PlayRow == 0){m_PlayRow = ui->lwMusicList->count() - 1;}else{m_PlayRow--;}QListWidgetItem *item = ui->lwMusicList->item(m_PlayRow);item->setSelected(true);m_mediaPlayer.stop();m_mediaPlayer.setMedia(QUrl::fromLocalFile(m_playPath+"/"+item->text()));m_mediaPlayer.play();}void MainWindow::on_btnNextMusic_clicked(){if(m_PlayRow + 1 == ui->lwMusicList->count()){m_PlayRow = 0;}else{m_PlayRow++;}QListWidgetItem *item = ui->lwMusicList->item(m_PlayRow);item->setSelected(true);m_mediaPlayer.stop();m_mediaPlayer.setMedia(QUrl::fromLocalFile(m_playPath+"/"+item->text()));m_mediaPlayer.play();}void MainWindow::on_btnVolume_clicked(){if(ui->vSliderVolume->isVisible()){ui->vSliderVolume->setVisible(false);}else{ui->vSliderVolume->setVisible(true);}}void MainWindow::on_vSliderVolume_sliderReleased(){ui->vSliderVolume->setVisible(false);}QString MainWindow::settime(int time){int h,m,s;time /= 1000; //获得的时间是以毫秒为单位的h = time/3600;m = (time-h*3600)/60;s = time-h*3600-m*60;return QString("%1:%2:%3").arg(h).arg(m).arg(s);}void MainWindow::getduration(){playtime = m_mediaPlayer.duration();ui->lblMusicTime->setText(settime(playtime));}void MainWindow::setPlayTime(){if(!lyrics.getListLyricsTime().empty()&&m_mediaPlayer.position()>=lyrics.getListLyricsTime().at(lyricsID)&&lyricsID<lyrics.getListLyricsTime().size()-1){ui->lblLyrics1->setText(lyrics.getListLyricsText().at(lyricsID));ui->lblLyrics2->setText(lyrics.getListLyricsText().at(lyricsID+1));lyricsID++;}ui->lblPlayTime->setText(settime(m_mediaPlayer.position()));}

mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QtMultimedia/QMediaPlayer> // 包含头文件#include <QTimer>#include <QListWidgetItem>#include <QString>#include <QFileDialog>#include <lyrics.h>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();QString settime(int time);private slots:void on_btnPlay_clicked();void on_hSliderPlayProgress_sliderMoved(int position);void setSliderValue();void on_vSliderVolume_sliderMoved(int position);void on_lwMusicList_itemDoubleClicked(QListWidgetItem *item);void on_btnAddMusic_clicked();void on_btnPreMusic_clicked();void on_btnNextMusic_clicked();void on_btnVolume_clicked();void on_vSliderVolume_sliderReleased();void getduration();void setPlayTime();private:Ui::MainWindow *ui;QMediaPlayer m_mediaPlayer; // 实例化对象QTimer *timer; //定时器QString m_playPath;Lyrics lyrics;int m_PlayRow;int playtime;int lyricsID = 0;};#endif // MAINWINDOW_H

七、最后

从无到有,从最开始的播放音乐、开始、暂停、播放时间、跳转播放、音量控制、选择歌曲,到今天的歌词显示,一个简单的本地音乐播放器也终于写完了。当然它很丑,但是至少也是基本的功能也都有不是,剩下的界面美化啊,网络播放啊,等等功能吧,以后慢慢优化吧,当然现在这个代码也是有一定问题的,bug不少,代码结构也不好,以后功能越来越多的时候,肯定是要重构的。

用Qt写一个简单的音乐播放器(七):界面美化(QSS样式表)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。