基于Qt的网络音乐播放器(四)酷狗API接口获取歌曲的搜索列表和歌曲的播放

举报
花狗Fdog 发表于 2021/03/26 00:52:32 2021/03/26
【摘要】 2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票! 我的投票地址:点击为我投票 文章目录 1.效果图2.准备好前面获取的酷狗api接口3.网络歌曲搜索实现4.网络歌曲播放的实现5.歌曲图片显示 网络播放器系列: qt 布局和样式表基于Qt的音乐播放器(一)添加音频文件,播放音乐,更新进度条基于Qt的音乐播放器(二)切换歌曲,调...

2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票!
我的投票地址:点击为我投票
在这里插入图片描述



网络播放器系列:

#include<QNetworkAccessManager>
#include<QVariant>
#include<QByteArray>
#include<QJsonParseError>
#include<QJsonDocument>
#include<QJsonObject>
#include<QJsonArray>
#include<QUrl>
#include<QPixmap>
#include<QSize>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 创作不易,你们的三连是我创作的动力!

1.效果图

老规矩,空口无凭,先上动态图,抓住你们的胃。
在这里插入图片描述
请忽视一些小细节,小BUG,后期会慢慢修复,嘿嘿!


2.准备好前面获取的酷狗api接口

第一个是搜索接口:
http://mobilecdn.kugou.com/api/v3/search/song?format=json&keyword=你需要填的&page=你需要填的&pagesize=你需要填的

  • keyword:搜索的内容。
  • page:搜索的页数
  • pagesize:返回的数据量,填10就是返回1首歌曲的数据。
  • 第一目标个是通过该接口,实现歌曲搜索,第二个目标是通过该接口获取特定歌曲的hash和album_id的值用于下面歌曲的播放,文字图片以及歌词(下一篇讲)的显示

第二个是歌曲详细接口:
http://www.kugou.com/yy/index.php?r=play/getdata""&hash=你需要填的&album_id=你需要填的&_=1497972864535

  • hash和album_id都是第一个接口返回json解析出来的。
  • 通过该接口,我们可以得到歌曲播放地址,图片地址,歌词等等

3.网络歌曲搜索实现

别忘了添加#include<QNetworkAccessManager> 和 #include<QNetworkReply>两个头文件

mainwindow.h

//添加类成员 QNetworkAccessManager * network_manager; QNetworkRequest * network_request;

  
 
  • 1
  • 2
  • 3

mainwindow.cpp

//构造函数中进行信号和槽的链接
//connect 有不同的写法,replyFinished也就是replyFinished()。
network_manager = new QNetworkAccessManager();
network_request = new QNetworkRequest();
connect(network_manager, &QNetworkAccessManager::finished, this, &MainWindow::replyFinished);

//点击搜索按钮调用该函数,参数为搜索框内容
void MainWindow::search(QString str)
{ QString KGAPISTR1 = QString("http://mobilecdn.kugou.com/api/v3/search/song?format=json" "&keyword=%1&page=1&pagesize=18").arg(str); network_request->setUrl(QUrl(KGAPISTR1)); network_manager->get(*network_request);
}
//为了简化代码,只使用参数keyword

//槽函数
void MainWindow::replyFinished(QNetworkReply *reply)
{ //获取响应的信息,状态码为200表示正常 QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); //无错误返回 if(reply->error() == QNetworkReply::NoError) { QByteArray bytes = reply->readAll();  //获取字节 QString result(bytes);  //转化为字符串 qDebug()<<result; parseJson(result);//该函数用于解析api接口返回的json } else { //处理错误 qDebug()<<"搜索失败"; }
}

void MainWindow::parseJson(QString json)
{ QString songname_original; //歌曲名 QString singername; //歌手 QString hashStr; //hash QString album_name; //专辑 int duration; //时间 QByteArray byte_array; QJsonParseError json_error; QJsonDocument parse_doucment = QJsonDocument::fromJson(byte_array.append(json), &json_error); if (json_error.error == QJsonParseError::NoError) { if (parse_doucment.isObject()) { QJsonObject rootObj = parse_doucment.object(); if (rootObj.contains("data")) { QJsonValue valuedata = rootObj.value("data"); if (valuedata.isObject()) { QJsonObject valuedataObject = valuedata.toObject(); if (valuedataObject.contains("info")) { QJsonValue valueArray = valuedataObject.value("info"); if (valueArray.isArray()) { QJsonArray array = valueArray.toArray(); int size = array.size(); for (int i = 0; i < size; i++) { QJsonValue value = array.at(i); if (value.isObject()) { QJsonObject object = value.toObject(); if (object.contains("songname_original"))//歌曲名 { QJsonValue AlbumID_value = object.take("songname_original"); if (AlbumID_value.isString()) { songname_original = AlbumID_value.toString(); } } if (object.contains("singername"))//歌手 { QJsonValue AlbumID_value = object.take("singername"); if (AlbumID_value.isString()) { singername = AlbumID_value.toString(); } } if (object.contains("album_name"))//专辑 { QJsonValue AlbumID_value = object.take("album_name"); if (AlbumID_value.isString()) { album_name = AlbumID_value.toString(); } } if (object.contains("hash")) //hash { QJsonValue FileHash_value = object.take("hash"); if (FileHash_value.isString()) { hashStr = FileHash_value.toString(); //用Vector保存每首歌曲的hash m_Vectorlist.append(FileHash_value.toString()); } } if (object.contains("album_id")) { QJsonValue FileHash_value = object.take("album_id"); if (FileHash_value.isString()) { //用Vector保存每首歌曲的album_id m_ID.append(FileHash_value.toString()); } } if (object.contains("duration"))//时长 { QJsonValue AlbumID_value = object.take("duration").toInt(); duration = AlbumID_value.toInt(); } //将解析出的内容放到列表中 ui->tableWidget->setItem(i,0,new QTableWidgetItem(songname_original)); //文字居中 ui->tableWidget->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); ui->tableWidget->setItem(i,1,new QTableWidgetItem(singername)); ui->tableWidget->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); ui->tableWidget->setItem(i,2,new QTableWidgetItem(album_name)); ui->tableWidget->item(i,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); QString time = QString("%1:%2").arg(duration/60).arg(duration%60); ui->tableWidget->setItem(i,4,new QTableWidgetItem(time)); ui->tableWidget->item(i,4)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); } } } } } } } } else { qDebug() << json_error.errorString(); }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144

如果有一天,这个代码不能用了,要注意查询的值对不对,酷狗可能是为了防止被爬,data,info,等等这些值有可能被更换成别的,要观察json。


4.网络歌曲播放的实现

当搜索列表有了内容,我们希望双击播放音乐,所以我们的第二个接口通过双击信号调用。

mainwindow.h

//类成员添加 QNetworkAccessManager * network_manager2; QNetworkRequest * network_request2;

  
 
  • 1
  • 2
  • 3

mainwindow.cpp

//构造函数中添加 network_manager2 = new QNetworkAccessManager(); network_request2 = new QNetworkRequest(); connect(network_manager2, &QNetworkAccessManager::finished, this, &MainWindow::replyFinished2);

void MainWindow::on_tableWidget_cellDoubleClicked(int row, int column)
{ //歌曲请求 row 是行号 QString KGAPISTR1 =QString("http://www.kugou.com/yy/index.php?r=play/getdata" "&hash=%1&album_id=%2&_=1497972864535").arg(m_Vectorlist.at(row)).arg(m_ID.at(row)); network_request2->setUrl(QUrl(KGAPISTR1)); //这句话很重要,我们手动复制url放到浏览器可以获取json,但是通过代码不行,必须加上下面这句才可以 network_request2->setRawHeader("Cookie","kg_mid=2333"); network_request2->setHeader(QNetworkRequest::CookieHeader, 2333); network_manager2->get(*network_request2);
}

void MainWindow::replyFinished2(QNetworkReply *reply)
{ //获取响应的信息,状态码为200表示正常 QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); //无错误返回 if(reply->error() == QNetworkReply::NoError) { QByteArray bytes = reply->readAll();  //获取字节 QString result(bytes);  //转化为字符串 parseJsonSongInfo(result);//解析json } else { //处理错误 qDebug()<<"歌曲播放失败"; }
}


void MainWindow::parseJsonSongInfo(QString json)
{ QString audio_name;//歌手-歌名 QString play_url;//播放地址 QString img; QByteArray byte_array; QJsonParseError json_error; QJsonDocument parse_doucment = QJsonDocument::fromJson(byte_array.append(json), &json_error); if(json_error.error == QJsonParseError::NoError) { if(parse_doucment.isObject()) { QJsonObject rootObj = parse_doucment.object(); if(rootObj.contains("data")) { QJsonValue valuedata = rootObj.value("data"); if(valuedata.isObject()) { QJsonObject valuedataObject = valuedata.toObject(); QString play_urlStr(""); if(valuedataObject.contains("play_url")) { QJsonValue play_url_value = valuedataObject.take("play_url"); if(play_url_value.isString()) { play_urlStr = play_url_value.toString(); //歌曲的url if(play_urlStr!="") { qDebug()<<play_urlStr; player->setMedia(QUrl(play_urlStr)); player->setVolume(50); player->play(); } } } if(valuedataObject.contains("audio_name")) { QJsonValue play_name_value = valuedataObject.take("audio_name"); if(play_name_value.isString()) { QString audio_name = play_name_value.toString(); //歌曲名字 if(audio_name!="") { //显示 qDebug()<<audio_name; ui->label_2->setText(audio_name); } } } //下一篇的歌词获取也是在这里添加代码 //图片显示代码在这里添加 } else { qDebug()<<"出错"; } } } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

5.歌曲图片显示

mainwindow.h

//类成员添加 QNetworkAccessManager * network_manager3; QNetworkRequest * network_request3;

  
 
  • 1
  • 2
  • 3

mainwindow.cpp

 network_manager3 = new QNetworkAccessManager(); network_request3 = new QNetworkRequest(); connect(network_manager3, &QNetworkAccessManager::finished,this, &MainWindow::replyFinished3);


//这段代码添加到上面的图片显示位置即可
if (valuedataObject.contains("img"))
{
	QJsonValue play_name_value = valuedataObject.take("img");
	if (play_name_value.isString())
	{
		QString audio_name = play_name_value.toString(); if (audio_name != "")
		{ m_Jpg.append(audio_name); network_request3->setUrl(QUrl(audio_name)); network_manager3->get(*network_request3);
		}
	}
}

void MainWindow::replyFinished3(QNetworkReply *reply)
{ //获取响应的信息,状态码为200表示正常 QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); //无错误返回 if(reply->error() == QNetworkReply::NoError) { QByteArray bytes = reply->readAll();  //获取字节 //由于获取的图片像素过大,而我们显示的图片很小,所以我们需要压缩图片的像素,我们label的大小为45*45,所以我们把图片压缩为45*45 QPixmap pixmap; QSize picSize(45,45); pixmap.loadFromData(bytes); //pixmap.save("url"); 也可以现在图片 ui->label_10->setPixmap(pixmap.scaled(picSize)); } else { //处理错误 qDebug()<<"处理错误3"; }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

上述代码还有很大的优化空间,代码重复性过大,有时间的话进行优化一波,这篇就到这里,下篇歌词的显示,不见不散。

文章来源: blog.csdn.net,作者:花狗Fdog,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Fdog_/article/details/107992205

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。