Initial commit
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled

This commit is contained in:
chorblack
2026-03-07 11:19:25 +08:00
commit e75f275ef4
4484 changed files with 645480 additions and 0 deletions

72
XiaMiPlayer/Action.php Normal file
View File

@@ -0,0 +1,72 @@
<?php
if(!defined('__TYPECHO_ROOT_DIR__'))exit;
class XiaMiPlayer_Action extends Typecho_Widget implements Widget_Interface_Do {
public function execute(){}
public function action(){
$this->on($this->request->isGet())->player();
}
private function player(){
$dir = Typecho_Widget::widget('Widget_Options')->pluginUrl;
error_reporting(0);
header('content-type: application/javascript');
if(!isset($_GET['songs'])) $_GET['songs'] = '';
$gets = explode(",", $_GET['songs']);
$songs = array();
foreach($gets as $get) {
$songs[] = strstr($get, '|') ? array_combine(array('url', 'name'), explode('|', $get)) : $get;
}
$cuz = '';
if (isset($_GET['setting'])) {
$gets = explode(',', $_GET['setting']);
$setting = array('background'=>'#'.$gets[0], 'border-bottom'=>'#'.$gets[1]);
$cuz = '
playbox.css('.json_encode($setting).');
$(".box", playbox).css('.json_encode($setting).');
$(".progress", playbox).css("background", "'.$setting['border-bottom'].'");';
}
$code = json_encode($songs);
echo
<<<EOF
(function($, songs) {
api = '$dir/XiaMiPlayer/ajax.php?type=songs&id=';
time = new Date().getTime();
document.write('<div id="'+time+'" class="xiamiplayer"><div class="box"><div class="progress"></div><div class="play"></div><div class="btn-play"></div><span></span></div><ul class="list"></ul></div>');
playbox = $('#'+time);
(function(playbox) {
songs.forEach(function(song, i) {
var li = $('<li></li>');
if(typeof song != 'object') {
li.attr('data-xiami', '1'),
li.attr('data-id', song);
$.getJSON(api+song, function(res) {
li.attr('data-url', res.listen_file),
li.attr('data-name', res.song_name),
li.attr('data-artist', res.artist_name),
li.attr('data-lyric', res.lyric),
li.text([res.song_name, res.artist_name].join(' - '));
if(i===0) {
console.log('Init music id '+song+' for playbox id #'+playbox.attr('id'));
XiaMiPlayerInit(li, playbox, false);
}
});
} else {
li.attr('data-xiami', '0'),
li.attr('data-url', song.url),
li.text(song.name);
if(i===0) XiaMiPlayerInit(li, playbox, false);
}
$('.list', playbox).append(li);
})
})(playbox);
if(songs.length <= 1)
$('.list', playbox).addClass('display');
$cuz
})(jQuery, $code);
EOF;
}
}

492
XiaMiPlayer/Plugin.php Normal file
View File

@@ -0,0 +1,492 @@
<?php
/**
* 虾米音乐播放器:虾米音乐搜索+引用
*
* @package XiaMiPlayer
* @author 公子
* @version 3.1.4
* @link https://imnerd.org
*/
class XiaMiPlayer_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static Function activate()
{
Helper::addRoute("XiaMiPlayer_Route","/XiaMiPlayer","XiaMiPlayer_Action",'action');
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('XiaMiPlayer_Plugin', 'Insert');
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('XiaMiPlayer_Plugin', 'Insert');
Typecho_Plugin::factory('Widget_Archive')->header = array('XiaMiPlayer_Plugin', 'header');
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('XiaMiPlayer_Plugin','ParseXiaMi');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){
Helper::removeRoute("XiaMiPlayer_Route");
}
/**
* 插件的实现方法
*
* @access public
* @return void
*/
public static function header()
{
$options = Helper::options();
if($options->plugin('XiaMiPlayer')->jquery) {
echo "<script type=\"text/javascript\" src=\"//lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js\"></script>";
}
?>
<link rel="stylesheet" type="text/css" href="<?php $options->pluginUrl('XiaMiPlayer/jplayer/XiaMiPlayer.css'); ?>" />
<script type="text/javascript" src="<?php $options->pluginUrl('XiaMiPlayer/jplayer/jquery.jplayer.min.js'); ?>"></script>
<?php
?>
<?php
}
/**
* 插件的实现方法
*
* @access public
* @return void
*/
public static function Insert()
{
$options = Helper::options();
$config = $options->plugin('XiaMiPlayer');
$box = Typecho_Common::url('XiaMiPlayer/jplayer/index.html', $options->pluginUrl);
$music = Typecho_Common::url('XiaMiPlayer',$options->index);
$ajax = $options->pluginUrl.'/XiaMiPlayer/ajax.php';
/* 播放器样式 */
switch($config->type) {
case 'blue':
$color = '37839e,2b5c70';
break;
case 'green':
$color = '74db89,55db74';
break;
case 'yellow':
$color = 'ffd863,de8d24';
break;
case 'red':
$color = 'd64e3c,b82a25';
break;
case 'purple':
$color = '8073c7,5c396e';
break;
case 'user':
$color = ($config->background && $config->border) ? ','.substr($config->background,1).'|'.substr($config->border,1) : '';
break;
default:
$color = '';
break;
}
?>
<link rel="stylesheet" type="text/css" href="<?php $options->pluginUrl('XiaMiPlayer/jplayer/XiaMiPlayer.css'); ?>" />
<link rel="stylesheet" type="text/css" href="<?php echo Typecho_Common::url('XiaMiPlayer/style.css' , $options->pluginUrl); ?>" />
<script type="text/javascript" src="<?php $options->pluginUrl('XiaMiPlayer/jplayer/jquery.jplayer.min.js'); ?>"></script>
<script type="text/javascript">
$(function() {
/* 判断是否为默认编辑器插入音乐按钮 */
if($('#wmd-button-row').length>0) {
$('#wmd-button-row').prepend('<li class="wmd-button" id="wmd-music-button" style="" title="插入音乐 Ctrl + Shift + M">♫</li>');
} else {
$('#text').before('<a href="javascript:void(0)" id="wmd-music-button" title="插入音乐 Ctrl + Shift + M">插入歌曲</a>');
}
/* 为编辑器按钮增加点击事件 */
$(document).on('click', '#wmd-music-button', function() {
$('body').append('<div id="searchPanel">'+
'<div class="wmd-prompt-background" style="height:'+$(document).height()+'px;width:'+$(document).width()+'px;"></div>'+
'<div class="wmd-prompt-dialog">'+
'<div>'+
'<ul id="tab" class="wmd-button-row">'+
'<li onclick="xm_search();" title="Ctrl + ←"><b>虾米搜索</b></li>'+
'<li onclick="xm_link();" title="Ctrl + →"><b>输入链接</b></li>'+
'<li class="multi" data="0" onclick="multi();">[列表]</li>'+
'</ul>'+
'<div class=\"close\" onclick=\"rm();\" title="Esc">×</div>'+
'</div>'+
'<form id="xm"></form>'+
'</div>'+
'</div>');
xm_search();
});
/* 增加各种快捷键操作 */
$(document).on('keydown', function(e){
/* Ctrl+Shift+M 调出音乐搜索窗口 */
if(e.ctrlKey && e.shiftKey && e.keyCode == '77')
$('#wmd-music-button').click();
/* ESC 退出音乐搜索窗口 */
if(($('#searchPanel').length != 0) && e.keyCode == '27')
rm();
/* Ctrl+Enter 执行搜索操作 */
if($('#xiami_search').is(':focus') && $('#xiami_search').val() != '' && e.ctrlKey && e.keyCode == '13') {
$('#xiami_navi').attr('page','1');
search();
}
/* Ctrl+Pagedown 下一页 */
if(e.ctrlKey && e.keyCode == '40') {
next();
e.preventDefault();
}
/*Ctrl+Pageup 上一页 */
if(e.ctrlKey && e.keyCode == '38') {
pre();
e.preventDefault();
}
/*Ctrl+Left 调出虾米搜索窗口 */
if(e.ctrlKey && e.keyCode == '37') {
xm_search();
e.preventDefault();
}
/*Ctrl+Right 调出直链窗口 */
if(e.ctrlKey && e.keyCode == '39') {
xm_link();
e.preventDefault();
}
/*Ctrl+[1-8] 使用数字键快捷选择歌曲 */
for(var i=1;i<9;i++) {
var result = $('#xiami_result a');
if(($('#searchPanel').length != 0) && result[i-1] != null && parseInt(e.keyCode) == 48+i) {
$(result[i-1]).click();
$('#text').focus();
e.preventDefault();
}
}
})
});
function multi() {
var multi = $('.multi');
if(multi.hasClass('checked')){
multi.removeClass('checked');
multi.attr('data', '0');
$('.multibtn').remove();
$('#playlist').remove();
} else {
multi.addClass('checked');
multi.attr('data', '1');
multi.after('<button class="multibtn" onclick="multishow()">确定</button>');
$('#tab').after('<ul id="playlist"></ul>');
}
}
function multishow() {
var list = $('#playlist li');
if(list.length == 0) return false;
var ids = [].slice.call(list).map(function(item) {
return item.getAttribute('data-url') ? item.getAttribute('data-url')+'|'+item.innerHTML : item.getAttribute('data-id');
});
var c = '<script type="text/javascript" src="<?php echo $music; ?>?songs='+ids.join(',')+'<?php if($color) echo "&setting=$color"; ?>"><\/script>';
$('#text').val($('#text').val() + c);
editor(c);
rm();
}
function xm_search() {
$('#xm').html('<form>'+
'<input type=\"text\" id=\"xiami_search\" autocomplete=\"off\">'+
'<input type=\"hidden\" id=\"xiami_page\" value=\"1\">'+
'<div class="btn-s primary" onclick=\"$(\'#xiami_navi\').attr(\'page\',\'1\');search();\" style="float:right;padding:0 12px;line-height:28px;" title="Ctrl + Enter">搜索</div>'+
'</form>'+
'<br style="clear:both;" />'+
'<div id=\"xiami_list\">'+
'<div id=\"xiami_result\"></div>'+
'<div id=\"xiami_navi\" page="1">'+
'<a href="#" class="pre" onclick="pre();" title="Ctrl+↑" style="display:inline-table;border:none;float:left;"></a>'+
'<a href="#" class="next" onclick="next();" title="Ctrl+↓" style="display:inline-table;border:none;float:right;"></a>'+
'</div>');
$('#xiami_search').focus();
}
function xm_link() {
$('#xm').html('<p style="margin-bottom:15px;">输入歌曲名称和歌曲直链地址,其中歌曲名称选填。</p>'+
'<p><input type=\"text\" id=\"song_name\" placeholder="歌曲名称"></p>'+
'<p><input type=\"text\" id=\"song_link\" placeholder="歌曲地址"></p>'+
'<button class="btn-s primary" onclick=\"insert_link();return false;\">插入</button>');
$('#song_name').focus();
}
function pre() {
var n = $('#xiami_navi'), p = Number(n.attr('page'))-1;
if(p == 1) $('.pre').html('');
n.attr('page', p);
search();
}
function next() {
var n = $('#xiami_navi'), p = Number(n.attr('page'))+1;
n.attr('page', p);
search();
}
function search() {
var k = $('#xiami_search').val(), p = Number($('#xiami_navi').attr('page'));
$('.pre').html('上一页');
$('.next').html('下一页');
if(k) {
$('#xiami_result').html('正在载入请稍后...');
$.getJSON('<?php echo $ajax; ?>?type=search&id='+k+'&page='+p,function(data) {
$('#xiami_result').html('');
$.each(data.songs,
function(i, item) {
var name = decodeURIComponent(item.song_name).replace('+', ' '), artist = decodeURIComponent(item.artist_name).split('+').join(' ');
$('<a href=\"#\" onclick=\"show(\'' + item.song_id + '\',\'' + name.replace('\'', '\\\'').replace(/(\r)?\n/g, '') + '-' + artist.replace('\'', '\\\'').replace(/(\r)?\n/g, '') + '\');\" title=\"Ctrl + '+(i+1)+'\">' + (i+1) + '. ' + name + ' - ' + artist + '</a>').appendTo('#xiami_result');
});
});
} else {
alert('请输入歌曲名称!')
}
}
function rm() {$('#searchPanel').remove()}
function show(id, name) {
if($('ul#playlist').size()>0) {
if($('ul#playlist li[data-id="'+id+'"]').size()>0)
alert('《'+name+'》已经被添加到列表中了!');
else
$('ul#playlist').append('<li data-id="'+id+'">'+name+'</li>');
} else {
var c = '[xiami <?php echo $music; ?>?songs='+id+'<?php if($color) echo "&setting=$color"; ?>]';
editor(c);
rm();
}
}
function insert_link() {
if($('#song_link').val()=='') return alert('必须输入音乐链接');
var name = $('#song_name').val(), link = $('#song_link').val();
if($('ul#playlist').size()>0) {
if($('ul#playlist li[data-url="'+link+'"]').size()>0)
alert('《'+name+'》已经被添加到列表中了!');
else
$('ul#playlist').append('<li data-url="'+link+'">'+name+'</li>');
} else {
var c = '[xiami <?php echo $music; ?>?songs='+link+'|'+name+'<?php if($color) echo "&setting=$color"; ?>]';
editor(c);
rm();
}
}
function editor(c) {
var textarea = $('#text'),
sel = textarea.getSelection(),
offset = (sel ? sel.start : 0)+c.length;
textarea.replaceSelection(c);
textarea.setSelection(offset,offset);
if (window.frames.length > 0) {
if (fck = window.frames['text___Frame'])
var _c = fck.document.getElementsByTagName('iframe')[0].contentDocument.body;
else if (mce = window.frames['text_ifr'])
var _c = mce.document.body;
else if (kin = document.getElementsByClassName('ke-edit-iframe')[0])
var _c = kin.contentDocument.body;
else if (cke = document.getElementsByClassName('cke_wysiwyg_frame')[0])
var _c = cke.contentDocument.body;
_c.innerHTML = _c.innerHTML + c;
}
}
$(document).on('mousedown', '#playlist', function(e) {
document.onselectstart = function(){return false;}
$('body').addClass('select');
var ul = $(this), li = $('#playlist li'),limit = {
up:parseInt(ul.offset().top),
down:parseInt(li.last().offset().top),
left:parseInt(ul.offset().left),
right:parseInt(ul.offset().left)+ul.width()
},height = [],parent=parseInt(ul.offsetParent().offset().top);
for(var i=0,l=li.length;i<l;i++) height.push(li[i].offsetTop+parent);
var t = $(e.target), s = $(document.createElement('li'));
s.addClass('sortable');
$('.sortable').remove(), t.before(s);
t.addClass('hover');
$(document).on('mousemove', function(e) {
var top = e.pageY;
if(top<limit.up) {
//top = limit.up;
ul.prepend(s);
} else if (top>limit.down) {
//top = limit.down;
ul.append(s);
} else {
t.css({'top':(top-ul.offsetParent().offset().top)+'px','left':(e.pageX-ul.offsetParent().offset().left)+'px'});
var f = $(li[getIndex(top)]);
if(!$(f.siblings()[0]).hasClass('sortable')) f.before(s);
}
});
$(document).on('mouseup', function(e) {
$(document).off('mouseup');
$(document).off('mousemove');
document.onselectstart = function(){return true;}
$('body').removeClass('select');
var left = e.pageX;
left>limit.right || left<limit.left ? t.remove() : s.before(t);
s.remove();
t.removeClass('hover');
});
function getIndex(y) {
var i=0;
height.forEach(function(value, index){
if(y >= value){i=index+1;return true;}
});
return i;
}
});
</script>
<?php
}
/**
* 解析文章中出现的专辑和精选集链接
*
* @access public
* @return 文章内容 $content
*/
public static function ParseXiaMi($content, $widget, $lastResult) {
$content = empty($lastResult) ? $content : $lastResult;
/* 播放器样式 */
$options = Helper::options();
$url = Typecho_Common::url('XiaMiPlayer',$options->index);
$ajax = $options->pluginUrl.'/XiaMiPlayer/ajax.php';
$config = $options->plugin('XiaMiPlayer');
switch($config->type) {
case 'blue':
$color = '37839e,2b5c70';
break;
case 'green':
$color = '74db89,55db74';
break;
case 'yellow':
$color = 'ffd863,de8d24';
break;
case 'red':
$color = 'd64e3c,b82a25';
break;
case 'purple':
$color = '8073c7,5c396e';
break;
case 'user':
$color = ($config->background && $config->border) ? ','.substr($config->background,1).'|'.substr($config->border,1) : '';
break;
default:
$color = '';
break;
}
/** 短代码替换 **/
$number = preg_match_all('/\[xiami (.*?)\]/si', $content, $match);
if($number) {foreach($match[0] as $key => $string) {
$content = str_replace($string, '<script type="text/javascript" src="'.strip_tags($match[1][$key]).'"></script>', $content);
}}
/** Markdown替换 **/
$number = preg_match_all("/<a href=\"(https:\/\/(www.)?xiami\.com\/([a-z]+)\/([a-zA-Z0-9]+))\">\\1<\/a>/im", $content, $match);
if($number) {foreach($match[0] as $key => $string) {
$type = $match[3][$key]=='song' ? 'songs' : $match[3][$key];
$id = $match[4][$key];
$result = json_decode(file_get_contents($ajax.'?type='.$type.'&id='.$id), true);
if(in_array($type, array("album", "collect"))) {
if(empty($result['songs'])) continue;
$songs = array();
foreach($result['songs'] as $song) $songs[] = $song['song_id'];
$lurl = $url."?songs=".implode(',', $songs);
if($color) $lurl .= "&setting=$color";
$content = str_replace($string, '<script type="text/javascript" src="'.$lurl.'"></script>', $content);
} else {
if(!$result['song_id']) continue;
$surl = $url."?songs=".$result['song_id'];
if($color) $surl .= "&setting=$color";
$content = str_replace($string, '<script type="text/javascript" src="'.$surl.'"></script>', $content);
}
}}
/** 非Markdown替换 **/
$number = preg_match_all("/https:\/\/(www.)?xiami\.com\/([a-z]+)\/([a-zA-Z0-9]+)/im", $content, $match);
if($number) {foreach($match[0] as $key => $string) {
$type = $match[2][$key]=='song' ? 'songs' : $match[2][$key];
$id = $match[3][$key];
$result = json_decode(file_get_contents($ajax.'?type='.$type.'&id='.$id), true);
if(in_array($type, array("album", "collect"))) {
if(empty($result['songs'])) continue;
$songs = array();
foreach($result['songs'] as $song) $songs[] = $song['song_id'];
$lurl = $url."?songs=".implode(',', $songs);
if($color) $lurl .= "&setting=$color";
$content = str_replace($string, '<script type="text/javascript" src="'.$lurl.'"></script>', $content);
} else {
if(!$result['song_id']) continue;
$surl = $url."?songs=".$result['song_id'];
if($color) $surl .= "&setting=$color";
$content = str_replace($string, '<script type="text/javascript" src="'.$surl.'"></script>', $content);
}
}}
return $content;
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$jquery = new Typecho_Widget_Helper_Form_Element_Radio('jquery', array('0' => _t('不加载'), '1' => _t('加载')), '1', _t('是否加载外部jQuery库文件'), _t('插件需要jQuery库文件的支持如果主题已经加载了可以选择不加载'));
$form->addInput($jquery);
$color = array('orange' => _t('默认橙'),'blue' => _t('天空蓝'),'green' => _t('自然绿'),'yellow' => _t('大地黄'),'red' => _t('高原红'),'purple' => _t('葡萄紫'),'user' => _t('自定义'));
$type = new Typecho_Widget_Helper_Form_Element_Radio('type', $color,'orange',_t('请选择播放器样式'));
$form->addInput($type);
$background = new Typecho_Widget_Helper_Form_Element_Text('background', NULL, '#FF6503', _t('播放器背景'), NULL);
$background->input->setAttribute('class', 'mini');
$form->addInput($background);
$border = new Typecho_Widget_Helper_Form_Element_Text('border', NULL, '#C4753D', _t('播放器边框'), NULL);
$border->input->setAttribute('class', 'mini');
$form->addInput($border);
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
}

15
XiaMiPlayer/README.md Normal file
View File

@@ -0,0 +1,15 @@
### 迷你版虾米点播插件XiaMiPlayer v3.1.4
通过编辑器按钮在线搜索虾米歌曲或输入mp3链接组成列表插入文章采用jplayer迷你多彩播放器支持快捷键。
:warning:由于原服务端lyric.php缺失暂时无法显示歌词。
- v3.1.4(18-7-25)[@羽中](https://github.com/jzwalk)
使用短代码替换兼容Typecho1.1+版Markdown解析修正虾米地址自动替换和编辑区焦点定位等问题。
- v3.1.3复活版(17-2-16)
整合[XiamiMusicAPI](https://github.com/metowolf/XiamiMusicAPI)内置action调用核心功能。
- 补更至v3.1.2。
###### 更多详见作者博客http://imnerd.org/XiaMiPlayer-Plugin-for-typecho-0-9.html

View File

@@ -0,0 +1,96 @@
<?php
/*!
* Xiami Music Api
* https://i-meto.com
* Version 0.1.0 beta
*
* Copyright 2016, METO
* Released under the MIT license
*/
class XiamiMusicAPI{
// General
protected $_USERAGENT='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36';
protected $_COOKIE='user_from=2;XMPLAYER_addSongsToggler=0;XMPLAYER_isOpen=0;_xiamitoken=cb8bfadfe130abdbf5e2282c30f0b39a;';
protected $_REFERER='http://h.xiami.com/';
// CURL
protected function curl($url,$data=null){
$curl=curl_init();
curl_setopt($curl,CURLOPT_URL,$url);
if($data){
if(is_array($data))$data=http_build_query($data);
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
curl_setopt($curl,CURLOPT_POST,1);
}
curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl,CURLOPT_REFERER,$this->_REFERER);
curl_setopt($curl,CURLOPT_COOKIE,$this->_COOKIE);
curl_setopt($curl,CURLOPT_USERAGENT,$this->_USERAGENT);
$result=curl_exec($curl);
curl_close($curl);
return $result;
}
// main function
public function search($s,$limit=30,$offset=0,$type=1){
$url='http://api.xiami.com/web?';
$data=array(
'v'=>'2.0',
'app_key'=>'1',
'key'=>$s,
'page'=>($offset+1),
'limit'=>$limit,
'r'=>'search/songs',
);
return $this->curl($url.http_build_query($data));
}
public function artist($artist_id){
$url='http://api.xiami.com/web?';
$data=array(
'v'=>'2.0',
'app_key'=>'1',
'id'=>$artist_id,
'page'=>1,
'limit'=>30,
'r'=>'artist/hot-songs',
);
return $this->curl($url.http_build_query($data));
}
public function album($album_id){
$url='http://api.xiami.com/web?';
$data=array(
'v'=>'2.0',
'app_key'=>'1',
'id'=>$album_id,
'r'=>'album/detail',
);
return $this->curl($url.http_build_query($data));
}
public function detail($song_id){
$url='http://api.xiami.com/web?';
$data=array(
'v'=>'2.0',
'app_key'=>'1',
'id'=>$song_id,
'r'=>'song/detail',
);
return $this->curl($url.http_build_query($data));
}
public function url($song_id){
$url='http://www.xiami.com/song/playlist/id/'.$song_id.'/object_name/default/object_id/0/cat/json';
return $this->curl($url);
}
public function playlist($playlist_id){
$url='http://api.xiami.com/web?';
$data=array(
'v'=>'2.0',
'app_key'=>'1',
'id'=>$playlist_id,
'r'=>'collect/detail',
);
return $this->curl($url.http_build_query($data));
}
public function lyric($song_id){
// Todo
return "...";
}
}

36
XiaMiPlayer/ajax.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
require dirname(__FILE__) . '/XiamiMusicAPI.php';
if(!isset($api)){
$api = new XiamiMusicAPI();
}
$type = $_GET['type'];
$id = $_GET['id'];
$page = isset($_GET['page']) ? ($_GET['page'])-1 : 0;
switch ($type) {
case 'songs' :
$data=json_decode($api->detail($id));
$data = $data ? $data->data->song : null;
break;
case 'album':
$data=json_decode($api->album($id));
$data = $data ? $data->data : null;
break;
case 'collect':
$data=json_decode($api->playlist($id));
$data = $data ? $data->data : null;
break;
case 'search':
$data=json_decode($api->search($id,5,$page));
$data = $data ? $data->data : null;
break;
}
header('Content-type: application/json; charset=UTF-8');
echo json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit;

Binary file not shown.

View File

@@ -0,0 +1 @@
.xiamiplayer{cursor:pointer;text-decoration:none;font:12px/1.2 "Helvetica Neue",Helvetica,Arial,sans-serif;overflow:hidden;width:280px;border-radius:3px;}.xiamiplayer,.xiamiplayer .box{background-color:#FF6503;}.xiamiplayer,.xiamiplayer .box{border-bottom:#C4753D 1px solid;}.xiamiplayer .box{display:block;height:30px;white-space:nowrap;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,.2);font-size:14px}.xiamiplayer .box span{float:left;margin-left:10px;line-height:30px;width:240px;overflow:hidden;text-align:left}.xiamiplayer .btn-play{width:0;height:0;border:10px solid transparent;border-left:15px solid #FFF;float:right;margin-top:5px}.xiamiplayer .btn-pause{width:5px;height:20px;border-left:5px solid #FFF;border-right:5px solid #FFF;float:right;margin-top:5px;margin-right:10px}.xiamiplayer .progress{height:30px;background:#C4753D;position:absolute;opacity:0.5;-moz-opacity:0.5;filter:alpha(opacity = 50)}.xiamiplayer .list{padding:0 3px;margin:0;list-style-type:none;}.xiamiplayer .list li{color:#FFF;font-size:14px;line-height:16px;padding:5px 8px;border-bottom:1px solid #FFF;}.xiamiplayer .list li:last-child{border-bottom:none;}.xiamiplayer .display{display:none;}

View File

@@ -0,0 +1,194 @@
<!DOCTYPE HTML>
<html>
<head>
<title>
</title>
<meta charset="UTF-8" />
<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js">
</script>
<script type="text/javascript" src="jquery.jplayer.min.js">
</script>
<style type="text/css">
body {
margin: 0;
padding: 0
}
div.openyy {
cursor: pointer;
text-decoration: none;
font: 12px/1.2 "Helvetica Neue",Helvetica,Arial,sans-serif;
overflow: hidden;
display: block;
width: 250px;
height: 30px;
line-height: 30px;
white-space: nowrap;
background-color: #FF6503;
color: #fff;
border-bottom: #C4753D 1px solid;
text-align: center;
border-radius: 3px;
text-shadow: 0-1px 0 rgba(0, 0, 0, .2);
font-size: 14px
}
.openyy span {
float: left;
margin-left: 10px;
width: 210px;
overflow: hidden;
text-align: left
}
#play {
width: 0;
height: 0;
border:10px solid transparent;
border-left: 15px solid #FFF;
float: right;
margin-top: 5px
}
#pause {
width: 5px;
height: 20px;
border-left: 5px solid #FFF;
border-right: 5px solid #FFF;
float: right;
margin-top: 5px;
margin-right: 10px
}
#progress {
height: 30px;
background: #FF8F00;
position: absolute;
opacity: 0.5;-moz-opacity: 0.5;
filter: alpha(opacity = 50)
}
</style>
<script type="text/javascript">
$(function() {
var hash = location.hash.split('|');
if (hash.length == 3) {
var background = '#' + hash[1],
border = '#' + hash[2]
} else {
var background = '#' + hash[2],
border = '#' + hash[3]
}
$('.openyy').css({
'background': background,
'border-bottom-color': border
});
$('#progress').css({
'background': border
});
var song = hash[0].substr(1);
if (song.substring(0, 7) == "http://") {
var songs = new Array(hash[0].substr(1), hash[1]),
format = songs[0].split('.').pop();
$('#jplayer').jPlayer({
ready: function() {
switch (format) {
case 'wma':
$(this).jPlayer('setMedia', {
wma: songs[0]
});
break;
case 'ogg':
$(this).jPlayer('setMedia', {
ogg: songs[0]
});
break;
case 'ape':
$(this).jPlayer('setMedia', {
ape: songs[0]
});
break;
default:
$(this).jPlayer('setMedia', {
mp3: songs[0]
});
break
}
$('title').html(songs[1]);
$('.openyy span').html(songs[1])
},
preload: 'none',
ended: function() {
$('#pause').click();
$('#progress').width('0px')
},
swfPath: './',
supplied: 'mp3,wma,ogg,ape'
})
} else {
$.ajax({
url: 'http://imnerd.org/lab/player/apiv2.php?id=' + song,
type: 'GET',
dataType: 'jsonp',
async: false,
success: function(d) {
$('#jplayer').jPlayer({
ready: function() {
$(this).jPlayer('setMedia', {
mp3: d.location
});
$('title').html(d.title);
$('.openyy span').html(d.title);
$.ajax({
url: 'http://imnerd.org/lab/search/lyric.php?url=' + d.lyric,
type: 'GET',
dataType: 'jsonp',
async: false,
success: function(lrc) {
var m = 0;
$('#jplayer').bind($.jPlayer.event.timeupdate,
function(e) {
if (e.jPlayer.status.currentTime > lrc[m][0]) $('.openyy span').html(lrc[m][1]),
m++
})
}
})
},
ended: function() {
$('#pause').click();
$('#progress').width('0px')
},
preload: 'none',
swfPath: './',
supplied: 'mp3'
})
}
})
}
$('#jplayer').bind($.jPlayer.event.timeupdate,
function(e) {
$('#progress').width(Math.round(e.jPlayer.status.currentPercentAbsolute / 100 * $('.openyy span').width()))
});
$('body').on('click', '#play',
function() {
$('#jplayer').jPlayer('play');
$(this).attr('id', 'pause')
});
$('body').on('click', '#pause',
function() {
$('#jplayer').jPlayer('pause');
$(this).attr('id', 'play')
})
});
</script>
</head>
<body>
<div class="openyy">
<div id="progress">
</div>
<div id="jplayer">
</div>
<span>
</span>
<div id="play"></div>
</div>
</body>
</html>

3101
XiaMiPlayer/jplayer/jquery.jplayer.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

134
XiaMiPlayer/style.css Normal file
View File

@@ -0,0 +1,134 @@
.wmd-button#wmd-music-button {
font-size: 20px;
text-align: center;
color: #AAA;
width: 20px;
float: left;
}
.wmd-prompt-background {
position: absolute;
top: 0px;
z-index: 1000;
opacity: 0.5;
left: 0px
}
input#xiami_search {
width: 270px;
height: 28px;
float: left
}
#searchPanel .wmd-prompt-dialog{
position:absolute;
}
#searchPanel form {
padding: 6px
}
#DoSearch {
-moz-box-shadow: inset 0px 1px 0px 0px #ffffff;
-webkit-box-shadow: inset 0px 1px 0px 0px #ffffff;
box-shadow: inset 0px 1px 0px 0px #ffffff;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ededed), color-stop(1, #dfdfdf));
background: -moz-linear-gradient(center top, #ededed 5 % , #dfdfdf 100 % );
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr = '#ededed', endColorstr = '#dfdfdf');
background-color: #ededed;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
border: 1px solid#dcdcdc;
display: inline-block;
color: #777777;
font-family: arial;
font-size: 15px;
font-weight: normal;
padding: 10px 15px;
margin-left: 10px;
text-decoration: none;
text-shadow: 1px 1px 0px#ffffff
}
#DoSearch:hover {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0.05, #dfdfdf), color-stop(1, #ededed));
background: -moz-linear-gradient(center top, #dfdfdf 5 % , #ededed 100 % );
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr = '#dfdfdf', endColorstr = '#ededed');
background-color: #dfdfdf;
cursor: pointer
}
#DoSearch:active {
position: relative;
top: 1px
}
#searchPanel .close {
position: absolute;
top: 6px;
right: 6px;
cursor: pointer;
display: block;
padding: 6px;
-moz-border-radius: 3px;
-khtml-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
color: #000;
width: 10px;
height: 10px;
text-align: center;
line-height: 10px;
font-size: 20px
}
#searchPanel #xiami_list a {
display: block;
padding: 6px;
border-bottom: 1px solid#ddd
}
ul#tab {
margin: 0px;
padding: 0px
}
#tab li: hover {
cursor: pointer;
background: #467b96;
color: #FFF
}
#tab .multi {
color:#DDD;
}
#tab .multi.checked {
color:#000;
font-weight:bold;
}
.select {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#playlist {
padding-left:25px;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#playlist li {
cursor:move;
box-sizing:border-box;
line-height:20px;
list-style-type:square;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#playlist .sortable {
border:1px dashed #AAA;
background:#DDD;
}
li.hover {
position:absolute;
list-style-type:none;
}