[1.0.3] 支持外文歌词翻译(网易云、QQ)

This commit is contained in:
metowolf 2017-02-06 19:38:18 +08:00
parent 9b0a1cfa3e
commit 471055083c
No known key found for this signature in database
GPG Key ID: 3D295741DC5DBCD0
3 changed files with 103 additions and 89 deletions

View File

@ -7,7 +7,7 @@ class Meting_Action extends Typecho_Widget implements Widget_Interface_Do {
public function execute(){}
public function action(){
$this->on($this->request->is('do=js'))->js();
$this->on($this->request->is('do=musicjs'))->musicjs();
$this->on($this->request->is('do=url'))->url();
$this->on($this->request->is('do=pic'))->pic();
$this->on($this->request->is('do=lrc'))->lrc();
@ -43,7 +43,6 @@ class Meting_Action extends Typecho_Widget implements Widget_Interface_Do {
elseif(preg_match('/album\/([^\.]*)/i',$url,$id))list($id,$type)=array($id[1],'album');
elseif(preg_match('/song\/([^\.]*)/i',$url,$id))list($id,$type)=array($id[1],'song');
elseif(preg_match('/artist\/([^\.]*)/i',$url,$id))list($id,$type)=array($id[1],'artist');
if(!preg_match('/^\d*$/i',$id,$t)){
$data=self::curl($url);
preg_match('/'.$type.'\/(\d+)/i',$data,$id);
@ -81,7 +80,7 @@ class Meting_Action extends Typecho_Widget implements Widget_Interface_Do {
return $result;
}
private function js(){
private function musicjs(){
self::filterReferer();
$PID=$this->request->get('id');
$data=$this->request->get('d');
@ -122,19 +121,19 @@ class Meting_Action extends Typecho_Widget implements Widget_Interface_Do {
$player['music']=json_encode($player['music']);
header('content-type:application/javascript');
echo"
var Meting{$PID} = new APlayer({
element: document.getElementById('MetingPlayer'+{$PID}),
autoplay: ".$player['autoplay'].",
preload: \"".$player['preload']."\",
showlrc: 3,
mutex: true,
mode: '".$player['mode']."',
theme: \"".$player['theme']."\",
music: ".$player['music'].",
listmaxheight: '".$player['height']."',
});
";
echo "
var Meting{$PID} = new APlayer({
element: document.getElementById('MetingPlayer'+{$PID}),
autoplay: ".$player['autoplay'].",
preload: \"".$player['preload']."\",
showlrc: 3,
mutex: true,
mode: '".$player['mode']."',
theme: \"".$player['theme']."\",
music: ".$player['music'].",
listmaxheight: '".$player['height']."',
});
";
}
private function url(){
@ -181,11 +180,28 @@ var Meting{$PID} = new APlayer({
$data=json_decode($data,1);
self::cacheWrite($cachekey,$data);
}
$text=$data['lyric'];
if(!empty($data['tlyric']))$text=$this->lrctran($data['lyric'],$data['tlyric']);
else $text=$data['lyric'];
if(strlen($text)==0)$text='[00:00.00]无歌词';
echo $text;
}
private function lrctran($lyric,$tlyric){
preg_match_all('/\[(\d{2}:\d{2}\.\d+)\]([^\n]+)/i',$lyric,$t1);
preg_match_all('/\[(\d{2}:\d{2}\.\d+)\]([^\n]+)/i',$tlyric,$t2);
$from=$to=$t1[0];
$len=sizeof($t1[0]);
for($i=0,$j=0;$i<$len;$i++){
while($t1[1][$i]>$t2[1][$j]&&$j+1<$len)$j++;
if($t1[1][$i]==$t2[1][$j]){
$t=trim(str_replace('/','',$t2[2][$j]));
if($t)$to[$i].=" (".$t2[2][$j].")";
$j++;
}
}
return str_replace($from,$to,$lyric);
}
private function cacheWrite($k,$v){
if(!is_array($v))return;
$db=Typecho_Db::get();

View File

@ -103,11 +103,9 @@ class Meting_Plugin extends Typecho_Widget implements Typecho_Plugin_Interface
public static function header(){
$dir=Helper::options()->pluginUrl.'/Meting/assets/';
$ver=METING_VERSION;
echo <<<EOF
<!-- Meting Start -->
<script type="text/javascript" src="{$dir}APlayer.min.js?v={$ver}"></script>
<!-- Meting End -->
EOF;
echo "<!-- Meting Start -->
<script type=\"text/javascript\" src=\"{$dir}APlayer.min.js?v={$ver}\"></script>
<!-- Meting End -->";
}
public static function footer(){}
@ -137,8 +135,12 @@ EOF;
$matches[5]=htmlspecialchars_decode($matches[5]);
$pattern=self::get_shortcode_regex(array('Music'));
preg_match_all("/$pattern/",$matches[5],$all);
if(sizeof($all[3]))return Meting_Plugin::parseMusic($all[3],$setting);
}
public static function parseMusic($matches,$setting){
$data=array();
foreach($all[3] as $vo){
foreach($matches as $vo){
$t=self::shortcode_parse_atts(htmlspecialchars_decode($vo));
if(!in_array($t['server'],array('netease','tencent','xiami','baidu','kugou')))continue;
if(!in_array($t['type'],array('search','album','playlist','artist','song')))continue;
@ -147,76 +149,15 @@ EOF;
$id=self::getPID();
$dir=Typecho_Common::url('MetingAPI',Helper::options()->index);
$data=base64_encode(json_encode($data));
return <<<EOF
<div id="MetingPlayer{$id}" class="aplayer" /></div>
<script type="text/javascript" src="{$dir}?do=js&s={$setting}&d={$data}&id={$id}" async defer></script>
EOF;
return "<div id=\"MetingPlayer{$id}\" class=\"aplayer\" /></div>
<script type=\"text/javascript\" src=\"{$dir}?do=musicjs&s={$setting}&d={$data}&id={$id}\" async defer></script>";
}
public static function addButton(){
$url=Typecho_Common::url('MetingAPI?do=parse',Helper::options()->index);
echo <<<EOF
<script type="text/javascript">
$(function() {
if($('#wmd-button-row').length>0)$('#wmd-button-row').append('<li class="wmd-spacer wmd-spacer1" id="wmd-spacer5"></li><li class="wmd-button" id="wmd-music-button" style="" title="插入音乐"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABBVBMVEUAAADS1NVVVVVKS0pWVldZWVpJSkrHyctlZmaxs7RlZmZgYWFfX1/GyMrLzc7P0dJiY2PO0NJaWlqWmJpYV1dVVVXQ09TIystJSkpXV1fMzs9QUFCYmpxVVla3ubmoqqqdnp+jpaaSlJZqamtmZmbP0dLCxMbBw8TLzc65vL1VV1dSU1PBw8XFx8nR09SOkJKipaeho6RjZWW7vL2ys7SusLHGyMpZWVp4eHisrrBqamrCxMapq6yusLJ5enrP0tNtbm+ipafGyMpJSkqmp6iZmptXV1dZWVnJy8zS1NWmqKrLzc7R09TFx8m3ubuqrK6hpKWcnqCVlpeXmZuSk5SDhIWDg4QW1XxpAAAATXRSTlMABEgFAvxPFv79+vrGsrGurpKNaFlOTTQ0MyMc/v367e3p6OPizczMyLetrKeemYSDg4F/fn59fXt5eW5ubGtpZ2BdTEI+NzYrKBYMC1kKAkAAAAC1SURBVBjTRY7VEoMwEEWh7sUKFOru7u6OVv7/U7oh7bAPOblnktlL/IYkMfE8eDoSofn7P1+jKfP9efnDF5ylipFnOI4pmGXJ+t1Kh87oEg9lmiRQKB5k/FQ+lgTAOmovaMzhGPQJpwsll5OYdoGzFVsTkRDr7GYMnGR1tweJfTKR6wGHioaFw/3U28CRogaxCBp6B7hT1EDMEgFN2wK9YdWHhc9fvRHILKmT1ZRaeHEduwfMF0K7E1YSv1vLAAAAAElFTkSuQmCC"/></li>');
$(document).on('click', '#wmd-music-button', function() {
$('body').append(
'<div id="MetingPanel">'+
'<div class="wmd-prompt-background" style="position: absolute; top: 0px; z-index: 1000; opacity: 0.5; height: 875px; left: 0px; width: 100%;"></div>'+
'<div class="wmd-prompt-dialog">'+
'<div>'+
'<p><b>插入音乐</b></p>'+
'<p>请在下方的输入框内输入要插入的音乐地址,如多个地址请用回车隔开'+
'<p><textarea type="text" rows="5" cols="40"></textarea></p>'+
'</div>'+
'<form>'+
'<button type="button" class="btn btn-s primary" id="ok">确定</button>'+
'<button type="button" class="btn btn-s" id="cancel">取消</button>'+
'</form>'+
'</div>'+
'</div>');
$('.wmd-prompt-dialog textarea').val('http://').select();
});
$(document).on('click','#cancel',function() {
$('#MetingPanel').remove();
$('textarea').focus();
});
$(document).on('click','#ok',function() {
callback=$.ajax({
type:'POST',
url:"{$url}",
data:{data:$('.wmd-prompt-dialog textarea').val()},
async:false
});
$('#MetingPanel').remove();
myField = document.getElementById('text');
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = callback.responseText;
myField.focus();
}
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
var cursorPos = startPos;
myField.value = myField.value.substring(0, startPos)
+ callback.responseText
+ myField.value.substring(endPos, myField.value.length);
cursorPos += callback.responseText.length;
myField.focus();
myField.selectionStart = cursorPos;
myField.selectionEnd = cursorPos;
}
else{
myField.value += callback.responseText;
myField.focus();
}
});
});
</script>
EOF;
$dir=Helper::options()->pluginUrl.'/Meting/assets/editer.js?v='.METING_VERSION;
echo "<script type=\"text/javascript\">var murl='{$url}';</script>
<script type=\"text/javascript\" src=\"{$dir}\"></script>";
}
# https://github.com/WordPress/WordPress/blob/master/wp-includes/shortcodes.php#L508

57
assets/editer.js Normal file
View File

@ -0,0 +1,57 @@
$(function() {
if($('#wmd-button-row').length>0)$('#wmd-button-row').append('<li class="wmd-spacer wmd-spacer1" id="wmd-spacer5"></li><li class="wmd-button" id="wmd-music-button" style="" title="插入音乐"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABBVBMVEUAAADS1NVVVVVKS0pWVldZWVpJSkrHyctlZmaxs7RlZmZgYWFfX1/GyMrLzc7P0dJiY2PO0NJaWlqWmJpYV1dVVVXQ09TIystJSkpXV1fMzs9QUFCYmpxVVla3ubmoqqqdnp+jpaaSlJZqamtmZmbP0dLCxMbBw8TLzc65vL1VV1dSU1PBw8XFx8nR09SOkJKipaeho6RjZWW7vL2ys7SusLHGyMpZWVp4eHisrrBqamrCxMapq6yusLJ5enrP0tNtbm+ipafGyMpJSkqmp6iZmptXV1dZWVnJy8zS1NWmqKrLzc7R09TFx8m3ubuqrK6hpKWcnqCVlpeXmZuSk5SDhIWDg4QW1XxpAAAATXRSTlMABEgFAvxPFv79+vrGsrGurpKNaFlOTTQ0MyMc/v367e3p6OPizczMyLetrKeemYSDg4F/fn59fXt5eW5ubGtpZ2BdTEI+NzYrKBYMC1kKAkAAAAC1SURBVBjTRY7VEoMwEEWh7sUKFOru7u6OVv7/U7oh7bAPOblnktlL/IYkMfE8eDoSofn7P1+jKfP9efnDF5ylipFnOI4pmGXJ+t1Kh87oEg9lmiRQKB5k/FQ+lgTAOmovaMzhGPQJpwsll5OYdoGzFVsTkRDr7GYMnGR1tweJfTKR6wGHioaFw/3U28CRogaxCBp6B7hT1EDMEgFN2wK9YdWHhc9fvRHILKmT1ZRaeHEduwfMF0K7E1YSv1vLAAAAAElFTkSuQmCC"/></li>');
$(document).on('click', '#wmd-music-button', function() {
$('body').append(
'<div id="MetingPanel">'+
'<div class="wmd-prompt-background" style="position: absolute; top: 0px; z-index: 1000; opacity: 0.5; height: 875px; left: 0px; width: 100%;"></div>'+
'<div class="wmd-prompt-dialog">'+
'<div>'+
'<p><b>插入音乐</b></p>'+
'<p>请在下方的输入框内输入要插入的音乐地址,如多个地址请用回车隔开'+
'<p><textarea type="text" rows="5" cols="40"></textarea></p>'+
'</div>'+
'<form>'+
'<button type="button" class="btn btn-s primary" id="ok">确定</button>'+
'<button type="button" class="btn btn-s" id="cancel">取消</button>'+
'</form>'+
'</div>'+
'</div>');
$('.wmd-prompt-dialog textarea').val('http://').select();
});
$(document).on('click','#cancel',function() {
$('#MetingPanel').remove();
$('textarea').focus();
});
$(document).on('click','#ok',function() {
callback=$.ajax({
type:'POST',
url:murl,
data:{data:$('.wmd-prompt-dialog textarea').val()},
async:false
});
$('#MetingPanel').remove();
myField = document.getElementById('text');
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = callback.responseText;
myField.focus();
}
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
var cursorPos = startPos;
myField.value = myField.value.substring(0, startPos)
+ callback.responseText
+ myField.value.substring(endPos, myField.value.length);
cursorPos += callback.responseText.length;
myField.focus();
myField.selectionStart = cursorPos;
myField.selectionEnd = cursorPos;
}
else{
myField.value += callback.responseText;
myField.focus();
}
});
});