QT音乐播放器(接入网易云API)
生活随笔
收集整理的這篇文章主要介紹了
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="http://music.163.com/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("https://music.163.com/song/media/outer/url?id=%0").arg(musicId);//通過網網易云API傳入之前返回的歌曲的ID實現播放playlist->addMedia(QUrl(url)); //添加一音樂到播放列表中ui->plainTextEdit->appendPlainText(musicName); //用于顯示 }遇到的問題:
1.網易云的API(自己在網上找的)
有關評論 http://music.163.com/api/v1/resource/comments/R_SO_4_{歌曲ID}?limit=20&offset=0 limit:返回數據條數(每頁獲取的數量),默認為20,可以自行更改 offset:偏移量(翻頁),offset需要是limit的倍數 type:搜索的類型歌單 https://music.163.com/api/playlist/detail?id={歌單ID} 網易云音樂每日推薦各種神奇歌單也是它的一大特色,我們可以利用這個api獲取歌單里的所有歌曲信息。用戶信息 https://music.163.com/api/v1/user/detail/{用戶ID}歌詞 https://music.163.com/api/song/lyric?id={歌曲ID}&lv=1&kv=1&tv=-1搜索結果 http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={搜索內容}&type=1&offset=0&total=true&limit=20 limit:返回數據條數(每頁獲取的數量),默認為20,可以自行更改 offset:偏移量(翻頁),offset需要是limit的倍數 type:搜索的類型 type=1 單曲 type=10 專輯 type=100 歌手 type=1000 歌單 type=1002 用戶 type=1004 MV type=1006 歌詞 type=1009 主播電臺歌手專輯 http://music.163.com/api/artist/albums/{歌手ID}?id={歌手ID}&offset=0&total=true&limit=10專輯信息 http://music.163.com/api/album/{專輯ID}?ext=true&id={專輯ID}&offset=0&total=true&limit=10歌曲信息 http://music.163.com/api/song/detail/?id={歌曲ID}&ids=%5B{歌曲ID}%5DMV http://music.163.com/api/mv/detail?id={MV的ID}&type=mp42.可能報的錯
qt.network.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_NAMESPACE namespace 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_Hwidget.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="http://music.163.com/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("https://music.163.com/song/media/outer/url?id=%0").arg(musicId);playlist->addMedia(QUrl(url)); //添加返回的音樂到播放列表中ui->plainTextEdit->appendPlainText(musicName); //用于顯示 }總結
以上是生活随笔為你收集整理的QT音乐播放器(接入网易云API)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信 小程序 常见错误
- 下一篇: 转载:https://blog.csdn