基于Qt编写的在线音乐播放器
Posted guishangppy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Qt编写的在线音乐播放器相关的知识,希望对你有一定的参考价值。
思路: 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,本地播放,选择想播放的歌曲(可以选择很多),点击播放即可
注:源码在我的资源中
Qt编写带频谱的音乐播放器
之前有个项目需要将音频文件的频谱显示出来,想了很多办法,后面发现fmod这个好东西,还是跨平台的,就一个头文件+一个库文件就行,简单小巧功能强大,人家做的真牛逼。为了不卡住界面,采用了多线程处理。
可执行文件下载:https://pan.baidu.com/s/1JIjiCv800KPDZS9aSRPObQ
1:可获取整个声音文件采样值数据
2:可实时获取当前播放位置的采样值数据
3:可设置采样的步长和数量
4:可开始播放/暂停播放/停止播放
5:多线程处理,超流畅
6:可设置当前播放位置
7:可设置音量
#ifndef FMODTHREAD_H #define FMODTHREAD_H /** * fmod音乐播放类 作者:feiyangqingyun(QQ:517216493) 2017-9-12 * 1:可获取整个声音文件采样值数据 * 2:可实时获取当前播放位置的采样值数据 * 3:可设置采样的步长和数量 * 4:可开始播放/暂停播放/停止播放 * 5:多线程处理,超流畅 * 6:可设置当前播放位置 * 7:可设置音量 * 参考文章:http://blog.csdn.net/fengyhack/article/details/43318575 */ #include <QThread> class FMOD_SYSTEM; class FMOD_SOUND; class FMOD_CHANNEL; class FmodThread : public QThread { Q_OBJECT public: explicit FmodThread(QObject *parent = 0); ~FmodThread(); protected: void run(); private: bool stopped; //停止线程标志位 bool isPlayWave; //开始播放标志位 bool isPauseWave; //暂停播放标志位 bool isStopWave; //停止播放标志位 bool isReadWave; //读取当前位置采样值标志位 int step; //采样值步长 int count; //采样点总数 int interval; //采样间隔 bool showWaveDataAll; //是否显示总采样 QString fileName; //当前声音文件 FMOD_SYSTEM *system; //fmod结构体 FMOD_SOUND *sound; //播放声音对象 FMOD_CHANNEL *channel; //播放声音通道 private slots: //获取当前位置采样值数据 void readWaveData(); //获取所有采样值数据 void readWaveDataAll(); //开始播放 void playWave(); //暂停播放 void pauseWave(); //停止播放 void stopWave(); signals: //开始播放信号 void playStart(); //停止播放信号 void playStop(); //暂停播放信号 void playPause(); //当前播放时长 void filePositionReceive(uint position, bool isPlay); //总时长 void fileLengthReceive(uint length); //音量大小 void fileVolumeReceive(int volume, bool mute); //当前声音正在播放位置采样值数据 void waveDataReceive(const QVector<float> &waveData); //当前声音所有采样值数据 void waveDataAllReceive(const QVector<float> &waveData); public slots: //设置采样值步长 void setStep(int step); //设置采样点总数 void setCount(int count); //设置采样间隔 void setInterval(int interval); //设置是否显示总采样 void setShowWaveDataAll(bool showWaveDataAll); //设置要播放的声音文件 void setFileName(const QString &fileName); //播放 void play(); //暂停 void pause(); //停止 void stop(); //停止线程 void stopAll(); //设置播放进度位置 void setPosition(int position); //设置音量 void setVolume(int volume); //设置静音 void setMute(bool mute); }; #endif // FMODTHREAD_H
以上是关于基于Qt编写的在线音乐播放器的主要内容,如果未能解决你的问题,请参考以下文章
QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解