void Widget::on_playMusicButton_clicked()//點擊播放歌曲按鈕{ if(currentSongIndex > songIdList.size()) return; currentSongInfo = this->getSongRealLinkById(songIdList.at(currentSongIndex)); mediaPlayer->setMedia(QUrl(currentSongInfo.songRealLink)); mediaPlayer->play(); QString lyric = this->getLyric(currentSongInfo.lyricLink);//從網上獲取歌詞 lyricList = this->parse(lyric);//將lyric一行行地解析到lyricList}//1、獲取頻道列表QList<CHANNEL_INFO> Widget::getChannelList(){ const QString channelUrl = "http://fm.baidu.com/dev/api/?tn=channellist"; QList<CHANNEL_INFO> channelInfoList; QNetworkRequest networkRequest; QNetworkaccessManager *networkManager = new QNetworkAccessManager; networkRequest.setUrl(QUrl(channelUrl)); networkManager->setCookieJar(0); QNetworkReply *reply = networkManager->get(networkRequest); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); reply->deleteLater(); QByteArray buf = reply->readAll(); QJsonParseError jsonError; QJsonDocument jsonRes = QJsonDocument::fromJson(buf, &jsonError);; if(jsonError.error == QJsonParseError::NoError) { if(jsonRes.isObject()) { QVariantMap result = jsonRes.toVariant().toMap();//提取花括號里的鍵值對 foreach(QVariant channel, result["channel_list"].toList())//提取[]里的頻道 { //由于每個頻道也是一個{} QVariantMap channelMap = channel.toMap();//提取花括號的鍵值對 CHANNEL_INFO channelInfo; channelInfo.channelId = channelMap["channel_id"].toString(); channelInfo.channelName = channelMap["channel_name"].toString(); channelInfoList.append(channelInfo); } } } return channelInfoList;}//2、根據頻道id,獲取某個頻道下的歌曲列表(比如推薦頻道public_tuijian_sPRing)QList<QString> Widget::getSongIdList(QString channelId){ const QString playListUrl = "http://fm.baidu.com/dev/api/?tn=playlist&format=json&id="; QNetworkRequest networkRequest; QNetworkAccessManager *networkManager = new QNetworkAccessManager; networkRequest.setUrl(QUrl(playListUrl + channelId)); networkManager->setCookieJar(0); QNetworkReply *reply = networkManager->get(networkRequest); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); reply->deleteLater(); QList<QString> songId; QByteArray buf = reply->readAll(); QJsonParseError jsonError; QJsonDocument jsonRes = QJsonDocument::fromJson(buf, &jsonError);; if(jsonError.error == QJsonParseError::NoError) { if(jsonRes.isObject()) { QVariantMap result = jsonRes.toVariant().toMap(); foreach(QVariant song, result["list"].toList()) { QVariantMap songMap = song.toMap(); QString id = songMap["id"].toString();//獲取歌曲id //如果歌曲ID有效 if(!id.isEmpty()) { songId.append(id); } } } } return songId;}//3、根據songID(比如1615837),獲取一首歌的歌曲名稱和下載鏈接SONG_INFO Widget::getSongRealLinkById(QString songId){ const QString downLoadLinkUrl = "http://music.baidu.com/data/music/fmlink?type=mp3&rate=320&songIds="; QNetworkRequest networkRequest; QNetworkAccessManager networkManager; networkRequest.setUrl(QUrl(downLoadLinkUrl + songId)); networkManager.setCookieJar(0); QNetworkReply *reply = networkManager.get(networkRequest); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); reply->deleteLater(); //歌曲信息 SONG_INFO songInfo; QByteArray buf = reply->readAll(); QJsonParseError jsonError; QJsonDocument jsonRes = QJsonDocument::fromJson(buf, &jsonError);; if(jsonError.error == QJsonParseError::NoError) { if(jsonRes.isObject()) { QVariantMap result = jsonRes.toVariant().toMap(); QVariantMap dataList = result["data"].toMap(); foreach(QVariant data, dataList["songList"].toList()) { QVariantMap linkMap = data.toMap(); songInfo.songRealLink = linkMap["songLink"].toString(); songInfo.songName = linkMap["songName"].toString(); songInfo.artistName = linkMap["artistName"].toString(); songInfo.songPicSmall = linkMap["songPicSmall"].toString(); songInfo.songPicRadio = linkMap["songPicRadio"].toString(); songInfo.albumName = linkMap["albumName"].toString(); songInfo.lyricLink = linkMap["lrcLink"].toString(); } } } return songInfo;}2、實現歌詞顯示
//根據lrcLink獲取歌詞QString Widget::getLyric(QString lyricLink)//lyricLink是歌詞下載地址{ QNetworkRequest networkRequest; QNetworkAccessManager networkManager; networkRequest.setUrl(QUrl(lyricLink)); QNetworkReply *reply = networkManager.get(networkRequest); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); reply->deleteLater(); QString lyrc; lyrc = reply->readAll(); return lyrc;}//解析從網上獲取的歌詞QList<QLyric> Widget::parse(QString lyric){ QTextStream stream(&lyric); QTextCodec *codec = QTextCodec::codecForName("utf-8"); stream.setCodec(codec); currentLyricIndex = 0; lyricList.clear(); //QRegExp解析歌詞 QRegExp timeExp; timeExp.setPatternSyntax(QRegExp::RegExp); timeExp.setCaseSensitivity(Qt::CaseSensitive); timeExp.setPattern("//[([0-9]{2}):([0-9]{2})//.([0-9]{2})//]"); //匹配[00:02.42] QList<QLyric> result; while (!stream.atEnd()) { QString line = stream.readLine(); int ret = timeExp.indexIn(line); QList<QTime> ticks; int lastindex = 0; while (ret >= 0) { QStringList tstr = timeExp.capturedTexts(); QTime time(0, tstr[1].toInt(), tstr[2].toInt(), tstr[3].toInt()); ticks.append(time); lastindex = ret + timeExp.matchedLength(); ret = timeExp.indexIn(line, lastindex); }//經過測試,ticks只會含有一個項 QString lyricstr = line.right(line.size() - lastindex);//提取歌詞 for (const QTime& t : ticks)//c++11 { QLyric lyric; lyric.time = t.minute() * 60 * 1000 + t.second() * 1000 + t.msec();//單位ms lyric.lyric = lyricstr; result.append(lyric); } } std::sort(result.begin(), result.end(), [] (const QLyric& a, const QLyric& b) -> bool { return a.time < b.time; }); return result;//保存了一行行的歌詞}//顯示歌詞的槽函數void Widget::slotShowLyric(qint64 position){ if(lyricList.size() <= 0 || currentLyricIndex >= lyricList.size()) return; for(int i = 0; i < lyricList.size(); i++) { if(position > lyricList.at(i).time) { currentLyricIndex = i; } } //顯示position之后的歌詞,position之前的已經播放過了 if(position > lyricList.at(currentLyricIndex).time) { //始終顯示作者名和歌曲名 QString lrc; lrc.clear(); lrc += QString("<p align='center'><span style=' font-style:italic;'>"); lrc += currentSongInfo.artistName + " - " + currentSongInfo.songName; lrc += QString("</span></p>"); //j從m_iCurrentIndex - 1開始,是為了顯示出正在唱的前一句 for(int j = currentLyricIndex - 1; j < lyricList.size(); j++) { if(j < 0) continue; if(currentLyricIndex == j)//正在唱的歌詞,顏色加粗 { lrc += QString("<p align='center'><span style=' font-weight:600;'>"); lrc += lyricList.at(currentLyricIndex).lyric; lrc += QString("</span></p>"); } else { lrc += "<p align='center'>"; lrc += lyricList.at(j).lyric; lrc += "</p>"; } } ui->lyricLabel->setText(lrc); currentLyricIndex++; }}3、實現歌曲下載
void Widget::on_downLoadButton_clicked()//點擊下載歌曲按鈕{ QString fileName; QDir dir; if(!dir.exists("./download")) { dir.mkdir("./download"); } fileName = "./download/" + currentSongInfo.songName + ".mp3"; this->downLoadMusic(fileName, currentSongInfo.songRealLink);}//從網上下載歌曲,fileName是下載之后文件名(含路徑),url是歌曲下載鏈接void Widget::downLoadMusic(QString fileName, QString songLink){ QNetworkRequest networkRequest; QNetworkAccessManager networkManager; networkRequest.setUrl(QUrl(songLink)); QNetworkReply *reply = networkManager.get(networkRequest); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); reply->deleteLater(); QFile file; file.setFileName(fileName); bool ok = file.open(QIODevice::WriteOnly); if(ok) { file.write(reply->readAll()); }}完整代碼下載:http://download.csdn.net/detail/bladeandmaster88/9749987
新聞熱點
疑難解答