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
新闻热点
疑难解答