思路: Qt中提供了音视频播放的类,类中提供了很多播放类的接口供我们调用,基本可以实现一个完整播放器的所有功能,由于想要实现的是支持在线搜索和播放的,所以要先解决音频的来源,再进行ui界面的设计,最后将背后的功能实现。
一,调用网易云API
如果想自己写服务器作为音乐播放的来源的话比较难实现,所以就调用网易云音乐的API,用特定的请求数据格式获得数据后进行解析后就可以得到音乐的 Url 格式,再通过Qt提供的在线播放类播放即可。
网易云音乐提供了这样一个 API 用于公共请求使用: https://music.cyrilstudio.top
成功进入后我们点击查看文档
点击开始使用:
点击使用指南可以查看该API提供了哪些基本功能,并提供了不同的功能调用的方法
以搜索歌曲为例,请求资源的格式为 :https://music.cyrilstudio.top/search?keywords=歌曲名称
我们先以他提供的例子将 Url 进行验证,如果得到如下的格式说明正确
这是对方服务器接收你的请求后返回的 json 格式的文本,使用 http://json.cn 进行翻译,查看是否包含所需要的信息,我们将 json 格式的文本全部复制到这个网页中进行解析,得到如下信息
id 是音乐ID ,可以唯一标识一首音乐,其他的还有歌曲名,歌手名,歌曲时长等信息都在里面,需要将其解析出来。
二,使用Qt中的 QNetworkAccessManager 类发送和接收数据
QNetworkAccessManager 也被称为网络大管家类,是因为所有和网络相关的接口都是围绕QNetworkAccessManager创造出来的对象,并且一个应用程序只要有一个QNetworkAccessManager对象即可。该类控制着应用程序发送请求和接受回复。该类也承载着一切公共的配置以及所发请求的设置,还包含了代理配置、缓存配置、以及相对应的各种信号,reply(应答)信号可以用来监视网络活动。所以我们可以通过这一个对象完成信息的收发。具体实现如下:
QNetworkAccessManager* http_acc = new QNetworkAccessManager; //定义并实例化一个网络管家
QString str;
str=QString("https://music.cyrilstudio.top/search?keywords=海阔天空"); //将请求格式作为字符串保存
QNetworkRequest request; //定义一个请求对象
request.setUrl(QString(str)); //将请求格式设置给请求对象
http_acc->get(request); //请求
这样对方的服务器就会接收到正确的请求,之后便会将你所请求的内容以 json 格式发送过来,先通过接收函数接收对方发送的 json 文本后再进行解析。
当然Qt 也提供了接收信息的类 QNetworkReply ,通过定义一个接收对象,将内容全部读取出来
QNetworkReply* r; //定义一个接收信息对象
QByteArray searchInfo= r->readAll(); //全部读取
三,解析json文本
1,先将收到的信息提取后转换为 json 文件对象,并检查内容是否符合 json 语法。
searchInfo = r->readAll(); // 读取全部信息
QJsonParseError err; //错误信息对象
QJsonDocument json_recv = QJsonDocument::fromJson(searchInfo,&err);//将json文本转换为 json 文件对象
if(err.error != QJsonParseError::NoError) //判断是否符合语法
{
qDebug() <<"搜索歌曲Json获取格式错误"<< err.errorString();
return;
}
2,如果语法合法后,我们就要检查是否有我们想要的信息,并对各个信息的 key 值作为解析条件提取出来。
QJsonObject totalObject = json_recv.object();
QStringList keys = totalObject.keys(); // 列出json里所有的key
if(keys.contains("result")) //如果有结果
{ //在 json 文本中 {}花括号里面是QJsonObject对象, []方括号里面是QJsonArray
QJsonObject resultObject = totalObject["result"].toObject(); //就将带 result 的内容提取后转换为对象
QStringList resultKeys = resultObject.keys(); //保存所有key
if(resultKeys.contains("songs")) //如果 key 为songs ,代表找到了歌曲
{
QJsonArray array = resultObject["songs"].toArray();
for(auto i : array) //开始获取歌曲中的信息
{
QJsonObject object = i.toObject();
musicId = object["id"].toInt(); // 音乐id
musicDuration = object["duration"].toInt(); // 音乐长度
musicName = object["name"].toString(); // 音乐名
mvId = object["mvid"].toInt(); // mvid
QStringList artistsKeys = object.keys();
if(artistsKeys.contains("artists")) //如果result中包含了 artists
{
QJsonArray artistsArray = object["artists"].toArray(); //将 artist 的内容提取后保存
for(auto j : artistsArray)
{
QJsonObject object2 = j.toObject();
singerName = object2["name"].toString(); // 歌手名
}
}
if(artistsKeys.contains("album")) //包含了专辑
{
QJsonObject albumObjct = object["album"].toObject();
albumName = albumObjct["name"].toString(); // 专辑名
}
// qDebug()<<"音乐ID:"+QString::number(musicId);
// qDebug()<<"音乐名:"+musicName;
// qDebug()<<"歌手名:"+singerName;
// qDebug()<<"总时长:"+QString::number(musicDuration);
// qDebug()<<"专辑名:"+albumName;
// qDebug()<<"mv的id:"+QString::number(mvId);
emit searchFinal(number,musicId,mvId,musicName,singerName,albumName,musicDuration); //发射信号
number+=1;
}
}
number = 0;
}
四,播放 url 歌曲
我们进行打印调试一下是否真正得到了想要的信息,以 《鼓楼》这首歌作为关键字进行搜索为例
发现已经得到了我们想要的信息,所以接下来我们将获取的音乐ID 以一定的Url 格式进行搜索进行验证, http:// https://music.163.com/song/media/outer/url?id=音乐ID
有了这个Url 之后我们就可以播放音乐了,如下:
QMediaPlayer *player=new QMediaPlayer; //播放对象
QMediaPlayerlist playerlist=new QMediaPlayerlist; //播放列表对象
QString url; //保存url
url=QString("https://music.163.com/song/media/outer/url?id=%0").arg(musicId); //将音乐ID作为格式输入到url中
playlist->addMedia(QUrl(url)); //添加一音乐到播放列表中
player->setMedia(playlist); //将列表设置到播放器中
player->play(); //播放
这样就可以听到自己想要听的音乐了,这就完成了播放器的主干,其余的功能可以慢慢查看Qt中的帮助进行补充。
自己做好的简易播放器如下,中间的空白部分功能还未完全添加
1,搜索(在线播放)
2,本地播放,选择想播放的歌曲(可以选择很多),点击播放即可
注:源码在我的资源中