Ludy Su
7 years ago
3 changed files with 259 additions and 2 deletions
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"name": "NetEaseLrc", |
||||
"displayname": "NE Cloud Music Lrc", |
||||
"description": "", |
||||
"version": "1.0", |
||||
"site": "http://music.163.com", |
||||
"module": "netease.php", |
||||
"type": "lyric", |
||||
"class": "NetEaseLrc" |
||||
} |
@ -1,2 +1,9 @@
@@ -1,2 +1,9 @@
|
||||
# Synology-LrcPlugin |
||||
Lyrics plugin for Synology Audio Station/DS Audio |
||||
# Synology Lrc Plugin |
||||
Lyrics plugin for Synology Audio Station/DS Audio. |
||||
|
||||
## Usage |
||||
|
||||
## Inspired by |
||||
[Synology Lyric project by Frank Lai](https://bitbucket.org/franklai/synologylyric) |
||||
|
||||
[PHP API by Moonlib](http://moonlib.com/606.html) |
||||
|
@ -0,0 +1,240 @@
@@ -0,0 +1,240 @@
|
||||
<?php |
||||
$DEBUG = true; |
||||
$NEED_TRANSLATION = false; |
||||
|
||||
|
||||
/** |
||||
* Implements the functions required by Audio Station/DSAudio. |
||||
*/ |
||||
class NetEaseLrc { |
||||
|
||||
/** |
||||
* Searches for a lyric with the artist and title, and returns the result list. |
||||
*/ |
||||
public function getLyricsList($artist, $title, $info) { |
||||
$artist = trim($artist); |
||||
$title = trim($title); |
||||
if ($this->isNullOrEmptyString($title)) { |
||||
echo "song title is empty"; |
||||
return 0; |
||||
} |
||||
|
||||
$response = $this->search($title); |
||||
if ($this->isNullOrEmptyString($response)) { |
||||
echo "===== no songs found in the response"; |
||||
return 0; |
||||
} |
||||
|
||||
$json = json_decode($response, true); |
||||
$songArray = $json['result']['songs']; |
||||
$foundArray = array(); |
||||
|
||||
if(count($songArray) == 0) { |
||||
echo "===== no songs found"; |
||||
return 0; |
||||
} |
||||
|
||||
// Try to find the titles that match exactly |
||||
$exactMatchArray = array(); |
||||
$partialMatchArray = array(); |
||||
foreach ($songArray as $song) { |
||||
echo "$title ===(" . $song['name'] . ")</br>"; |
||||
if (strtolower($title) === strtolower($song['name'])) { |
||||
array_push($exactMatchArray, $song); |
||||
} else if (strpos($song['name'], $title) || strpos($title, $song['name'])) { |
||||
array_push($partialMatchArray, $song); |
||||
} |
||||
} |
||||
|
||||
if (count($exactMatchArray) != 0) { |
||||
echo "exact matched titles " . count($exactMatchArray) ."</br>"; |
||||
$songArray = $exactMatchArray; |
||||
} else if (count($partialMatchArray != 0)) { |
||||
echo "part match " . count($partialMatchArray) . "</br>"; |
||||
$songArray = $partialMatchArray; |
||||
} |
||||
|
||||
// Try to find the artists that match exactly |
||||
foreach ($songArray as $song) { |
||||
foreach ($song['artists'] as $item) { |
||||
if (strtolower($item['name']) === strtolower($artist)) { |
||||
echo "====== found " . $song['id'] . "</br>"; |
||||
array_push($foundArray, $song['id']); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
echo "found " . count($foundArray) . " exact match artist songs ===== </br>"; |
||||
if (count($foundArray) == 0) { |
||||
echo "no match artist found, picking any match </br>"; |
||||
foreach ($songArray as $song) { |
||||
array_push($foundArray, $song["id"]); |
||||
} |
||||
} |
||||
|
||||
// It's not easy for user to select the best match, so randomize the restult so that next time a new one will be returned |
||||
shuffle($foundArray); |
||||
foreach ($foundArray as $songId) { |
||||
$info->addTrackInfoToList($artist, $title, $songId, ''); |
||||
} |
||||
|
||||
return count($foundArray); |
||||
} |
||||
|
||||
/** |
||||
* Downloads a file with the specific ID |
||||
*/ |
||||
public function getLyrics($id, $info) { |
||||
//TODO combine translated lrc |
||||
$lrc = $this->downloadLyric($id); |
||||
if ($this->isNullOrEmptyString($lrc)) { |
||||
printf("download lyrics from server failed\n"); |
||||
return FALSE; |
||||
} |
||||
|
||||
$info->addLyrics($lrc, $id); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static function search($word) { |
||||
$params = array( |
||||
's' => $word, |
||||
'offset' => '0', 'limit' => '20', |
||||
'total' => true, |
||||
'type' => '1', //搜索单曲(1),歌手(100),专辑(10),歌单(1000),用户(1002) |
||||
); |
||||
|
||||
$headers = array( |
||||
'Connection: close', 'Content-Type: application/x-www-form-urlencoded', |
||||
'Host: music.163.com', 'Cookie: appver=1.5.0.75771;'); |
||||
|
||||
$curl = curl_init(); |
||||
curl_setopt_array($curl, array( |
||||
CURLOPT_URL => "http://music.163.com/api/search/pc", |
||||
CURLOPT_RETURNTRANSFER => true, |
||||
CURLOPT_POST => true, |
||||
CURLOPT_POSTFIELDS => http_build_query($params), |
||||
// CURLOPT_REFERER => "http://music.163.com/", |
||||
// CURLOPT_HTTPHEADER => $headers, |
||||
)); |
||||
|
||||
$output = curl_exec($curl); |
||||
curl_close($curl); |
||||
|
||||
return $output; |
||||
} |
||||
|
||||
/** |
||||
* Gets all lyrics, apart from original one, translated and karaoke versions will also be returned if available. |
||||
*/ |
||||
private function downloadLyric($music_id) { |
||||
// lv = original version; tv = translated version; kv = karaoke version, rarely available. Set value to 0 if don't want |
||||
$url = "http://music.163.com/api/song/lyric?os=pc&id=" . $music_id . "&lv=-1&kv=0&tv=-1"; |
||||
$response = $this->download($url); |
||||
if ($this->isNullOrEmptyString($response)) { |
||||
echo "Can not download lyrics id '$music_id'"; |
||||
return NULL; |
||||
} |
||||
|
||||
// var_dump($response);echo "</br>========</br>"; |
||||
$json = json_decode($response, true); |
||||
return $json['lrc']['lyric']; |
||||
} |
||||
|
||||
// Function for basic field validation (present and neither empty nor only white space |
||||
private static function isNullOrEmptyString($question){ |
||||
return (!isset($question) || trim($question)===''); |
||||
} |
||||
|
||||
private static function download($url) { |
||||
$header[] = "Cookie: appver=1.5.0.75771;"; |
||||
$curl = curl_init(); |
||||
curl_setopt_array($curl, array( |
||||
CURLOPT_URL => $url, |
||||
// CURLOPT_HTTPHEADER => $header, |
||||
CURLOPT_RETURNTRANSFER => true, |
||||
// CURLOPT_BINARYTRANSFER => true, |
||||
// CURLOPT_REFERER => "http://music.163.com/", |
||||
)); |
||||
$output = curl_exec($curl); |
||||
curl_close($curl); |
||||
return $output; |
||||
} |
||||
} |
||||
|
||||
|
||||
////////////////////////// Debug //////////////////////////////////// |
||||
|
||||
if ($DEBUG == true) { |
||||
class TestObj { |
||||
private $items; |
||||
|
||||
function __construct() { |
||||
$this->items = array(); |
||||
} |
||||
|
||||
public function addLyrics($lyric, $id) { |
||||
printf("\n"); |
||||
printf("song id: %s\n", $id); |
||||
printf("\n"); |
||||
printf("== lyric ==\n"); |
||||
printf("%s\n", $lyric); |
||||
printf("** END of lyric **\n\n"); |
||||
} |
||||
|
||||
public function addTrackInfoToList($artist, $title, $id, $prefix) { |
||||
printf("\n"); |
||||
printf("song id: %s\n", $id); |
||||
printf("artist [%s]\n", $artist); |
||||
printf("title [%s]\n", $title); |
||||
printf("prefix [%s]\n", $prefix); |
||||
printf("\n"); |
||||
|
||||
array_push($this->items, array( |
||||
'artist' => $artist, |
||||
'title' => $title, |
||||
'id' => $id |
||||
)); |
||||
} |
||||
|
||||
function getItems() { |
||||
return $this->items; |
||||
} |
||||
|
||||
function getFirstItem() { |
||||
if (count($this->items) > 0) { |
||||
return $this->items[0]; |
||||
} else { |
||||
return NULL; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Main |
||||
*/ |
||||
$artist = " lisa"; |
||||
$title = "catch the moment "; |
||||
echo "Trying to find lyrics for ['$title'] by artist ['$artist'] ...</br>"; |
||||
|
||||
$testObj = new TestObj(); |
||||
$downloader = (new ReflectionClass("NetEaseLrc"))->newInstance(); |
||||
$count = $downloader->getLyricsList($artist, $title, $testObj); |
||||
if ($count > 0) { |
||||
$item = $testObj->getFirstItem(); |
||||
|
||||
if (array_key_exists('id', $item)) { |
||||
$downloader->getLyrics($item['id'], $testObj); |
||||
} else { |
||||
echo "\nno id to query lyric\n"; |
||||
} |
||||
} else { |
||||
echo " ****************************\n"; |
||||
echo " *** Failed to find lyric ***\n"; |
||||
echo " ****************************\n"; |
||||
} |
||||
} |
||||
|
||||
|
Loading…
Reference in new issue