Qt C++版 网易云音乐 API NetEaseCloudMusicAPI
QCloudMusicApi API 由以下组件组成:
module.h
: 封装了NeteaseCloudMusicApi
类,实现了所有的API方法apihelper.h
: 封装了ApiHelper
类,将所有API接口的调用都封装在了一个方法中,支持设置全局的Cookie与网络代理api_c.h
: 提供C语言接口,实现对ApiHelper
类的跨语言调用的支持plugins.h
: Plugins
插件类,供NeteaseCloudMusicApi
类调用util/request.h
: Request
网络接口类,通过事件循环实现同步调用网络接口util/crypto.h
: 通过调用openssl实现API底层的加解密功能,支持rsa、aes的加解密等util/index.h
: Index
类,封装了一些通用的方法util/logger.h
: 管理QCloudMusicApi的日志输出NeteaseCloudMusicApi
类和ApiHelper
类中的所有方法均通过Q_INVOKABLE
宏注册到Qt元对象系统中,支持反射调用
module.h
、apihelper.h
和api_c.h
为外部调用,其他类均为内部调用
module.h
封装了NeteaseCloudMusicApi
类,参考Node.js项目的module
目录,实现了所有API方法。
继承了QObject
类并声明了Q_OBJECT
宏,用于实现Qt的反射调用
class QCLOUDMUSICAPI_EXPORT NeteaseCloudMusicApi : public QObject {
Q_OBJECT
public:
explicit NeteaseCloudMusicApi(QObject* parent = nullptr);
// 声明所有方法
}
类中所有方法均以Q_INVOKABLE QVariantMap 方法名(QVariantMap)
的格式定义;Q_INVOKABLE
用于将方法注册到Qt元对象系统中,函数的入参和返回值均为QVariantMap
类型
// 歌手全部歌曲
Q_INVOKABLE QVariantMap artist_songs(QVariantMap);
调用方式:
NeteaseCloudMusicApi api;
qDebug() << api.artist_songs({
{ "id", "1408586353" },
{ "offset", 0 },
{ "limit", 100 }
});
apihelper.h
封装了ApiHelper
类,通过反射机制将所有API接口的调用都封装在了一个方法中,支持设置全局的Cookie与网络代理,实现对Cookie的管理;所有方法均使用Q_INVOKABLE
声明
/**
* @brief 调用API的成员函数
* @param member 成员函数名
* @param arg 调用参数
* @return QVariantMap 返回调用结果
*/
Q_INVOKABLE QVariantMap invoke(QString member, QVariantMap arg);
使用Qt的元对象系统对NeteaseCloudMusicApi
类的API接口反射调用,若找不到对应的方法,则返回一个空的QVariantMap
调用invoke
方法时,若参数中传有Cookie
,则将其保存下来,下一次调用无需传入Cookie
当调用登录等接口返回值中有Cookie
,也将其保存下来,存放于内存中
QVariantMap ret;
QMetaObject::invokeMethod(this, member.toUtf8(),
Qt::DirectConnection,
Q_RETURN_ARG(QVariantMap, ret),
Q_ARG(QVariantMap, arg));
return ret;
调用方式:
ApiHelper helper;
qDebug() << helper.invoke("artist_songs",
{
{ "id", "1408586353" },
{ "offset", 0 },
{ "limit", 100 }
});
api_c.h
提供C语言接口,实现对ApiHelper
类跨语言调用的支持,所有方法用extern "C"
包裹,声明为C语言函数,传入参数均为C语言类型
/**
* @brief 通过反射调用API的成员函数
* @param memberName 调用的函数的名称
* @param value 函数参数的JSON格式字符
* @return 调用结果的JSON格式字符串
*/
QCLOUDMUSICAPI_EXPORT const char* invoke(char* memberName, char* value);
调用前创建一个QCoreApplication
单例,提供事件循环支持,否则无法同步接收网络请求
auto currentPath = QDir::currentPath().toStdString();
// 创建一个QCoreApplication单例,用于支持事件循环QEventLoop
if (!QCoreApplication::instance()) {
int argc = 1;
char* argv[1]{ (char*)currentPath.c_str() };
app = new QCoreApplication(argc, argv);
}
调用方式参考跨语言调用