Created
January 16, 2019 08:02
-
-
Save uyq/c90d251bdcc4f076be9c057bd7c7848d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env php | |
| <?php | |
| /** | |
| * 网易云音乐歌单批量下载脚本 | |
| * -------------------------------------------------------------- | |
| * Useage: | |
| * ./php music.php 歌单ID | |
| */ | |
| error_reporting(0); | |
| empty($argv) && die("Resque only run in cli mode\n"); | |
| if (empty($argv[1])) { | |
| die("Play List can not be null\n"); | |
| } | |
| //接口地址 | |
| $api = 'http://music.163.com/api/playlist/detail?id='; | |
| $downloadUrl = "http://m%u.music.126.net/%s/%s.mp3"; | |
| //获取歌单数据 | |
| $playListId = $argv[1]; | |
| $rs = http_get($api . $playListId); | |
| if (empty($rs)) { | |
| die("Request failed\n"); | |
| } | |
| $rs = json_decode($rs, true); | |
| if ($rs['code'] != 200) { | |
| die("Parse failed\n"); | |
| } | |
| //获取下载地址,下载至本地 | |
| $playList = $rs['result']['tracks']; | |
| $total = count($playList); | |
| foreach ($playList as $key => $value) { | |
| $tmp = getSongAlbum($value['album']['id']); | |
| // getSongDetail($value['id']); | |
| if ($tmp['code'] == 200) { | |
| $songKsy = 0; | |
| foreach ($tmp['album']['songs'] as $key1 => $value1) { | |
| if($value['name']==$value1['name']){ | |
| $songKsy = $key1; | |
| } | |
| } | |
| $song = $tmp['album']['songs'][$songKsy]; | |
| $download = 0; | |
| //低音质 | |
| if ($download == 0) { | |
| $url = 'http://music.163.com/song/media/outer/url?id='.$song['id'].'.mp3'; | |
| echo $song['name'], PHP_EOL, $url, PHP_EOL; | |
| $savepath = './mp3s/'.$rs['result']['name'].'/'; | |
| if (!is_dir($savepath)) { | |
| mkdir($savepath, 0755); | |
| } | |
| if (downRemoteFile($url, $savepath.$song['artists'][0]['name'].' - '.$song['name'].'.mp3')) { | |
| $download = 1; | |
| echo 'Download success', PHP_EOL; | |
| } else { | |
| echo 'Download failed', PHP_EOL; | |
| } | |
| } | |
| } else { | |
| echo 'Get album information failed' , PHP_EOL; | |
| } | |
| echo 'rest : '.($total-1-$key),PHP_EOL,PHP_EOL; | |
| } | |
| function http_get($url) | |
| { | |
| $oCurl = curl_init(); | |
| curl_setopt($oCurl, CURLOPT_HTTPHEADER, ['Content-type:text/html', 'Charset=utf8']); | |
| if (stripos($url, "https://") !== false) { | |
| curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false); | |
| curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); | |
| curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); | |
| } | |
| curl_setopt($oCurl, CURLOPT_URL, $url); | |
| curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); | |
| curl_setopt($oCurl, CURLOPT_COOKIE, 'appver=1.5.0.75771'); | |
| curl_setopt($oCurl, CURLOPT_REFERER, 'http://music.163.com/'); | |
| $sContent = curl_exec($oCurl); | |
| $aStatus = curl_getinfo($oCurl); | |
| curl_close($oCurl); | |
| if (intval($aStatus["http_code"]) == 200) { | |
| return $sContent; | |
| } else { | |
| return false; | |
| } | |
| } | |
| function downRemoteFile($url, $local, $timeout = 10) | |
| { | |
| $ch = curl_init(); | |
| curl_setopt($ch, CURLOPT_URL, $url); | |
| curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); | |
| curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
| curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); | |
| curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); | |
| ob_start(); | |
| curl_exec($ch); | |
| $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
| if ($code != 200) { | |
| ob_end_clean(); | |
| return false; | |
| } | |
| $content = ob_get_contents(); | |
| ob_end_clean(); | |
| $fp = @fopen($local, 'a'); | |
| fwrite($fp, $content); | |
| if (!is_dir('./mp3s/')) { | |
| mkdir('./mp3s/', 0755); | |
| } | |
| return true; | |
| } | |
| /** | |
| * 获取歌曲详情 | |
| * @param int $songId 歌曲id | |
| * @return array 歌曲详情 | |
| */ | |
| function getSongDetail($songId) | |
| { | |
| $apiUrl = 'http://music.163.com/api/song/detail?id=' . $songId . '&ids=%5B' . $songId . '%5D'; | |
| return json_decode(http_get($apiUrl), true); | |
| } | |
| /** | |
| * 获取专辑详情 | |
| * @param int $albumId 专辑id | |
| * @return array 专辑详情 | |
| */ | |
| function getSongAlbum($albumId) | |
| { | |
| $apiUrl = 'http://music.163.com/api/album/' . $albumId . '?id=' . $albumId; | |
| return json_decode(http_get($apiUrl), true); | |
| } | |
| function BytesToStr($bytes) | |
| { | |
| $str = ''; | |
| foreach ($bytes as $ch) { | |
| $str .= chr($ch); | |
| } | |
| return $str; | |
| } | |
| function strToBytes($string) | |
| { | |
| $bytes = array(); | |
| for ($i = 0; $i < strlen($string); $i++) { | |
| $bytes[] = ord($string[$i]); | |
| } | |
| return $bytes; | |
| } | |
| /** | |
| * 网易云音乐歌曲ID加密函数 | |
| * @param string $dfsId 音质ID | |
| * @return string 加密值 | |
| * 参考https://github.com/yanunon/NeteaseCloudMusic/wiki/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90API%E5%88%86%E6%9E%90 | |
| */ | |
| function encrypt_id($dfsId) | |
| { | |
| $str1 = strToBytes('3go8&$8*3*3h0k(2)2'); | |
| $str2 = strToBytes((string) $dfsId); | |
| $len = count($str2); | |
| for ($i = 0; $i < $len; $i++) { | |
| $str2[$i] = $str2[$i] ^ $str1[$i % $len]; | |
| } | |
| $encryptStr = base64_encode(md5(BytesToStr($str2), 1)); | |
| $encryptStr = str_replace('/', '_', $encryptStr); | |
| $encryptStr = str_replace('+', '_', $encryptStr); | |
| return $encryptStr; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment