一、引言与说明 目前很多公众帐号都可以实现点歌功能,笔者也很好奇是如何实现的,就做了个实验,现将经验分享如下。 有关音乐消息的说明,就不在此赘述,请自行查阅开发文档。 回复音乐消息的关键在于如何获得歌曲的链接,开发者必须找一个现成的音乐搜索AP
目前很多公众帐号都可以实现点歌功能,笔者也很好奇是如何实现的,就做了个实验,现将经验分享如下。
有关音乐消息的说明,就不在此赘述,请自行查阅开发文档。
回复音乐消息的关键在于如何获得歌曲的链接,开发者必须找一个现成的音乐搜索API(对大多数开发者都不太可能有自己的音乐服务器),或者只向用户回复固定的几首音乐,可以定期手动更新[1](参考)。
百度有一个私有的音乐搜索API。开发者可以直接调用,地址如下:
http://box.zhangmen.baidu.com/x?op=12&count=1&title=Song$$Singer$$$$
<result> <count>1</count> <url> <encode> http://zhangmenshiting.baidu.com/data2/music/64380827/Z2ZmbGVuaW9fn6NndK6ap5WXcGZlbm-aYpNol2ppm5xjamRtbpttbWeVlpdrmGlrkpNomZaXa3CTZJeZmW1ncGVll1qin5t1YWBnZWVoam5hZWNqZ2hnaTE$ </encode> <decode> 64380827.mp3?xcode=2088b1a5c53dd28199e656ccc6b23aa5eaa48b2ded70843d&mid=0.41023603062201 </decode> <type>8</type> <lrcid>14706</lrcid> <flag>1</flag> </url> <durl> <encode>http://zhangmenshiting2.baidu.com/data2/music/35424427/ZGdnZmlqaW9fn6NndK6ap5WXcGZlbm-aYpNol2ppm5xjamSWm5qbaGaWZWyXbm2dampsbGqca5mVZ5iWlmxwnGJmZlqin5t1YWBnZWVoam5hZWNqZ2hnaTE$ </encode> <decode> 35424427.mp3?xcode=2088b1a5c53dd281bfdd05d28b86e98985f4ad5eba69d143&mid=0.41023603062201 </decode> <type>8</type> <lrcid>14706</lrcid> <flag>1</flag> </durl> <p2p> <hash>d1cae9f7634c5aa3d54d7b1b1ad4c5b79b6e97ff</hash> <url></url> <type>mp3</type> <size>5710896</size> <bitrate>192</bitrate> </p2p> </result>
1)
2)
3)
4)
开发者需要对
<span>/* * 所属类:apiFunction * 函数名:baiduMusic() * 参数: * 功能:调用百度音乐api,推送音乐 */ public function baiduMusic($Song, $Singer) { if (!empty($Song)) { //音乐链接有两中品质,普通品质和高品质 $music = array ( 'url' => "", 'durl' => ""); //采用php函数file_get_contents来读取链接内容 $file = file_get_contents("http://box.zhangmen.baidu" .".com/x?op=12&count=1&title=".$Song."$$".$Singer."$$$$"); //simplexml_load_string() 函数把 XML 字符串载入对象中 $xml = simplexml_load_string($file, 'SimpleXMLElement', LIBXML_NOCDATA); //如果count大于0,表示找到歌曲 if ($xml->count > 0) { //普通品质音乐 $encode_str = $xml->url->encode; //使用正则表达式,进行字符串匹配,处理网址 preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_str, $matches); //第一个匹配的就是我们需要的字符串 $url_parse = $matches[0]; $decode_str = $xml->url->decode; //分离字符串,截去mid $decode_arr = explode('&', $decode_str); //拼接字符串,获得普通品质音乐 $musicUrl = $url_parse.$decode_arr[0]; //高品质音乐 $encode_dstr = $xml->durl->encode; preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_dstr, $matches_d); //第一个匹配的就是我们需要的字符串 $durl_parse = $matches_d[0]; $decode_dstr = $xml->durl->decode; //分离字符串,截去mid $decode_darr = explode('&', $decode_dstr); //拼接字符串,获得高品质音乐 $musicDurl = $durl_parse.$decode_darr[0]; //将两个链接放入数组中 $music = array( 'url' => $musicUrl, 'durl' => $musicDurl ); return $music; } return $music; } else { $music = ""; return $music; } } </span>
重点解释下preg_match这条语句
preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_str, $matches);
preg_match执行一个正则表达式匹配,原型如下:
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
subject
与pattern
的一个匹配。结果保存在array $matches中。第一个括号匹配的结果为http://zhangmenshiting.baidu.com
- \/表示/
- (\w+\/)表示匹配 ’music/‘ 这样的字符串
- +表示匹配前面的子表达式一次或多次
第二个括号匹配结果为/data2/music/64380827/
这两段字符串连起来就是所需要的字符串,保存在$matches中
在处理文本消息函数中,调用
<span> /* 点歌,百度API */ $str_music = mb_substr($keyword, 0, 1, "UTF-8"); $str_explode = mb_substr($keyword, 1, 20, "UTF-8"); $req_music = explode('#|#', $str_explode); //$song = mb_substr($keyword, 1, 220, "UTF-8"); $song = $req_music[0]; $singer = $req_music[1]; if ($str_music == '#' || $str_music == '#') { if ($str_valid == '#' || $str_valid == '#') { $contentStr = "输入格式不正确哦". "点歌请输入:#+歌名 或者 #+歌名+#+歌手"; } else { $url_arr = $apiFunc->baiduMusic($song, $singer); if (empty($url_arr)) { $contentStr = "非常抱歉哦,小和尚". "没有找到这首歌,可以换一首嘛[微笑]"; } else { include("wx_tpl.php"); $resultStr = sprintf( $musicTpl, $object->FromUserName, $object->ToUserName, $song, $singer, $url_arr['url'], $url_arr['durl'] ); return $resultStr; } } } </span>
explode函数对字符串进行分隔,将分隔后结果保存在数组中,在将数组值赋给变量$Song、$Singer。
[1]青龙老贼:《微信公众平台入门到精通》Vol.11
[2] [042] 微信公众帐号开发教程第18篇-应用实例之音乐搜索
bsdcfp的专栏,请尊重他人的辛勤劳动成果,谢谢!