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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 基于Qt的网络音乐播放器(四)酷狗API接口获取歌曲的搜索列表和歌曲的播放

网络播放器系列:

#include<QNetworkAccessManager>
#include<QVariant>
#include<QByteArray>
#include<QJsonParseError>
#include<QJsonDocument>
#include<QJsonObject>
#include<QJsonArray>
#include<QUrl>
#include<QPixmap>
#include<QSize>
  • ==创作不易,你们的三连是我创作的动力!==

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;

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();
    }
}

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


4.网络歌曲播放的实现

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

mainwindow.h

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

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()<<"出错";
                   }
               }
           }
       }
}

5.歌曲图片显示

mainwindow.h

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

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月前
|
网络协议
Qt中的网络编程(Tcp和Udp)运用详解以及简单示范案例
Tcp和Udp是我们学习网络编程中经常接触到的两个通讯协议,在Qt也被Qt封装成了自己的库供我们调用,对于需要进行网络交互的项目中无疑是很重要的,希望这篇文章可以帮助到大家。 是关于Qt中TCP和UDP的基本使用和特点:
170 7
Qt开发网络嗅探器02
Qt开发网络嗅探器02
|
1天前
|
存储 运维 监控
Qt开发网络嗅探器01
Qt开发网络嗅探器01
|
1天前
|
网络协议 容器
Qt开发网络嗅探器03
Qt开发网络嗅探器03
|
17天前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API三种搭建神经网络的方式及以mnist举例实现
使用Keras API构建神经网络的三种方法:使用Sequential模型、使用函数式API以及通过继承Model类来自定义模型,并提供了基于MNIST数据集的示例代码。
30 12
|
17天前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API两种训练GAN网络的方式
使用Keras API以两种不同方式训练条件生成对抗网络(CGAN)的示例代码:一种是使用train_on_batch方法,另一种是使用tf.GradientTape进行自定义训练循环。
20 5
|
1月前
|
机器学习/深度学习 TensorFlow API
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
|
1月前
|
机器学习/深度学习 人工智能 计算机视觉
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
好的资源-----打卡机+Arm+Qt+OpenCV嵌入式项目-基于人脸识别的考勤系统-----B站神经网络与深度学习,商城
|
3月前
|
编解码 前端开发 Java
Java网络API之Netty深度解析
Java网络API之Netty深度解析
31 0
|
3月前
|
存储 安全 API
网络安全与信息安全:防御前线的关键技术深入理解RESTful API设计原则与实践
【5月更文挑战第30天】在数字化时代,网络安全和信息安全已成为维系信息社会运行的核心支柱。本文深入探讨了网络安全漏洞的概念、加密技术的进展以及提升安全意识的重要性。通过对这些领域的分析,旨在为读者提供一个关于如何保护个人和组织资产免遭网络威胁的综合性视角。 【5月更文挑战第30天】 在现代Web服务开发领域,表述性状态传递(REST)已成为构建后端API的一种流行且成熟的架构风格。本文将探讨RESTful API的核心设计原则,并通过实例分析如何将这些原则应用于实际开发中。我们将重点讨论资源的概念化、HTTP方法的正确使用、状态码的准确传达以及API的可扩展性和版本控制问题。通过本文,读者将

推荐镜像

更多