一、界面效果
功能:
搜索歌曲:
客户端用户输入歌曲名,点击显示歌曲信息,服务器根据客户端发送来的名字在歌曲表内查询查询到的话,则将对应的歌曲文件数据发送到客户端新创建的一个文件夹内,然后加入到多媒体播放。(最后关闭窗口会直接删除此文件夹)
添加歌单:
客户端用户觉得搜索到的此首歌曲可以,可将该歌曲添加到服务器端自己的歌单表内。
下载歌曲:
客户可根据搜索到的此首歌曲,将此歌曲下载到客户端内选择的文件夹内。
歌曲选择:
客户可选择自己的本地下载过的歌曲加入列表播放。
显示歌单:
客户端用户调用服务器数据库内自己的表,将表内歌单显示在客户端列表内。
播放选择:
通过歌曲选择在列表内的歌单
正常的播放/暂停,上下歌切换,进度条的调节,单曲/顺序/随机播放等
(注:歌曲列表显示的是服务器发送过来的数据 上下歌切换关闭)
部分代码:
音乐播放器界面:
#include "musicwin.h"
#include "ui_musicwin.h"
#include <QFileDialog>
#include <QTime>
#include <QTimer>
#include <QFileInfo>
#include <QDebug>
#include <QByteArray>
#include <network.h>
#include <QMessageBox>
#include <QtEndian>
#include <QtGlobal>
#include <winsock2.h>
#include<QTextCodec> //引入
#include <QPainter>
musicwin::musicwin(QWidget *parent) :
QWidget(parent),
ui(new Ui::musicwin)
{
this->dirName = "C:\\Users\\Administrator\\Desktop\\QT_Project\\day4_musicWork\\TemporaryMusic";
this->times = 0;
this->j = 0;
this->flag = 0;
this->size = 0;
this->all = 0;
this->dirName = nullptr;
this->file = NULL;
this->row = 0;
ui->setupUi(this);
this->Icount = 0;
this->n = 0;
this->mediaPlayer = new QMediaPlayer(this);
this->music = new QByteArray;
this->music->clear();
this->exist = -1;
ui->label->setText("00:00/00:00");
//设置播放/暂停的图标
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPlay));
//设置上一曲和下一曲的图标
this->ui->pushButton_last->setIcon(this->style()->standardIcon(QStyle::SP_MediaSeekBackward));
this->ui->pushButton_next->setIcon(this->style()->standardIcon(QStyle::SP_MediaSeekForward));
//设置按钮图标
this->ui->searchBtn->setIcon(QIcon(":/image/搜索.png"));
this->ui->downloadBtn->setIcon(QIcon(":/image/下载.png"));
this->ui->showBtn->setIcon(QIcon(":/image/查看.png"));
this->ui->collectBtn->setIcon(QIcon(":/image/收藏.png"));
this->ui->pushButton_choose->setIcon(QIcon(":/image/选择.png"));
this->ui->pushButton->setIcon(QIcon(":/image/刷新.png"));
//设置音量调节进度条的取值范围和初始值
this->ui->volumeSlider->setRange(0, 100);
this->ui->volumeSlider->setValue(30);
this->timer = new QTimer(this);
//设置编辑框后虚内容显示
this->ui->searchEdit->setPlaceholderText("歌曲搜索");
//绘制背景图
QPalette pal = this->palette();
pal.setBrush(QPalette::Background, QBrush(QPixmap(":/image/音乐.jpg")));
setPalette(pal);
//滚动显示歌曲名称
connect(this->timer, SIGNAL(timeout()), this, SLOT(showMusicName()));
//根据位置的变化来设置进度条的位置
connect(this->mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(updatePlaySlider(qint64)));
//根据时长的变化来获取播放的总时长设置给进度条的范围
connect(this->mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(setPlaySliderRange(qint64)));
}
musicwin::~musicwin()
{
delete ui;
}
void musicwin::on_pushButton_choose_clicked()
{
//清空编辑框
this->ui->searchEdit->clear();
//如果选择本地歌曲设置上下切换为可按状态
this->ui->pushButton_last->setEnabled(true);
this->ui->pushButton_next->setEnabled(true);
this->ui->listWidget->clear();
//打开文件选择歌曲 获取歌曲路径加入列表
this->fileList = QFileDialog::getOpenFileNames(this, "选择", ".", "MP3(*.MP3)");
//默认选择的歌曲从第一首开始 获取路径
this->musicPath = fileList.at(0);
//获取根据路径获取名称
QFileInfo fileInfo(musicPath);
//显示第一首的歌曲信息 转换获取歌曲名
this->musicName = fileInfo.fileName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//将选中的歌曲添加列表框内
int i;
for (i = 0; i < this->fileList.size(); i++)
{
QFileInfo fileInfo(this->fileList.at(i));
this->ui->listWidget->addItem(fileInfo.baseName());
}
//将第一首歌曲加入播放器中
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//显示正在播放的歌曲
this->ui->listWidget->setCurrentRow(0);
//开始播放第一首音乐
this->mediaPlayer->play();
//启动定时器让歌曲名称进行滚动显示
this->timer->start(1000);
//播放开始的时候将播放的按钮由播放设置为暂停
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
}
//滚动显示选中的歌曲名称
void musicwin::showMusicName()
{
this->n++;
if (this->n == this->name.size())
{
this->n = 0;
}
this->ui->label_2->setText(this->name.mid(this->n));
//显示总时长--毫秒
qint64 dur = this->mediaPlayer->duration();
//显示当前播放时长--毫秒
qint64 pos = this->mediaPlayer->position();
//实例化时间对象 动态显示时间
QTime time1(0, 0, 0), time2(0, 0, 0);
this->ui->label->setText(time1.addMSecs(int(pos)).toString("mm:ss") + "/"
+ time2.addMSecs(int(dur)).toString("mm:ss"));
//判断歌曲是否播放完成
if (dur == pos)
{
if ("顺序播放" == ui->comboBox->currentText())
{
this->n = ui->listWidget->currentRow();
if (n == this->fileList.size() - 1)
{
//再次从0开始
n = -1;
}
//按照顺序执行列表框内的歌单
this->musicPath = this->fileList.at(n + 1);
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//列表显示到歌曲名称
this->ui->listWidget->setCurrentRow(n + 1);
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.fileName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
}
else if ("循环播放" == ui->comboBox->currentText())
{
//循环播放 stop让这个播放器停止再次打开 从头开始 不改变其内容
this->mediaPlayer->stop();
this->mediaPlayer->play();
}
else if ("随机播放" == ui->comboBox->currentText())
{
//使用随机函数获取随机值
int num = qrand() % (this->fileList.size() - 1);
this->musicPath = this->fileList.at(num);
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//列表显示到歌曲名称
this->ui->listWidget->setCurrentRow(num);
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.fileName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
}
}
}
//修改播放进度条
void musicwin::updatePlaySlider(qint64 position)
{
//根据歌曲的修改位置设置播放进度条的位置
this->ui->viewSlider->setValue(int(position));
}
void musicwin::setPlaySliderRange(qint64 duration)
{
//根据选中歌曲的总范围设置播放进度条的设置
this->ui->viewSlider->setRange(0, int(duration));
}
void musicwin::on_pushButton_play_clicked()
{
//获取当前播放音乐的状态
int state = this->mediaPlayer->state();
//如果当前为播放状态
if (state == QMediaPlayer::PlayingState)
{
//设置播放器为暂停态
this->mediaPlayer->pause();
//修改按钮显示为暂停
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPlay));
}
//如果当前为暂停态
else if (state == QMediaPlayer::PausedState)
{
//设置为播放器播放态
this->mediaPlayer->play();
//修改按钮显示为播放
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
}
}
//根据播放进度滑块的位置来设置歌曲播放的位置
void musicwin::on_viewSlider_sliderMoved(int position)
{
this->mediaPlayer->setPosition(position);
}
//根据音量滑块的位置来设置歌曲播放的音量
void musicwin::on_volumeSlider_sliderMoved(int position)
{
this->mediaPlayer->setVolume(position);
}
//上一首
void musicwin::on_pushButton_last_clicked()
{
int pos = this->ui->listWidget->currentRow();
if (0 == pos)
{
//如果是第一首点击上一首则跳到最后一首
pos = this->fileList.size();
}
//获取上一首的路径 也就是当前的减一 列表内的上一个
this->musicPath = this->fileList.at(pos - 1);
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//列表显示到上一首歌曲名称
this->ui->listWidget->setCurrentRow(pos - 1);
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.baseName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
}
void musicwin::on_pushButton_next_clicked()
{
int pos = this->ui->listWidget->currentRow();
if (pos == this->fileList.size() - 1)
{
//如果是最后一首点击下一首则跳到第一首
pos = -1;
}
//获取下一首的路径 也就是当前的加一 列表内的下一个
this->musicPath = this->fileList.at(pos + 1);
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//列表显示到下一首歌曲名称
this->ui->listWidget->setCurrentRow(pos + 1);
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.baseName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
}
//双击列表框内切换歌曲
void musicwin::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
//获取当前列表内对应的第几行
int pos = this->ui->listWidget->currentRow();
//获取当前歌曲的路径
this->musicPath = this->fileList.at(pos);
qDebug() << pos;
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.baseName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
}
//搜索歌曲
void musicwin::on_searchBtn_clicked()
{
ui->label->setText("00:00/00:00");
this->name = " ";
this->timer->stop();
this->ui->listWidget->clear();
//如果有音乐正在播放 一切内容清空
//路径清空
this->musicPath.clear();
this->mediaPlayer->stop();
QMessageBox::information(this, "提示框", "抱歉用户系统不够完善,请于最少10s后点击刷新进行歌曲播放");
//获取套接字
NetWork *w = NetWork::getNet();
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(showMyMusic()));
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(ensureCollect()));
//读完缓存区内容
QString recv = w->socket->readAll();
//获取编辑框内容
char str[100] = {'\0'};
QByteArray data = this->ui->searchEdit->text().toUtf8();
sprintf(str, "Search#%s", data.data());
connect(w->socket, SIGNAL(readyRead()), this, SLOT(readData()));
//将数据发送过去
w->socket->write(str);
}
void musicwin::readData()
{
NetWork *w = NetWork::getNet();
if (this->j == 0) //获取到歌曲名称
{
QByteArray data = w->socket->read(50);
this->row = QString(data).toInt();
if (this->row > 0)
{
this->row = 0;
//创建临时文件夹
setDir();
//UTF-8 GBK类型转换
this->musicPath = this->dirName + "/" + this->ui->searchEdit->text() + ".mp3";
QTextCodec *code = QTextCodec::codecForName("GB2312");
std::string name = code->fromUnicode(this->musicPath).data();
qDebug() << this->musicPath;
FILE *file = fopen(name.c_str(), "wb+");
if (file == NULL)
{
qDebug() << "打开文件失败";
return;
}
this->file = file;
this->ui->listWidget->clear();
this->ui->listWidget->addItem(this->ui->searchEdit->text());
this-> j = 1;
}
else if (this->row == 0)
{
QMessageBox::information(this, "提示框", "抱歉用户,该歌曲不存在");
this->ui->searchEdit->clear();
this->ui->listWidget->clear();
//断掉连接 为了下次连接正确
NetWork *w = NetWork::getNet();
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(readData()));
this->j = 0;
}
}
else if (this->j == 1) //获取文件大小
{
qDebug() << "文件大小";
QByteArray recv = w->socket->readAll();// 大小
QString str = QString(recv);
//得到了音乐文件的大小
this->size = str.split("#").at(1).toInt();
qDebug() << this->size;
this->j = 2;
}
else if (this->j == 2)
{
//读前4字节获取读多少数据
QByteArray recv = w->socket->read(4);
u_long count = 0;
memcpy(&count, recv.data(), 4);
count = ntohl(count);
this->Icount = count;
//读后4字节获取读到的第几个包
QByteArray bag = w->socket->read(4);
u_long many = 0;
memcpy(&many, bag.data(), 4);
many = ntohl(many);
//读8个字节后的数据
QByteArray data = w->socket->read(count);
this->music->append(data);
this->all = this->all + count;
qDebug() << QString::number(this->all) + "/" + QString::number(this->size);
fwrite(data.toStdString().c_str(), count, 1, file);
}
}
void musicwin::setDir()
{
QFileInfo info("./day4_musicWork.exe");
QString absolutePath = info.absolutePath();
//创建临时文件夹
this->dirName = absolutePath + "/" + "TemporaryMusic";
QDir dir(dirName);
if (!dir.exists())
{
dir.mkdir(dirName);
qDebug() << "文件夹创建成功";
}
}
//刷新读数据
void musicwin::on_pushButton_clicked()
{
while (1)
{
readData();
if (this->Icount != 1000)
{
qDebug() << this->musicPath;
fclose(file);
this->file = NULL;
this->j = 0;
this->all = 0;
//断开信号
NetWork *w = NetWork::getNet();
QByteArray rec = w->socket->readAll();
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(readData()));
break;
}
}
QMessageBox::information(this, "提示框", "歌曲开始播放");
//此时歌曲播放
//播放音乐
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//滚动显示歌曲名称
QFileInfo fileInfo(this->musicPath);
this->musicName = fileInfo.baseName();
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
//播放开始的时候将播放的按钮由播放设置为暂停
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
//设置上下首为不可按状态
this->ui->pushButton_last->setEnabled(false);
this->ui->pushButton_next->setEnabled(false);
return;
}
//重新关闭函数
void musicwin::closeEvent(QCloseEvent *e)
{
int ret = QMessageBox::question(this, "提示框", "是否确认退出");
if (ret != QMessageBox::Yes)
{
e->ignore();
return;
}
DelDir(this->dirName);
exit(0);
}
//删除临时文件夹
bool musicwin::DelDir(const QString &path)
{
if (path.isEmpty())
{
return false;
}
QDir dir(path);
if (!dir.exists())
{
return true;
}
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); //设置过滤
QFileInfoList fileList = dir.entryInfoList(); // 获取所有的文件信息
foreach (QFileInfo file, fileList) //遍历文件信息
{
if (file.isFile()) // 是文件,删除
{
file.dir().remove(file.fileName());
}
else // 递归删除
{
DelDir(file.absoluteFilePath());
}
}
qDebug() << "删除临时文件夹成功";
return dir.rmdir(dir.absolutePath()); // 删除文件夹
}
//下载文件
void musicwin::on_downloadBtn_clicked()
{
NetWork *w = NetWork::getNet();
QByteArray rec = w->socket->readAll();
//下载前把多媒体关闭
this->mediaPlayer->stop();
QString filePath;
//获取保存到的地址
filePath = QFileDialog::getSaveFileName(this, "歌曲下载到", ".", "MP3(*.mp3)");
if (filePath.isNull() == true)
{
return;
}
else
{
QTextCodec *code = QTextCodec::codecForName("GB2312");
std::string name = code->fromUnicode(filePath).data();
FILE *saveFile = fopen(name.c_str(), "ab+");
if (saveFile != NULL)
{
//UTF-8 GBK类型转换
this->musicPath = this->dirName + "/" + this->ui->searchEdit->text() + ".mp3";
QTextCodec *code = QTextCodec::codecForName("GB2312");
std::string musicName = code->fromUnicode(this->musicPath).data();
FILE *musicFile = fopen(musicName.c_str(), "rb");
if (musicFile == NULL)
{
qDebug() << "打开文件失败";
return;
}
fseek(musicFile, 0, SEEK_SET);
char buf[1000] = {'\0'};
while (!feof(musicFile))
{
memset(buf, '\0', sizeof(buf));
fread(buf, 1, sizeof(buf), musicFile);
fwrite(buf, 1, sizeof(buf), saveFile);
}
fclose(musicFile);
}
fclose(saveFile);
}
this->ui->searchEdit->clear();
this->ui->listWidget->clear();
QMessageBox::information(this, "提示框", "开始播放下载好的歌曲");
//此时歌曲播放
//播放音乐
this->mediaPlayer->setMedia(QUrl(filePath));
//将第一首歌曲加入播放器中
this->mediaPlayer->setMedia(QUrl(this->musicPath));
//滚动显示歌曲名称
QFileInfo fileInfo(filePath);
this->musicName = fileInfo.baseName();
//加入列表显示
this->ui->listWidget->addItem(this->musicName);
//显示正在播放的歌曲
this->ui->listWidget->setCurrentRow(0);
this->name = this->musicName + " ";
this->ui->label_2->setText(this->name);
//开始播放
this->mediaPlayer->play();
this->timer->start(1000);
//播放开始的时候将播放的按钮由播放设置为暂停
this->ui->pushButton_play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPause));
}
//将这个歌曲收藏到歌单里
void musicwin::on_collectBtn_clicked()
{
//断开连接
NetWork *w = NetWork::getNet();
//拼接字符串
char str[100] = {'\0'};
QByteArray musicName = this->ui->searchEdit->text().toUtf8();
sprintf(str, "Collect#%s", musicName.data());
qDebug() << str;
//有写数据的时候,会发射一个readyRead的信号
connect(w->socket, SIGNAL(readyRead()), this, SLOT(ensureCollect()));
//发送信息
w->socket->write(str);
}
//确保是否加入收藏歌单内
void musicwin::ensureCollect()
{
NetWork *w = NetWork::getNet();
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(showMyMusic()));
QByteArray str = w->socket->read(50);
if (QString(str) == "1")
{
QMessageBox::information(this, "提示框", "收藏歌曲成功");
}
else
{
QMessageBox::warning(this, "提示框", "收藏歌曲失败");
}
//用完之后断开连接
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(ensureCollect()));
}
//显示该用户的歌单
void musicwin::on_showBtn_clicked()
{
//显示列表前清空列表框
this->ui->listWidget->clear();
NetWork *w = NetWork::getNet();
//拼接字符串
char str[100] = {'\0'};
strcpy(str, "Show");
qDebug() << str;
//有写数据的时候,会发射一个readyRead的信号
connect(w->socket, SIGNAL(readyRead()), this, SLOT(showMyMusic()));
//发送信息
w->socket->write(str);
}
//从服务器接收自己的歌单显示在列表框内
void musicwin::showMyMusic()
{
NetWork *w = NetWork::getNet();
if (this->times == 0) // 判断第一次歌单是否存在
{
QByteArray str = w->socket->read(50);
this->exist = QString(str).toInt();
this->times = 1;
}
else if (this->exist == 0 && this->times == 1) // 第二次如果有数据接收数据
{
QByteArray recv = w->socket->readAll();
QString str = QString(recv);
//得到了发送来的歌单的数量
int number = str.split("#").at(1).toInt();
//第三个开始为歌曲名字 i从2开始 所以循环歌曲数量number+2次
for (int i = 2; i <= (number + 2); i++)
{
this->ui->listWidget->addItem(str.split("#").at(i));
}
this->times = 0;
disconnect(w->socket, SIGNAL(readyRead()), this, SLOT(showMyMusic()));
}
else if (this->exist == 1)
{
QMessageBox::warning(this, "提示框", "您尚未收藏任何歌曲");
}
}
版权声明:本文为m0_73859283原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。