QT实现简单音乐播放器

基于QT实现一个多功能媒体播放器,它能播放音频(如mp3),视频

媒体播放器界面,有进度条,可展示总播放时间、当前播放时间,进度条可拖动,有播放、暂停键,有快进、快退键,上一曲下一曲,静音,调节音量,双击播放歌曲,以及简单的歌词同步。

主界面如下:

创建三个本地文件夹分别存放MV,歌词和音乐文件

工程结构目录如下(整个结构没有设计好,所以每个视频都要单独创建文件):

mainwindow.h代码如下:

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

#include <QMediaPlayer>

#include <QMediaPlaylist>

#include <QMediaPlayer>

#include <QStringList>

#include <QDir>

#include <QTime>

#include <QTimer>

#include<videoplayer.h>

#include<videoplayer_qr.h>

#include<videoplayer_cq.h>

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

MainWindow(QWidget *parent = nullptr);

~MainWindow();

private:

Ui::MainWindow *ui;

VideoPlayer *v1;

videoplayer_qr *v_qr;

videoplayer_cq *v_cq;

bool isPlay=false;

bool ismute=false;

QString MusicPath="C:\\Users\\44637\\Music\\QTMusic";

QString LrcPath="C:\\Users\\44637\\Music\\QTLrc";

QStringList fileList; //文件名称

QStringList lrcList;

QMediaPlaylist *PlayerList;

QMediaPlayer *Player;

int moved;

int iCount=0;

QTimer *timer2;

QMap<int, QString> map;

QMap<QString, QString> *map2;

void getHeader(const char *str, QString &des);

void getTime(QString line);//改动二

private slots:

void init();//初始化

void addItem(QString name); //把歌名添加到musicname上

QStringList getFileNames(const QString &path); //获取路径下所有文件名

QStringList getLrcNames(const QString &path); //获取路径下所有文件名

void slotButtonStart();//播放

void slotButtonLast();//上一首

void slotButtonNext();//下一首

void slotShowCurrentMusic();//显示当前播放的歌曲

void volumChange(int);//控制音量

void positionChange(qint64 position);//进度条随着音乐播放变化

void seekChange(int position); //滑动滑动条快进、倒退音乐,且音乐已播放时长也跟着变化

void musicTime();//歌曲总时间

void slotShowCurrentLrc();

void showWord(int time);//显示歌词

void initlrc(const QString& fileName);//初始化歌词

void button_style();//按钮样式

void changestartbutton();

void cleanmap();

void playto(int i,int );//双击播放

void video_click_wm();//播放相应视频

void video_click_qr();

void video_click_cq();

void mute();//静音

void fastForward();//快进

void fastBack();//快退

};

#endif // MAINWINDOW_H

mainwindow.cpp代码如下:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <QDebug>

#include <QFile>

#include <QTextStream>

#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this);

connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotButtonStart);

connect(ui->Buttonlast,&QPushButton::clicked,this,&MainWindow::slotButtonLast);

connect(ui->Buttonnext,&QPushButton::clicked,this,&MainWindow::slotButtonNext);

connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::changestartbutton);

connect(ui->Buttonvideo_wm,&QPushButton::clicked,this,&MainWindow::video_click_wm);

connect(ui->Buttonvideo_qr,&QPushButton::clicked,this,&MainWindow::video_click_qr);

connect(ui->Buttonvideo_cq,&QPushButton::clicked,this,&MainWindow::video_click_cq);

connect(ui->Buttonmute,&QPushButton::clicked,this,&MainWindow::mute);

connect(ui->fastButton,&QPushButton::clicked,this,&MainWindow::fastForward);

connect(ui->fastbackButton,&QPushButton::clicked,this,&MainWindow::fastBack);

init();

}

MainWindow::~MainWindow()

{

delete ui;

}

void MainWindow::init(){

button_style();

PlayerList = new QMediaPlaylist; //实例化播放器和播放列表

Player = new QMediaPlayer;

fileList = getFileNames(this->MusicPath); //获取文件夹下所有音乐文件

lrcList = getLrcNames(this->LrcPath);

moved = 0;

qDebug()<<"ALL Music File \n"<<fileList;

qDebug()<<"ALL Lrc File \n"<<lrcList;

for(int i=0;i<fileList.size();i++){

QString fileName=fileList.at(i);

addItem(fileName);

PlayerList->addMedia(QUrl::fromLocalFile(MusicPath+"\\"+fileName));

}

PlayerList->setCurrentIndex(0);

Player->setPlaylist(PlayerList); //将播放列表加载到播放器

connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::slotShowCurrentMusic);

connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::slotShowCurrentLrc);

connect(Player,&QMediaPlayer::currentMediaChanged,this,&MainWindow::cleanmap);

connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);

connect(ui->Buttonnext,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);

connect(ui->Buttonlast,&QPushButton::clicked,this,&MainWindow::slotShowCurrentLrc);

connect(ui->Buttonstart,&QPushButton::clicked,this,&MainWindow::slotShowCurrentMusic);

connect(ui->Volumebar, SIGNAL(sliderMoved(int)), this, SLOT(volumChange(int)));

connect(Player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChange(qint64)));

connect(Player,SIGNAL(durationChanged(qint64)),this,SLOT(musicTime()));

connect(ui->Progressbar,SIGNAL(sliderMoved(int)),this,SLOT(seekChange(int)));

connect(ui->musicname,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(playto(int,int)));

}

QStringList MainWindow::getFileNames(const QString &path)

{

QDir dir(path);

QStringList nameFilters;

nameFilters << "*.mp3";

QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);

return files;

}

QStringList MainWindow::getLrcNames(const QString &path)

{

QDir dir(path);

QStringList nameFilters;

nameFilters <<"*.txt";

QStringList files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);

return files;

}

void MainWindow::addItem(QString name){

int count = ui ->musicname->rowCount();

ui->musicname->setRowCount(count+1);

QTableWidgetItem *itemName = new QTableWidgetItem(name);

itemName->setFlags(itemName->flags() & ~Qt::ItemIsEditable);

ui->musicname->setItem(count,0,itemName);

}

void MainWindow::slotShowCurrentMusic(){

int index=PlayerList->currentIndex();

QString songName=fileList.at(index);

ui->CurrentMusic->setText(songName);

}

void MainWindow::slotShowCurrentLrc(){

int index=PlayerList->currentIndex();

qDebug()<<index;

QString musicLrc=lrcList.at(index);

qDebug()<<musicLrc;

initlrc(musicLrc);

}

void MainWindow::slotButtonStart(){

if(!isPlay){

isPlay=true;

Player->setVolume(100);

Player->play();

musicTime();

}

else{

isPlay=false;

Player->pause();

musicTime();

}

}

void MainWindow::slotButtonLast(){

int currentIndex = PlayerList->currentIndex();

if(currentIndex == 0){

currentIndex=PlayerList->mediaCount();

}

else{

PlayerList->previous();

PlayerList->previousIndex();

musicTime();

}

}

void MainWindow::slotButtonNext(){

int currentIndex = PlayerList->currentIndex();

if(++currentIndex == PlayerList->mediaCount()){

currentIndex=0;}

PlayerList->setCurrentIndex(currentIndex);

musicTime();

}

void MainWindow::volumChange(int vol)

{

Player -> setVolume(vol);

}

void MainWindow::positionChange(qint64 position)

{

ui->Progressbar->setMaximum(Player->duration() / 1000);//设置滑块的长度范围为音乐长.00度

ui->Progressbar->setValue(position / 1000);//如果音乐进度改变,则改变滑块显示位置

moved = position;//让播放时间等于音乐进度(毫秒)

QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//设置时间

ui->showPro ->setText(moveTime.toString("mm:ss"));//显示时间

QString t=moveTime.toString("mm:ss");

QString mm = t.mid(0,2);

QString ss = t.mid(3, 2);

int m = mm.toInt();

int s = ss.toInt();

int time = m*60*1000 + s*1000;

showWord(time);

}

void MainWindow::seekChange(int position)

{

Player -> setPosition(position * 1000);//如果滑块改变位置,则改变音乐进度

moved = position * 1000;//让播放时间等于音乐进度(毫秒)

QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//设置时间

ui->showPro ->setText(moveTime.toString("mm:ss"));//显示时间

}

void MainWindow::musicTime(){

qint64 time = Player->duration();

QTime Time(0,(time % (1000 * 60 * 60)) / (1000 * 60),(time % (1000 * 60)) / 1000);

ui->MusicTime->setText(Time.toString("mm:ss"));

qDebug()<<"time:"<<Time;

}

void MainWindow::showWord(int time)

{

if(map.contains(time))

{

ui->label1->setText(map.value(time));

}

else{

qDebug()<<"继续上一句歌词";

}

}

void MainWindow::getHeader(const char *str, QString &des)

{

des = des.remove(str);

des = des.remove("]");

}

void MainWindow::getTime(QString line)//获取lrc文件的每句的时间

{

if(line.startsWith("["))

{

int index = line.indexOf("]");

QString t = line.mid(1, index - 1);

QString mm = t.mid(0,2);

QString ss = t.mid(3, 2);

int m = mm.toInt();

int s = ss.toInt();

int time = m*60*1000 + s*1000;

t = line.mid(index + 1);

index = t.lastIndexOf("]");

if(index < 0)

{

map.insert(time, t);

}

else

{

t = t.mid(index + 1);

map.insert(time, t);

getTime(t);

qDebug()<<"time123:"<<time;

}

}

}

void MainWindow::initlrc(const QString& fileName)

{

QMap<int, QString> map;

QString l;

QFile file("C:\\Users\\44637\\Music\\QTLrc\\"+fileName);

if(file.exists()){

qDebug()<<"文件存在";

}

else{

qDebug()<<"文件不存在";

}

if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){

return;

}

QTextCodec *codec = QTextCodec::codecForName("GBK");

while(!file.atEnd())

{

QString line = codec->toUnicode(file.readLine());

QString s(line);

if(s.length()<4)

continue;

if(s.startsWith("[ti:"))

{

getHeader("[ti:", s);

map.insert(0, s);

ui->topmusicname->setText(s);

continue;

}

else if(s.startsWith("[ar:"))

{

getHeader("[ar:", s);

map.insert(1000, s);

ui->singer->setText("歌手:"+s);

continue;

}

else if(s.startsWith("[al:"))

{

getHeader("[al:", s);

map.insert(2000, s);

ui->album->setText("专辑:"+s);

continue;

}

else if(s.startsWith("[by:"))

{

getHeader("[by:", s);

map.insert(3000, s);

continue;

}

else

{

getTime(s);

}

}

file.close();

}

void MainWindow::button_style(){

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));

ui->Buttonlast->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\last.jpg"));

ui->Buttonnext->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\next.png"));

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));

ui->Buttonvideo_qr->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));

ui->Buttonvideo_wm->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));

ui->Buttonvideo_cq->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\MV.png"));

}

void MainWindow::changestartbutton(){

if(isPlay)

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));

else

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));

}

void MainWindow::cleanmap(){

map.clear();

}

void MainWindow::playto(int i,int )

{

PlayerList->setCurrentIndex(i);

isPlay=true;

changestartbutton();

QString musicLrc=lrcList.at(i);

initlrc(musicLrc);

Player->play();

}

void MainWindow::video_click_wm(){

v1= new VideoPlayer(this);

v1->setModal(false);

v1->show();

}

void MainWindow::video_click_qr(){

v_qr= new videoplayer_qr(this);

v_qr->setModal(false);

v_qr->show();

}

void MainWindow::video_click_cq(){

v_cq= new videoplayer_cq(this);

v_cq->setModal(false);

v_cq->show();

}

void MainWindow::mute(){

if(!ismute){

Player -> setVolume(0);

//ui->voiceslider->value();

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\mute.png"));

ismute=true;

}

else{

Player -> setVolume(100);

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));

ismute=false;

}

}

void MainWindow::fastForward(){

qint64 position=Player->position();

qDebug()<<"position"<<position;

position=position+5000;

ui->Progressbar->setValue(position/1000);

Player -> setPosition(position);//如果滑块改变位置,则改变音乐进度

}

void MainWindow::fastBack(){

qint64 position=Player->position();

qDebug()<<"position"<<position;

position=position-5000;

ui->Progressbar->setValue(position/1000);

Player -> setPosition(position);//如果滑块改变位置,则改变音乐进度

}

videoplayer.h代码如下(视频播放和音乐播放差不多):

#ifndef VIDEOPLAYER_H

#define VIDEOPLAYER_H

#include <QDialog>

#include <QMediaPlayer>

#include <QVideoWidget>

#include <QMediaPlaylist>

#include <QTime>

#include <QTimer>

namespace Ui {

class VideoPlayer;

}

class VideoPlayer : public QDialog

{

Q_OBJECT

public:

explicit VideoPlayer(QWidget *parent = nullptr);

~VideoPlayer();

public slots:

void init();

void slotButtonStart();

void slotstop();

void closeEvent(QCloseEvent *);

void volumChange(int);

void positionChange(qint64 position);

void seekChange(int position); //滑动滑动条快进、倒退音乐,且音乐已播放时长也跟着变化

void videoTime();

void changestartbutton();

void button_style();

void mute();

private:

QMediaPlayer* player;

QVideoWidget* videoWidget;

QMediaPlaylist* playlist;

Ui::VideoPlayer *ui;

bool isPlay_wm=false;

bool ismute=false;

int moved;

};

#endif // VIDEOPLAYER_H

videoplayer.cpp代码如下:

#include "videoplayer.h"

#include "ui_videoplayer.h"

#include <QDebug>

#include <QFile>

#include <QCloseEvent>

VideoPlayer::VideoPlayer(QWidget *parent) :

QDialog(parent),

ui(new Ui::VideoPlayer)

{

ui->setupUi(this);

qDebug()<<"执行到此处";

connect(ui->Buttonstart,&QPushButton::clicked,this,&VideoPlayer::changestartbutton);

connect(ui->Buttonmute,&QPushButton::clicked,this,&VideoPlayer::mute);

init();

connect(ui->Buttonstart,&QPushButton::clicked,this,&VideoPlayer::slotButtonStart);

connect(ui->voiceSlider, SIGNAL(sliderMoved(int)), this, SLOT(volumChange(int)));

connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChange(qint64)));

connect(ui->timeSlider,SIGNAL(sliderMoved(int)),this,SLOT(seekChange(int)));

connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(videoTime()));

}

VideoPlayer::~VideoPlayer()

{

slotstop();

delete ui;

}

void VideoPlayer::init(){

//widget=new QWidget;

button_style();

player= new QMediaPlayer;

videoWidget=new QVideoWidget;

playlist=new QMediaPlaylist;

playlist->clear();

playlist->addMedia(QUrl::fromLocalFile("C:\\Users\\44637\\Music\\MV\\陈奕迅-我们MV.mp4"));

player->setPlaylist(playlist);

QFile file("C:\\Users\\44637\\Music\\MV\\陈奕迅-我们MV.mp4");

if(!file.open(QIODevice::ReadOnly))

qDebug() << "Could not open file";

player->setVideoOutput(videoWidget);

player->setPlaylist(playlist);

videoWidget->setAutoFillBackground(true);

QPalette qplte;

qplte.setColor(QPalette::Window, QColor(0,0,0));

videoWidget->setPalette(qplte);

ui->verticalLayout->addWidget(videoWidget);

player->play();

isPlay_wm=true;

}

void VideoPlayer::slotButtonStart(){

if(!isPlay_wm){

isPlay_wm=true;

//Player->setVolume(100);

player->play();

//musicTime();

//qApp->quit();

}

else{

isPlay_wm=false;

player->pause();

//musicTime();

}

}

void VideoPlayer::slotstop(){

player->stop();

playlist->clear();

//player->

}

void VideoPlayer::closeEvent(QCloseEvent *event){

slotstop();

event->accept();

}

void VideoPlayer::volumChange(int vol)

{

player -> setVolume(vol);

}

void VideoPlayer::positionChange(qint64 position)

{

ui->timeSlider->setMaximum(player->duration() / 1000);//设置滑块的长度范围为音乐长.00度

ui->timeSlider->setValue(position / 1000);//如果音乐进度改变,则改变滑块显示位置

moved = position;//让播放时间等于音乐进度(毫秒)

QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//设置时间

ui->currenttime ->setText(moveTime.toString("mm:ss"));//显示时间

QString t=moveTime.toString("mm:ss");

QString mm = t.mid(0,2);

QString ss = t.mid(3, 2);

int m = mm.toInt();

int s = ss.toInt();

int time = m*60*1000 + s*1000;

qDebug()<<"int"<<time;

}

void VideoPlayer::seekChange(int position)

{

player -> setPosition(position * 1000);//如果滑块改变位置,则改变音乐进度

moved = position * 1000;//让播放时间等于音乐进度(毫秒)

QTime moveTime(0,(moved/60000) % 60,(moved / 1000) % 60);//设置时间

}

void VideoPlayer::videoTime(){

qint64 time = player->duration();

QTime Time(0,(time % (1000 * 60 * 60)) / (1000 * 60),(time % (1000 * 60)) / 1000);

ui->videotime->setText(Time.toString("mm:ss"));

qDebug()<<"time:"<<Time;

}

void VideoPlayer::changestartbutton(){

if(!isPlay_wm)

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));

else

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\start.jpg"));

}

void VideoPlayer::button_style(){

ui->Buttonstart->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\pause.jpg"));

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));

}

void VideoPlayer::mute(){

if(!ismute){

player -> setVolume(0);

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\mute.png"));

ismute=true;

}

else{

player -> setVolume(100);

ui->Buttonmute->setIcon(QIcon("E:\\QT\\QTcode\\MusicPlayer\\icon\\volume.jpg"));

ismute=false;

}

}

总体运行界面如下:

一些关键方法和思路:

(1)导入歌曲:

从本地文件将歌曲名和歌曲的歌词导入,获取文件路径下所有的音乐文件和歌词文件,生成两个QStringList类型的列表。同时将歌名添加到显示歌名的组件上。同时实例化播放器和播放列表,将列表逐项加载到播放列表上,并将播放列表加载到播放器上。

(2)音乐、视频进度条:

设置滑块的长度范围为音乐长0.001倍,如果音乐进度发生改变,则同时改变滑块位置,如果滑块改变位置,则改变音乐进度。同时设置时间,让播放时间等于音乐进度(毫秒)并用Qlabel组件显示。

(3)显示歌词:(个人觉得这是个最难的点,参考了大神的思路,加上自己的思考,搞了好久才搞出来😂)

mp3歌词文件是以lrc为扩展名的文件,属于纯文本格式文件,通过解析mp3纯文本格式的歌词文件(“XXX.lrc”),实现歌词的同步显示。

LRC歌词是一种包含着“[:]”形式的“标签(tag)”、基于纯文本的歌词专用格式。

标签分为“标识标签”和“时间标签”两种,下面①~⑤为“标识标签”,⑥为“时间标签”。

①[ti:曲名]

②[ar:艺人名]

③[al:专辑名]

④[by:编者(指编辑LRC歌词的人)]

⑤[offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。用于总体调整显示的快慢。

⑥[分:秒.厘秒]歌词内容

中括号里边是歌曲内容显示时的开始时间,“:”前面为分钟,“:”后面为秒,其中“.”前面为秒,“.”后面为厘秒(一秒的百分之一);中括号外边是歌词内容。

读取对应音乐名字的歌词文件,逐行读取歌词,用QMap格式储存,不同标签开头用不同的key值储存。

获取每个标签中的时间,将时间和相对应的歌词以键值对的形式储存到QMap中。

显示歌词将当前时间以参数的形式传入,将时间对应的值读出。

本人初学QT,已经是尽力了,但还有很多做不好的地方,还有一些方法和思路之后再补充。

播放视频貌似还有点bug,界面太丑,歌词没实现滚动,只能显示当前播放到的歌词,希望大家讨论指导。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 QT实现简单音乐播放器 的全部内容, 来源链接: utcz.com/p/245316.html

回到顶部