一、前言

在用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样式表)

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

  1. 用Qt写一个简单的音乐播放器(三):增加界面(播放跳转与音量控制)

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

  2. 用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐

    一.前言 QMediaplayer可以用于解析音频文件和视频文件,继承自QMediaObject,涉及到的对象为QMediaContent.QMediaObject可以提供关于媒体内容的接入,通过UR ...

  3. 用Qt写一个简单的音乐播放器(五):歌曲播放时间显示

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

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

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

  5. 用Qt写一个简单的音乐播放器(四):歌曲浏览、上一曲、下一曲

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

  6. 用C/C++写一个简单的音乐播放器(基于windows控制台编程)

    学习内容:1. 使用单例模式设计,让加载资源唯一化. 2. 控件管理. 3. 按键消息处理 4. 音频函数的使用 1. 资源管理与加载 1.1 公共头文件 将用到的头文件保存到一个公共头文件" ...

  7. 用java写一个简单的音乐播放器(二)

    前言 之前的版本,有位朋友说无法实现暂停播放,还有一些其他无伤大雅的bug,所以我就查了一波资料,研究了一下后,进行的一波优化. 这个版本的播放器,实现了:上一首.下一首.暂停/播放.目录浏览等功能. ...

  8. 使用python加PyQt5,利用QMediaPlayer写一个简易的音乐播放器(进度条拖动,音量改变,播放停止切换,歌曲列表))

    当你学习了python之后,总想着利用它去做些什么,无论是制作小工具还是小游戏,都是一种锻炼. 那么,利用python加上PyQt5写一个简单的音乐播放器,可能会是一个有趣的体验. 下面我会分享一下如 ...

  9. HTML+CSS+原生JS写一个简易的音乐播放器(仅播放一首歌)

    用HTML+CSS+原生JS写一个简易的音乐播放器(仅播放一首歌) 效果如下:(鼠标点击按钮可以实现播放或暂停,按钮会旋转,实现了歌词同步,功能还需改进) 代码如下: <!DOCTYPE htm ...

最新文章

  1. mysql bin.000013_mysql运维-二进制日志BINARY LOG清理_ mysql-bin磁盘占用高处理办法
  2. req.xhr在express中的应用
  3. 浅谈React虚拟DOM
  4. 15个相当不错的jQuery技巧
  5. 新手学linux之-----------memroy.c
  6. 【转】xilinx usb下载器 速度高速极限设置 JTAG-SMT2 JTAG-HS2 JTAG-HS3和Platform Cable USB DLC9 DLC10速度测试
  7. HighCharts解析之xAxis——x轴的样式
  8. ForkJoin框架简单使用
  9. 学习笔记 :E1696 C1107 错误提示
  10. Cocos2Dx之处理键盘输入
  11. C 和 CPP 混合代码cmath编译出错
  12. 配置Web.Config连接数据库
  13. github上有什么好的渗透测试软件?(Git_Pentesting_Toolkit)
  14. android 手机头提示消息,正确的手机头部声明(android,iphone)
  15. 【人话版】WEB3黑暗森林中的隐私博弈
  16. TCP和UDP和端口
  17. 公交大数据辅助分析平台建设方案(PPT)
  18. RGB格式学习:RGBx、xRGB、RGBA、ARGB等格式转换成RGB
  19. 百度地图点击触发事件介绍
  20. stm32f103c8t6--sd卡的读写flash地址空间的数据读取

热门文章

  1. 1024位密钥加密已不再安全
  2. 润乾——鼠标滑过改变行背景色
  3. 微信开发-发放普通红包(java代码实例)
  4. 每日软件分享,一起来看看吧
  5. Linux路由转发+多网卡配置(route命令)
  6. 关于计算机的外文翻译博客,个人博客网站设计外文翻译
  7. 【YOLOv7】Python基于YOLOv7的人员跌倒检测系统(源码&部署教程&数据集)
  8. 不用安装软件也能下载网页视频的方法
  9. 解决Mac中微信\QQ无法截图的问题
  10. Yolov5自学笔记之二--在游戏中实时推理并应用(实例:哈利波特手游跳舞小游戏中自动按圈圈)