1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > QT音乐播放器(接入网易云API)

QT音乐播放器(接入网易云API)

时间:2019-12-29 02:25:36

相关推荐

QT音乐播放器(接入网易云API)

实现的功能

1.可以播放本地音乐

2.实现常用功能(上下曲,播放/暂停,显示播放时长)

3.通过网易云API搜索歌曲

实现步骤

1.在pro文件里面添加multimedia库和network库

2.设计好自己的UI界面

3.添加自己需要的头文件并定义自己需要的变量

4.打开自己存放歌曲的目录,将歌曲添加到歌曲列表然后进行播放

5.通过信号与槽机制实现常用的功能

6.接入网易云API进行歌曲搜索

ui界面展示

代码模块展示

添加本地文件

file = QFileDialog::getOpenFileName(this,"Open File","D:/Music","mp3 Files (*.mp3)");//打开MP3文件,如果需要添加其余音频文件,只需继续添加过滤项即可playlist->addMedia(QUrl(file));//将自己需要的MP3文件添加入播放列表//以下是去掉前面的路径并且追加显示到plainTextEdit(将名字复制到另一个字符串)int fi=0,af=9;//fi为新字符串的开始位置,af为歌曲名字的第一个位置(自己的路径)QString s;//新字符串while(file[af]!='\0')将歌曲名字移动到数组开头{s[fi]=file[af];fi++;af++;}s[fi]='\0';//添加字符串结束标志ui->plainTextEdit->appendPlainText(s);//显示到plainTextEdit

播放/暂停

//通过标志位来实现播放与暂停if(x==0) //如果是停止状态或暂停就播放{player->play();x=1; //置1下一次点击就会暂停}else if(x==1) //如果是播放状态就暂停{player->pause(); x=0; //置0下一次点击就会播放}

下一曲

//点击下一曲,如果当前歌曲是最后一首歌曲,就跳到第一首歌,其余则直接跳到下一首int m_Value=playlist->currentIndex(); //当前歌曲是第几个int m_Amount=playlist->mediaCount(); //总歌曲数量if(m_Value<m_Amount) //判断当前歌曲是否为最后一首{m_Value=m_Value+1; //播放的位置+1playlist->setCurrentIndex(m_Value); //重新设置播放的位置player->play(); }else{m_Value=0;playlist->setCurrentIndex(m_Value); //跳到第一首player->play();}

上一曲与之类似

时间显示

//通过槽函数实现void Widget::timechange(qint64 duration){int secs = duration/1000; //全部秒数int mins = secs/60;//分secs = secs % 60;//秒QString str=QString::asprintf("%d:%d",mins,secs);//转换为字符串ui->lcdNumber->display(str);//用lcdNumber进行显示}

正在播放歌曲显示

//通过信号与槽机制检测文件是否变化void Widget::onDurationChanged(qint64 duration) //文件时长变化,更新当前播放文件名显示播放文件数据总大小的信号, 它可以获得文件时间长度。{ui->horizontalSlider->setMaximum(duration); //设置进度条最大值 也就是歌曲时长 msint m_Value=playlist->currentIndex();//获取当前歌曲的位置QTextBlock textLine=doc->findBlockByNumber (m_Value) ;//获取当前文本中的一段QString str=textLine.text();//将获取后的数据转为字符串int fi=0,af=9;QString s;if(str[0]=='D')//判断是否为本地文件(我的歌是在D盘里面的,所以第一个字符是D){while(str[af]!='\0'){s[fi]=str[af];fi++;af++;}s[fi]='\0';ui->lineEdit->setText(s);}elseui->lineEdit->setText(str);}

进度条显示

void Widget::onPositionChanged(qint64 position)//当前文件播放位置变化,更新进度显示播放到什么位置的信号, 参数是以毫秒来计算的。{if(ui->horizontalSlider->isSliderDown())return;//如果手动调整进度条,则不处理ui->horizontalSlider->setSliderPosition(position);//设置进度条的位置}

搜索歌曲ID

void Widget::on_b_search_clicked(){ui->music_m->clear();QString str,s;s=ui->l_search->text();//获取在搜索框输入的数据str="/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={"+s+"}&type=1&offset=0&total=true&limit=1";//接入网易云API并且传入需要搜索的数据和返回的数量QNetworkRequest request;//定义一个请求对象request.setUrl(str);//将请求格式设置给请求对象manager->get(request); //请求}

解析返回的数据

void Widget::databack(QNetworkReply *reply){searchInfo=reply->readAll(); //读取返回的全部数据QJsonParseError err;//错误信息对象QJsonDocument json_recv = QJsonDocument::fromJson(searchInfo,&err);//将json文本转换为 json 文件对象if(err.error != QJsonParseError::NoError) //判断是否符合语法{qDebug() <<"搜索歌曲Json获取格式错误"<< err.errorString();return;}QJsonObject totalObject = json_recv.object();QStringList keys = totalObject.keys(); // 列出json里所有的keyif(keys.contains("result")) //如果有结果{ //在 json 文本中 {}花括号里面是QJsonObject对象, []方括号里面是QJsonArrayQJsonObject resultObject = totalObject["result"].toObject();//就将带 result 的内容提取后转换为对象QStringList resultKeys = resultObject.keys();//保存所有keyif(resultKeys.contains("songs"))//如果 key 为songs ,代表找到了歌曲{QJsonArray array = resultObject["songs"].toArray();for(auto i : array) //开始获取歌曲中的信息{QJsonObject object = i.toObject();musicId = object["id"].toInt();// 音乐idmusicDuration = object["duration"].toInt(); // 音乐长度musicName = object["name"].toString(); // 音乐名mvId = object["mvid"].toInt();// mvidQStringList 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(); // 专辑名}ui->music_m->appendPlainText("音乐ID:"+QString::number(musicId));ui->music_m->appendPlainText("音乐名:"+musicName);ui->music_m->appendPlainText("歌手名:"+singerName);ui->music_m->appendPlainText("总时长:"+QString::number(musicDuration));ui->music_m->appendPlainText("专辑名:"+albumName);}}}QString url;url=QString("/song/media/outer/url?id=%0").arg(musicId);//通过网网易云API传入之前返回的歌曲的ID实现播放playlist->addMedia(QUrl(url)); //添加一音乐到播放列表中ui->plainTextEdit->appendPlainText(musicName); //用于显示}

遇到的问题:

1.网易云的API(自己在网上找的)

有关评论/api/v1/resource/comments/R_SO_4_{歌曲ID}?limit=20&offset=0limit:返回数据条数(每页获取的数量),默认为20,可以自行更改offset:偏移量(翻页),offset需要是limit的倍数type:搜索的类型歌单/api/playlist/detail?id={歌单ID}网易云音乐每日推荐各种神奇歌单也是它的一大特色,我们可以利用这个api获取歌单里的所有歌曲信息。用户信息/api/v1/user/detail/{用户ID}歌词/api/song/lyric?id={歌曲ID}&lv=1&kv=1&tv=-1搜索结果/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={搜索内容}&type=1&offset=0&total=true&limit=20limit:返回数据条数(每页获取的数量),默认为20,可以自行更改offset:偏移量(翻页),offset需要是limit的倍数type:搜索的类型type=1 单曲type=10 专辑type=100 歌手type=1000歌单type=1002用户type=1004MVtype=1006歌词type=1009主播电台歌手专辑/api/artist/albums/{歌手ID}?id={歌手ID}&offset=0&total=true&limit=10专辑信息/api/album/{专辑ID}?ext=true&id={专辑ID}&offset=0&total=true&limit=10歌曲信息/api/song/detail/?id={歌曲ID}&ids=%5B{歌曲ID}%5DMV/api/mv/detail?id={MV的ID}&type=mp4

2.可能报的错

work.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed大致说,Qt模块中是包含了OpenSSL库的,但是这些库不会自动部署到应用程序中。开发人员希望使用SSL的同时,它们的用户也安装了相关库。或者确保在当地使用SSL是经过许可可以安装opssl解决doRender: Unknown error 0x80040218.可能是因为没有装解码组件可以去安装一个 LAVFilters:也可能是因为播放的音乐是VIP音乐(播放VIP音乐就会报这个错)

效果视频单独发布了(用的那个游戏盒子录的屏,跳出来的文件夹没有显示)

源码

widget.h

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QMediaPlayer>#include <QMediaPlaylist>#include <QList>#include <QMediaContent>#include <QTextBlock>#include <QTimer>#include <QNetworkAccessManager>#include <QNetworkReply>#include <QJsonParseError>#include <QJsonObject>#include <QJsonArray>#include <QMessageBox>QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public slots:void on_pushButton_2_clicked();void on_pushButton_clicked();void on_next_clicked();void on_up_clicked();void timechange(qint64 duration);void onDurationChanged(qint64 duration); void onPositionChanged(qint64 position); void on_b_search_clicked();void databack(QNetworkReply *reply);private:Ui::Widget *ui;QString durationTime;QString positionTime;QNetworkAccessManager* manager;QMediaPlayer *player;QMediaPlaylist *playlist;QString file;QTextDocument* doc;QTextBlock textLine;QString str;int i,x;int musicId,musicDuration,mvId;QString musicName,singerName,albumName;QByteArray searchInfo;};#endif // WIDGET_H

widget.cpp

#include "widget.h"#include "ui_widget.h"#include <QFileDialog>#include <QDir>#include <QFile>#include <QLCDNumber>#include <QString>#include <QBrush>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);this->setMinimumSize(600,600);this->setMaximumSize(600,600);//我固定了窗口的大小ui->music_m->setReadOnly(true);//将显示信息的组件设置设置为只读manager = new QNetworkAccessManager(this); //定义并实例化一个网络管家ui->plainTextEdit->setReadOnly(true);//将显示音乐列表的组件设置为只读ui->lineEdit->setReadOnly(true);//将显示正在播放音乐的组件设置为只读this->setWindowTitle("QT播放器");//设置窗口标题x=0;//初始化标志位doc=ui->plainTextEdit->document () ; //文本对象player=new QMediaPlayer(this);playlist=new QMediaPlaylist(this);//初始化对象player->setMedia(playlist);//设置播放列表playlist->setPlaybackMode(QMediaPlaylist::Loop);设置播放模式//信号与槽机制进行处理connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(timechange(qint64)));connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(onPositionChanged(qint64)));connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(onDurationChanged(qint64)));connect(manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(databack(QNetworkReply *)));}Widget::~Widget(){delete ui;}void Widget::on_pushButton_2_clicked(){file = QFileDialog::getOpenFileName(this,"Open File","D:/Music","mp3 Files (*.mp3)");//打开文件playlist->addMedia(QUrl(file));//将选中的MP3文件添加到播放列表//将选中的文件去掉路径后追加显示到plainTextEditint fi=0,af=9;QString s;while(file[af]!='\0'){s[fi]=file[af];fi++;af++;}s[fi]='\0';ui->plainTextEdit->appendPlainText(s);}void Widget::on_pushButton_clicked(){if(x==0) //如果是停止状态或暂停就播放{player->play();x=1;}else if(x==1) //如果是播放状态就暂停{player->pause();x=0;}}void Widget::on_next_clicked(){int m_Value=playlist->currentIndex();//当前歌曲是第几个int m_Amount=playlist->mediaCount(); //总歌曲数量if(m_Value<m_Amount){m_Value=m_Value+1;playlist->setCurrentIndex(m_Value);player->play();}else{m_Value=0;playlist->setCurrentIndex(m_Value);player->play();}}void Widget::on_up_clicked(){int m_Value=playlist->currentIndex();//当前歌曲是第几个int m_Amount=playlist->mediaCount(); //总歌曲数量if(m_Value>0){m_Value=m_Value-1;playlist->setCurrentIndex(m_Value);player->play();}else{m_Value=m_Amount-1;playlist->setCurrentIndex(m_Value);player->play();}}void Widget::timechange(qint64 duration){int secs = duration/1000; //全部秒数int mins = secs/60;//分secs = secs % 60;//秒QString str=QString::asprintf("%d:%d",mins,secs);ui->lcdNumber->display(str);}void Widget::onDurationChanged(qint64 duration) //文件时长变化,更新当前播放文件名显示播放文件数据总大小的信号, 它可以获得文件时间长度。{ui->horizontalSlider->setMaximum(duration); //设置进度条最大值 也就是歌曲时长 msint m_Value=playlist->currentIndex();QTextBlock textLine=doc->findBlockByNumber (m_Value) ; // 文本中的一段QString str=textLine.text();int fi=0,af=9;QString s;if(str[0]=='D'){while(str[af]!='\0'){s[fi]=str[af];fi++;af++;}s[fi]='\0';ui->lineEdit->setText(s);}elseui->lineEdit->setText(str);}void Widget::onPositionChanged(qint64 position)//当前文件播放位置变化,更新进度显示播放到什么位置的信号, 参数是以毫秒来计算的。{if(ui->horizontalSlider->isSliderDown())return;//如果手动调整进度条,则不处理ui->horizontalSlider->setSliderPosition(position);}void Widget::on_b_search_clicked(){ui->music_m->clear();QString str,s;s=ui->l_search->text();str="/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={"+s+"}&type=1&offset=0&total=true&limit=1";QNetworkRequest request;//定义一个请求对象request.setUrl(str);//将请求格式设置给请求对象manager->get(request); //请求}void Widget::databack(QNetworkReply *reply){searchInfo=reply->readAll();QJsonParseError err;//错误信息对象QJsonDocument json_recv = QJsonDocument::fromJson(searchInfo,&err);//将json文本转换为 json 文件对象if(err.error != QJsonParseError::NoError) //判断是否符合语法{qDebug() <<"搜索歌曲Json获取格式错误"<< err.errorString();return;}QJsonObject totalObject = json_recv.object();QStringList keys = totalObject.keys(); // 列出json里所有的keyif(keys.contains("result")) //如果有结果{ //在 json 文本中 {}花括号里面是QJsonObject对象, []方括号里面是QJsonArrayQJsonObject resultObject = totalObject["result"].toObject();//就将带 result 的内容提取后转换为对象QStringList resultKeys = resultObject.keys();//保存所有keyif(resultKeys.contains("songs"))//如果 key 为songs ,代表找到了歌曲{QJsonArray array = resultObject["songs"].toArray();for(auto i : array) //开始获取歌曲中的信息{QJsonObject object = i.toObject();musicId = object["id"].toInt();// 音乐idmusicDuration = object["duration"].toInt(); // 音乐长度musicName = object["name"].toString(); // 音乐名mvId = object["mvid"].toInt();// mvidQStringList 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(); // 专辑名}ui->music_m->appendPlainText("音乐ID:"+QString::number(musicId));ui->music_m->appendPlainText("音乐名:"+musicName);ui->music_m->appendPlainText("歌手名:"+singerName);ui->music_m->appendPlainText("总时长:"+QString::number(musicDuration));ui->music_m->appendPlainText("专辑名:"+albumName);}}}QString url;url=QString("/song/media/outer/url?id=%0").arg(musicId);playlist->addMedia(QUrl(url)); //添加返回的音乐到播放列表中ui->plainTextEdit->appendPlainText(musicName); //用于显示}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。