[Linux C]百度音乐API实现在线搜歌

news/2024/2/20 13:52:19

最近在做科大讯飞的语音解析模块,主要用于语音控制播放。采集语音输入后,送给科大讯飞语音的SDK,云服务器返回JSON的数据,再解析拿到URL地址,最后送给播放器去播放。不知是否是尚未上线的product,申请的appid,解析JSON后拿到的URL地址,歌曲播放的时间都很短,一般不到1分钟。

一番网络搜索后,据说百度有个未公开的搜歌API,只要拿到歌手和歌曲名,就可以传给这个URL,然后百度就会回你一个XML文件,解析这个文件,就可以拿到你要的MP3播放地址了,那就开始干活吧。

百度音乐搜索API实现说明

搜歌API: http://box.zhangmen.baidu.com/x?op=12&count=1&title=
在上面这个地址后面加上要搜索的歌手和歌曲名,如下图
这里写图片描述
至于这里的歌手和歌曲名,都是由科大讯飞的SDK返回的JSON数据,解析出来的,此处不需要关心。

在浏览器的地址栏上输入上面的地址,就会返回如下图的内容:
这里写图片描述
然后将红色框框的1和2拼凑在一起,就得到了mp3的地址,即
http://zhangmenshiting.baidu.com/data2/music/88329745/88329745.mp3?xcode=1c4dab84d5d0d5dc44a2e9dde28d95e5117565b2b6f412d5&mid=0.00592347543617

具体流程图如下图:

这里写图片描述

本文主要讲述实线框框内的实现

  • Decode 中文 URL
    因为URL带有中文字符,做HTTP请求的时候,需要将中文字符 decode一下,方能识别,具体方法如下
CHAR from_hex(CHAR ch) 
{return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}CHAR *url_decode(CHAR *str) 
{CHAR *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf;while (*pstr) {if (*pstr == '%') {if (pstr[1] && pstr[2]) {*pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);pstr += 2;}} else if (*pstr == '+') { *pbuf++ = ' ';} else {*pbuf++ = *pstr;}pstr++;}*pbuf = '\0';return buf;
}

拿到decode的字符后,将其拼凑成一个完整的URL即可。

  • CURL模拟HTTP请求
    拿到可以访问的URL后,接下来就是用CURL模拟HTTP请求,去抓取百度搜歌的内容,此处利用的CURL将数据写到buffer的方式,并非保存文件方式,具体实现如下:
static INT32 curl_http_download_progress_callback(void *p,double t, /* dltotal */double d, /* dlnow */double ultotal,double ulnow)
{INT32 currentPercent = 0;if(t != 0){currentPercent = (int)((double)100*(d/t));  }printf("Curl DownLoad percent : %d\n", currentPercent);if(100 == currentPercent){sem_post(&semDownLoadFinished);}return CURL_RET_OK;
}static size_t curl_http_write_memory_cb(void *contents, size_t size, size_t nmemb, void *userp)
{size_t realsize = size * nmemb;struct MemoryStruct *mem = (struct MemoryStruct *)userp;mem->memory = realloc(mem->memory, mem->size + realsize + 1);if (mem->memory == NULL) {/* out of memory! */printf("not enough memory (realloc returned NULL)\n");exit(EXIT_FAILURE);}memcpy(&(mem->memory[mem->size]), contents, realsize);mem->size += realsize;mem->memory[mem->size] = 0;return realsize;
}INT32 curl_http_get_page(const CHAR * url)
{CURL *curl;CURLcode res;chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */chunk.size = 0;    /* no data at this point */res = curl_global_init(CURL_GLOBAL_ALL);if(CURLE_OK != res){return CURL_RET_FAIL;}curl = curl_easy_init();if(curl) {        curl_easy_setopt(curl, CURLOPT_URL, url);curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_http_write_memory_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_http_download_progress_callback);curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,curl);curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);                        // display debug msgcurl_easy_perform(curl);curl_easy_cleanup(curl);}    return CURL_RET_OK;
}

在确保网页的内容全部保存到buffer中,这里用到了CURL的CURLOPT_PROGRESSFUNCTION参数,通过它,你可以拿到下载的百分比,当下载到100%时,会post一个信号量,收到这个信号量,就可以进行下一个环节了

注意:
1.这里没有做CURL超时处理,请自行加上
2.关于CURL的使用,可以参考以下地址
curl使用小结
ubuntu 13.10下安装curl
ubuntu下运行程序提示找不到libcurl动态库

  • XML解析
    拿到网页内容后,解析来就是XML字段。这里是利用libxml2去做解析,具体实现如下
CHAR * xml_parse_file(CHAR *buf, INT32 len)
{INT32 str1Len=0, str2Len=0;CHAR *temp1URL=NULL, *temp2URL=NULL;CHAR * retURL = NULL;xmlDocPtr doc;xmlNodePtr root,node;xmlChar *value;//xml_str_replace(buf, "encoding=\"gb2312\"", "encoding=\"utf-8\"");  //此处因为在板子上跑,xml解析会出错,说不支持gb2312,而PC上的LINUX不需要转换即可解析,PC上加了也可以解析出来doc = xmlParseMemory(buf,len);    //parse xml in memoryif (NULL == doc) {  printf("Document not parsed successfully\n");return NULL; } root=xmlDocGetRootElement(doc);for(node=root->children;node;node=node->next){if(xmlStrcasecmp(node->name,BAD_CAST"url")==0)break;}if(node==NULL){TONLY_VOICE_LOG_ERR("no node = content\n");return NULL;}for(node=node->children;node;node=node->next){if(xmlStrcasecmp(node->name,BAD_CAST"encode")==0){   value=xmlNodeGetContent(node);            temp1URL = strrchr((CHAR *)value, '/');str1Len = strlen((CHAR *)value) - strlen((CHAR *)temp1URL);temp2URL = (CHAR *)malloc(sizeof(CHAR)*str1Len+1);            memset(temp2URL, 0, sizeof(CHAR)*str1Len+1);memcpy(temp2URL, value, str1Len+1);temp2URL[str1Len+1] = '\0';printf("Cut out the decode URL is %s\n",temp2URL);             xmlFree(value);}else if(xmlStrcasecmp(node->name,BAD_CAST"decode")==0){       value=xmlNodeGetContent(node);if(temp2URL){str2Len = strlen((CHAR *)value) + strlen((CHAR *)temp2URL);retURL = (CHAR *)malloc(sizeof(CHAR)*str2Len + 1);memset(retURL, 0, sizeof(CHAR)*strlen((CHAR *)value) + 1);strcpy(retURL, temp2URL);strcat(retURL, (CHAR *)value);retURL[str2Len+1] = '\0';free(temp2URL);printf("retURL is %s\n",retURL); }xmlFree(value);}}xmlFreeDoc(doc);    return retURL;
}

最后xml_parse_file返回的字符串,就是最终的mp3播放地址,将其送给播放器就可以实现播放了。

注意:
1.libxml2的安装方法如下:
(1)sudo apt-get install libxml2
(2)sudo apt-get install libxml2-dev

2.libxml2使用方法
[Linux C]利用libxml2解析xml文件
Linux环境下C使用的XML解析库:libxml2

参考资料

  1. 百度MP3音乐API接口及应用
  2. 在线音乐API的研究
  3. 抓包获取百度音乐API
  4. linux c语言字符串函数replace,indexOf,substring等的实现
  5. libxml2官网

http://www.ppmy.cn/news/882520.html

相关文章

百度音乐的爬虫操作流程

通常&#xff0c;我们会使用selenium来获取页面的元素&#xff0c;百度音乐(千千音乐)的爬取音乐&#xff0c;并下载下来。 这里&#xff0c;我们依然使用selenium来换取页面歌单信息&#xff0c;经过分析&#xff0c;歌单列表获取后&#xff0c;可以获取歌曲的song_id 和 tit…

python下载百度音乐

之前看到有人写过类似的代码&#xff0c;感觉有点累赘&#xff0c;其中登陆那些东西其实可以避免的 我把百度音乐的网页代码稍微分析了一下&#xff0c;如果要求不高&#xff0c;下载普通音质的歌曲是不需要登陆的&#xff08;当然如果你用浏览器打开下载的话&#xff0c;普通…

python爬虫之爬取百度音乐

本人大三真皮沙发又来了&#xff0c;继上次写了一个爬取捞月狗直播的爬虫后&#xff0c;笔者觉得自己有必要写一个原创的爬虫小框架。可是大家都知道&#xff0c;一个成熟的框架是十分困难的&#xff0c;所以笔者就尝试了不同的数据的抓取方法。在不同的方法中&#xff0c;找到…

使用百度音乐盒API接口实现音乐播放器

百度音乐盒提供了一个便捷的API可以拿来访问一些音乐资源&#xff0c;开发者通过访问指定格式的url可以拿到返回的数据&#xff0c;这个数据可以是json或者xml&#xff0c;这里面包含了歌曲的信息。完整的API各种访问格式是非常丰富的&#xff0c;参见http://www.cnblogs.com/l…

音乐直链php,【原创】百度音乐直链 + 实现方法

前几天发了一篇QQ音乐直链的帖子:http://www.52pojie.cn/thread-419942-1-1.html 今晚利用空闲时间,折腾了一个百度音乐直链分析工具,也是网页在线的, 大家可以先看一下:http://dwz.cn/1WQoqW ---------------------------------------------蛋疼的分割线----------------…

微信服务开发——读取百度音乐接口返回音乐

最近用了很多网上的坑爹接口&#xff0c;都泪奔了&#xff0c;不说了&#xff0c;都是泪啊~ 前两天做了个微信返回音乐的接口&#xff0c;先来看下效果&#xff1a; 出来之后在手机微信里面就可以实现音乐播放了。 技术很简单&#xff0c;首先访问百度音乐接口&#xff0c;传入…

百度音乐接口API

歌曲URL 详细信息接口&#xff1a; http://ting.baidu.com/data/music/links?songIds776965 {data {songList ({albumId 0;albumName "2004\U65e0\U4e0e\U4f26\U6bd4\U6f14\U5531\U4f1a";artistId 7994;artistName "\U5468\U6770\U4f26&quo…

百度音乐下载地址解析

软件初步介绍&#xff1a; 为什么我要干这档子事情啊&#xff1f; 一个字&#xff0c;懒&#xff0c;太懒&#xff0c;懒得自己去找&#xff0c;懒得冲会员去下载一些高品质歌&#xff0c;所以干脆写个小东西来搞一搞吧。直接了当&#xff0c;干脆直接balbala一堆歌曲源下载地址…

百度音乐API抓取

百度音乐API抓取 前段时间做了一个本地音乐的播放器 github地址&#xff0c;想实现在线播放的功能&#xff0c;于是到处寻找API&#xff0c;很遗憾&#xff0c;不是歌曲不全就是质量不高。在网上发现这么一个APIMRASONG博客&#xff0c;有“获取榜单&#xff0c;搜索歌词&#…

百度音乐接口

百度音乐接口 2011-09-07 08:40 当你在百度去搜索一首歌时,你会发现有种更简单的方法,嘿嘿,安宁ヤ太天真告诉你个秘密,百度有个不公开的API http://box.zhangmen.baidu.com/x?op12&count1&title大约在冬季$$齐秦$$$$ 用上面的地址,红色部分改成歌名与作者名,然后百度…

百度音乐全接口 API

百度音乐全接口 会利用使用接口找歌简单又快捷 http://tingapi.ting.baidu.com/v1/restserver/ting 获取方式&#xff1a;GET 参数&#xff1a;formatjson或xml&calback&fromwebapp_music&method以下不同的参数获得不同的数据 PS&#xff1a;format根据开发需要可…

百度音乐接口使用示例

百度音乐全接口 http://tingapi.ting.baidu.com/v1/restserver/ting 请求方式&#xff1a;GET 参数处理&#xff1a;formatjson&calback&fromwebapp_music&method以下不同的参数获得不同的数据 一、获取列表 例&#xff1a;methodbaidu.ting.billboard.billLi…

Google Bard 拓展与归纳

导言&#xff1a; Bard&#xff08;谷歌人工智能语言模型“https://bard.google.com”&#xff09;在不断演进和改进中&#xff0c;为用户提供了更丰富、便捷和个性化的服务体验。本文集将深入探索 Bard 在不同方面的关键更新&#xff0c;包括语言支持扩大、图像呈现、交互方式…

Python 爬取百度音乐

Python&#xff1a;3.5 欢迎加入学习交流QQ群&#xff1a;657341423 获取歌曲信息 post方式 import requests urlhttp://play.baidu.com/data/music/songlink data{songIds:100575177} rrequests.post(url,datadata) print (r.content.decode(UTF-8)) fopen(data.txt,w,encod…

制作百度音乐标签页面html,百度音乐标签.html

无标题文档 全部歌手 A AFineFrenzy Air Supply Aln Spink 安其拉 安在旭 安室奈美惠 B Babyface Backstsktrrt.. Bandari Barbra Streisand Bee Gss 北京天使合唱团 宝儿 包包的音乐花园 巴哈尔古丽 巴桑 布仁巴雅尔 C Chris Garneau Cheistina Aguilera Christina Perr…

百度音乐API全接口

百度音乐API http://tingapi.ting.baidu.com/v1/restserver/ting 获取方式&#xff1a;GET 参数&#xff1a;formatjson或xml&calback&fromwebapp_music&method以下不同的参数获得不同的数据 PS&#xff1a;format根据开发需要可选择json或xmml&#xff0c;其他参…

html制作百度音乐标签页面,网页调用百度音乐盒

在自己的网页中嵌入百度音乐盒 选择播放自己的音乐 完整代码如下:my music body{margin:0; padding: 0; } .p{font-size: 20px; font-family: "Times New Roman"; } .center{width: 500px; height: 300px; margin:20px 0 0 100px; float:left; } 请输入格式为“后来…

百度音乐api接口

音乐列表 http://tingapi.ting.baidu.com/v1/restserver/ting?format{0}&calback&fromwebapp_music&methodbaidu.ting.billboard.billList&type{1}&size{2}&offset{3} 参数{0}&#xff1a;返回格式&#xff0c;json或xml 参数{1}&#xff1a;列表类型…

百度音乐标签页面

代码如下&#xff1a; <!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equ…

百度音乐高调改名后 掉队的千千音乐还有机会吗?

最近&#xff0c;数字音乐市场再生变数&#xff0c;向来低调的百度音乐突然宣布改名“千千音乐”&#xff0c;曾经的“千千静听”重新归来。令人没想到的是&#xff0c;在百度音乐改名之后&#xff0c;其背后的太合音乐也宣布融资10亿&#xff0c;数字音乐市场仿佛即将迎来巨大…
最新文章