| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191 | <?php/*** Meting music framework* https://i-meto.com* https://github.com/metowolf/Meting* Version 1.4.1** Copyright 2018, METO Sheel <i@i-meto.com>* Released under the MIT license*/namespace Metowolf;class Meting{    protected $_SITE;    protected $_TEMP;    protected $_RETRY = 3;    protected $_FORMAT = false;    public function __construct($v = 'netease')    {        $this->site($v);    }    public function site($v)    {        $suppose = array('netease', 'tencent', 'xiami', 'kugou', 'baidu');        $this->_SITE = in_array($v,$suppose) ? $v : 'netease';        return $this;    }    public function cookie($v = '')    {        $this->_TEMP['cookie'] = $v;        return $this;    }    public function format($v = true)    {        $this->_FORMAT = $v;        return $this;    }    private function curl($API)    {        if (isset($API['encode'])) {            $API=call_user_func_array(array($this,$API['encode']), array($API));        }        $BASE = $this->curlset();        $curl = curl_init();        if ($API['method'] == 'POST') {            if (is_array($API['body'])) {                $API['body'] = http_build_query($API['body']);            }            curl_setopt($curl, CURLOPT_POST, 1);            curl_setopt($curl, CURLOPT_POSTFIELDS, $API['body']);        } elseif ($API['method'] == 'GET') {            if (isset($API['body'])) {                $API['url'] = $API['url'].'?'.http_build_query($API['body']);            }        }        curl_setopt($curl, CURLOPT_HEADER, 0);        curl_setopt($curl, CURLOPT_TIMEOUT, 20);        curl_setopt($curl, CURLOPT_ENCODING, 'gzip');        curl_setopt($curl, CURLOPT_IPRESOLVE, 1);        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);        curl_setopt($curl, CURLOPT_URL, $API['url']);        curl_setopt($curl, CURLOPT_COOKIE, isset($this->_TEMP['cookie'])?$this->_TEMP['cookie']:$BASE['cookie']);        curl_setopt($curl, CURLOPT_HTTPHEADER, array(            'Accept: */*',            'Accept-Encoding: gzip, deflate',            'Accept-Language: zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4',            'Connection: keep-alive',            'Content-Type: application/x-www-form-urlencoded',            'Referer: ' . $BASE['referer'],            'User-Agent: ' . $BASE['useragent']        ));        for ($i=0;$i<=$this->_RETRY;$i++) {            $data = curl_exec($curl);            $info = curl_getinfo($curl);            $error = curl_errno($curl);            $status = $error ? curl_error($curl) : '';            if (!$error) {                break;            }        }        curl_close($curl);        if ($error) {            return json_encode(                array(                    'error'  => $error,                    'info'   => $info,                    'status' => $status,                )            );        }        if ($this->_FORMAT && isset($API['decode'])) {            $data = call_user_func_array(array($this,$API['decode']), array($data));        }        if ($this->_FORMAT && isset($API['format'])) {            $data = json_decode($data, 1);            $data = $this->clean($data, $API['format']);            $data = json_encode($data);        }        return $data;    }    private function pickup($array, $rule)    {        $t = explode('#', $rule);        foreach ($t as $vo) {            if (!isset($array[$vo])){                return array();            }            $array = $array[$vo];        }        return $array;    }    private function clean($raw, $rule)    {        if (!empty($rule)) {            $raw = $this->pickup($raw, $rule);        }        if (!isset($raw[0]) && sizeof($raw)) {            $raw = array($raw);        }        $result = array_map(array($this,'format_'.$this->_SITE), $raw);        return $result;    }    public function search($keyword, $option = null)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'POST',                    'params' => array(                        's'      => $keyword,                        'type'   => isset($option['type']) ? $option['type'] : 1,                        'limit'  => isset($option['limit']) ? $option['limit'] : 30,                        'total'  => 'true',                        'offset' => isset($option['page']) && isset($option['limit']) ? ($option['page'] - 1) * $option['limit'] : 0,                    ),                    'url' => 'http://music.163.com/api/cloudsearch/pc',                ),                'encode' => 'netease_AESECB',                'format' => 'result#songs',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp',                'body'   => array(                    'format'   => 'json',                    'p'        => isset($option['page']) ? $option['page'] : 1,                    'n'        => isset($option['limit']) ? $option['limit'] : 30,                    'w'        => $keyword,                    'aggr'     => 1,                    'lossless' => 1,                    'cr'       => 1,                    'new_json' => 1,                ),                'format' => 'data#song#list',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'key'     => $keyword,                    'page'    => isset($option['page']) ? $option['page'] : 1,                    'limit'   => isset($option['limit']) ? $option['limit'] : 30,                    'r'       => 'search/songs',                ),                'format' => 'data#songs',            );            break;            case 'kugou':            $API = array(                'method' => 'GET',                'url'    => 'http://ioscdn.kugou.com/api/v3/search/song',                'body'   => array(                    'iscorrect' => 1,                    'pagesize'  => isset($option['limit']) ? $option['limit'] : 30,                    'plat'      => 2,                    'tag'       => 1,                    'sver'      => 5,                    'showtype'  => 10,                    'page'      => isset($option['page']) ? $option['page'] : 1,                    'keyword'   => $keyword,                    'version'   => 8550                ),                'format' => 'data#info',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.search.merge',                    'isNew'     => 1,                    'platform'  => 'darwin',                    'page_no'   => isset($option['page']) ? $option['page'] : 1,                    'query'     => $keyword,                    'version'   => '11.0.2',                    'page_size' => isset($option['limit']) ? $option['limit'] : 30                ),                'format' => 'result#song_info#song_list',            );            break;        }        return $this->curl($API);    }    public function song($id)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'POST',                    'params' => array(                        'c' => '[{"id":'.$id.',"v":0}]',                    ),                    'url' => 'http://music.163.com/api/v3/song/detail/',                ),                'encode' => 'netease_AESECB',                'format' => 'songs',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg',                'body'   => array(                    'songmid'  => $id,                    'platform' => 'yqq',                    'format'   => 'json',                ),                'decode' => 'tencent_singlesong',                'format' => 'data',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'r'       => 'song/detail',                ),                'format' => 'data#song',            );            break;            case 'kugou':            $API = array(                'method' => 'POST',                'url'    => 'http://m.kugou.com/app/i/getSongInfo.php',                'body'   => array(                    "cmd"  => "playInfo",                    "hash" => $id,                    "from" => "mkugou",                ),                'format' => '',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.song.getInfos',                    'songid'    => $id,                    'res'       => 1,                    'platform'  => 'darwin',                    'version'   => '1.0.0'                ),                'encode' => 'baidu_AESCBC',                'format' => 'songinfo',            );            break;        }        return $this->curl($API);    }    public function album($id)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'GET',                    'params' => array(                        "total"         => "true",                        "offset"        => "0",                        "id"            => $id,                        "limit"         => "1000",                        "ext"           => "true",                        "private_cloud" => "true"                    ),                    'url' => 'http://music.163.com/api/v1/album/'.$id,                ),                'encode' => 'netease_AESECB',                'format' => 'songs',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_album_detail_cp.fcg',                'body'   => array(                    'albummid' => $id,                    'platform' => 'mac',                    'format'   => 'json',                    'newsong'  => 1,                ),                'format' => 'data#getSongInfo',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'r'       => 'album/detail',                ),                'format' => 'data#songs',            );            break;            case 'kugou':            $API = array(                'method' => 'GET',                'url'    => 'http://mobilecdn.kugou.com/api/v3/album/song',                'body'   => array(                    'albumid'  => $id,                    'plat'     => 2,                    'page'     => 1,                    'pagesize' => -1,                    'version'  => 8550,                ),                'format' => 'data#info',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.album.getAlbumInfo',                    'album_id'  => $id,                    'platform'  => 'darwin',                    'version'   => '11.0.2'                ),                'format' => 'songlist',            );            break;        }        return $this->curl($API);    }    public function artist($id, $limit=50)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'GET',                    'params' => array(                        "ext"           => "true",                        "private_cloud" => "true",                        "ext"           => "true",                        "top"           => $limit,                        "id"            => $id                    ),                    'url' => 'http://music.163.com/api/v1/artist/'.$id,                ),                'encode' => 'netease_AESECB',                'format' => 'hotSongs',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg',                'body'   => array(                    'singermid' => $id,                    'begin'     => 0,                    'num'       => $limit,                    'order'     => 'listen',                    'platform'  => 'mac',                    'newsong'   => 1,                ),                'format' => 'data#list',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'limit'   => $limit,                    'page'    => 1,                    'r'       => 'artist/hot-songs',                ),                'format' => 'data',            );            break;            case 'kugou':            $API = array(                'method' => 'GET',                'url'    => 'http://mobilecdn.kugou.com/api/v3/singer/song',                'body'   => array(                    'singerid' => $id,                    'page'     => 1,                    'plat'     => 0,                    'pagesize' => $limit,                    'version'  => 8400,                ),                'format' => 'data#info',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.artist.getSongList',                    'artistid'  => $id,                    'limits'    => 20,                    'platform'  => 'darwin',                    'offset'    => 0,                    'tinguid'   => 0,                    'version'   => '11.0.2'                ),                'format' => 'songlist',            );            break;        }        return $this->curl($API);    }    public function playlist($id)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'POST',                    'params' => array(                        "s"  => "0",                        "id" => $id,                        "n"  => "1000",                        "t"  => "0"                    ),                    'url' => 'http://music.163.com/api/v3/playlist/detail',                ),                'encode' => 'netease_AESECB',                'format' => 'playlist#tracks',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_playlist_cp.fcg',                'body'   => array(                    'id'       => $id,                    'format'   => 'json',                    'newsong'  => 1,                    'platform' => 'jqspaframe.json',                ),                'format' => 'data#cdlist#0#songlist',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'r'       => 'collect/detail',                ),                'format' => 'data#songs',            );            break;            case 'kugou':            $API = array(                'method' => 'GET',                'url'    => 'http://mobilecdn.kugou.com/api/v3/special/song',                'body'   => array(                    'specialid' => $id,                    'page'      => 1,                    'plat'      => 2,                    'pagesize'  => -1,                    'version'   => 8400,                ),                'format' => 'data#info',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.diy.gedanInfo',                    'listid'    => $id,                    'platform'  => 'darwin',                    'version'   => '11.0.2'                ),                'format' => 'content',            );            break;        }        return $this->curl($API);    }    public function url($id, $br=320)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'POST',                    'params' => array(                        'ids' => array($id),                        'br'  => $br*1000,                    ),                    'url' => 'http://music.163.com/api/song/enhance/player/url',                ),                'encode' => 'netease_AESECB',                'decode' => 'netease_url',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg',                'body'   => array(                    'songmid' => $id,                    'platform' => 'yqq',                    'format'  => 'json',                ),                'decode' => 'tencent_url',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://www.xiami.com/song/gethqsong/sid/'.$id,                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'r'       => 'song/detail',                ),                'decode' => 'xiami_url',            );            break;            case 'kugou':            $API = array(                'method' => 'POST',                'url'    => 'http://media.store.kugou.com/v1/get_res_privilege',                'body'   => json_encode(array(                    "relate"    => 1,                    "userid"    => 0,                    "vip"       => 0,                    "appid"     => 1005,                    "token"     => "",                    "behavior"  => "download",                    "clientver" => "8493",                    "resource"  => array(array(                        "id"   => 0,                        "type" => "audio",                        "hash" => $id,                    )))                ),                'decode' => 'kugou_url',            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.song.getInfos',                    'songid'    => $id,                    'res'       => 1,                    'platform'  => 'darwin',                    'version'   => '1.0.0'                ),                'encode' => 'baidu_AESCBC',                'decode' => 'baidu_url',            );            break;        }        $this->_TEMP['br'] = $br;        return $this->curl($API);    }    public function lyric($id)    {        switch ($this->_SITE) {            case 'netease':            $API = array(                'method' => 'POST',                'url'    => 'http://music.163.com/api/linux/forward',                'body'   => array(                    'method' => 'POST',                    'params' => array(                        'id' => $id,                        'os' => 'linux',                        'lv' => -1,                        'kv' => -1,                        'tv' => -1,                    ),                    'url' => 'http://music.163.com/api/song/lyric',                ),                'encode' => 'netease_AESECB',                'decode' => 'netease_lyric',            );            break;            case 'tencent':            $API = array(                'method' => 'GET',                'url'    => 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg',                'body'   => array(                    'songmid'  => $id,                    'g_tk'     => '5381',                ),                'decode' => 'tencent_lyric',            );            break;            case 'xiami':            $API = array(                'method' => 'GET',                'url'    => 'http://api.xiami.com/web',                'body'   => array(                    'v'       => '2.0',                    'app_key' => '1',                    'id'      => $id,                    'r'       => 'song/detail',                ),                'decode' => 'xiami_lyric',            );            break;            case 'kugou':            $API = array(                'method' => 'GET',                'url'    => 'http://m.kugou.com/app/i/krc.php',                'body'   => array(                    'keyword'    => '%20-%20',                    'timelength' => 1000000,                    'cmd'        => 100,                    'hash'       => $id,                ),                'decode' => 'kugou_lyric'            );            break;            case 'baidu':            $API = array(                'method' => 'GET',                'url'    => 'http://tingapi.ting.baidu.com/v1/restserver/ting',                'body'   => array(                    'from'      => 'qianqianmini',                    'method'    => 'baidu.ting.song.lry',                    'songid'    => $id,                    'platform'  => 'darwin',                    'version'   => '1.0.0'                ),                'decode' => 'baidu_lyric',            );            break;        }        return $this->curl($API);    }    public function pic($id, $size=300)    {        switch ($this->_SITE) {            case 'netease':            $url='https://p3.music.126.net/'.$this->netease_pickey($id).'/'.$id.'.jpg?param='.$size.'y'.$size;            break;            case 'tencent':            $url='https://y.gtimg.cn/music/photo_new/T002R'.$size.'x'.$size.'M000'.$id.'.jpg?max_age=2592000';            break;            case 'xiami':            $format=$this->_FORMAT;            $data=$this->format(false)->song($id);            $this->format($format);            $data=json_decode($data, 1);            $url=$data['data']['song']['logo'];            $url=str_replace(array('_1.','http:','img.'), array('.','https:','pic.'), $url).'@'.$size.'h_'.$size.'w_100q_1c.jpg';            break;            case 'kugou':            $format=$this->_FORMAT;            $data=$this->format(false)->song($id);            $this->format($format);            $data=json_decode($data, 1);            $url=$data['imgUrl'];            $url=str_replace('{size}', '400', $url);            break;            case 'baidu':            $format=$this->_FORMAT;            $data=$this->format(false)->song($id);            $this->format($format);            $data=json_decode($data, 1);            $url=isset($data['songinfo']['pic_radio'])?$data['songinfo']['pic_radio']:$data['songinfo']['pic_small'];            break;        }        return json_encode(array('url'=>$url));    }    private function curlset()    {        switch ($this->_SITE) {            case 'netease':            return array(                'referer'   => 'https://music.163.com/',                'cookie'    => 'os=linux; deviceId=' . $this->getRandomHex(52) . '; osver=Ubuntu%2016.04.3%20LTS; appver=1.1.0.1232; channel=netease; MUSIC_U=255b19fea4bdec0a0011f855c3708e3e97b229707fccab67d74da902317635b4f866558227e6c3335d9bd72ef1abb9ea77749c2dda21047b; __csrf=' . $this->getRandomHex(32),                'useragent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',            );            case 'tencent':            return array(                'referer'   => 'https://y.qq.com/portal/player.html',                'cookie'    => 'pgv_pvi=22038528; pgv_si=s3156287488; pgv_pvid=5535248600; yplayer_open=1; ts_last=y.qq.com/portal/player.html; ts_uid=4847550686; yq_index=0; qqmusic_fromtag=66; player_exist=1',                'useragent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',            );            case 'xiami':            return array(                'referer'   => 'http://h.xiami.com/',                'cookie'    => '_xiamitoken=' . $this->getRandomHex(32) . '; _unsign_token=' . $this->getRandomHex(32),                'useragent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',            );            case 'kugou':            return array(                'referer'   => 'http://www.kugou.com/webkugouplayer/flash/webKugou.swf',                'cookie'    => 'kg_mid=' . $this->getRandomHex(32),                'useragent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',            );            case 'baidu':            return array(                'referer'   => '',                'cookie'    => 'BAIDUID=' . $this->getRandomHex(32) . ':FG=1',                'useragent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) baidu-music/1.0.2 Chrome/56.0.2924.87 Electron/1.6.11 Safari/537.36',            );        }    }    private function getRandomHex($length)    {        if (function_exists('openssl_random_pseudo_bytes')) {            return bin2hex(openssl_random_pseudo_bytes($length));        } else {            return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));        }    }    /**     * 乱七八糟的函数,加密解密...     * 正在努力重构这些代码 TAT     */    private function netease_AESECB($API)    {        $KEY='7246674226682325323F5E6544673A51';        $body=json_encode($API['body']);        if (function_exists('openssl_encrypt')) {            $body=openssl_encrypt($body, 'aes-128-ecb', pack('H*', $KEY));        } else {            $PAD=16-(strlen($body)%16);            $body=base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, hex2bin($KEY), $body.str_repeat(chr($PAD), $PAD), MCRYPT_MODE_ECB));        }        $body=strtoupper(bin2hex(base64_decode($body)));        $API['body']=array(            'eparams'=>$body,        );        return $API;    }    private function baidu_AESCBC($API)    {        $key = 'DBEECF8C50FD160E';        $vi = '1231021386755796';        $data = 'songid='.$API['body']['songid'].'&ts='.intval(microtime(true)*1000);        if (function_exists('openssl_encrypt')) {            $data = openssl_encrypt($data, 'aes-128-cbc', $key, false, $vi);        } else {            $PAD = 16-(strlen($data)%16);            $data = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data.str_repeat(chr($PAD), $PAD), MCRYPT_MODE_CBC, $vi));        }        $API['body']['e'] = $data;        return $API;    }    private function tencent_singlesong($result)    {        $result=json_decode($result, 1);        $data=$result['data'][0];        $t=array(            'songmid' => $data['mid'],            'songname' => $data['name'],            'albummid' => $data['album']['mid'],        );        foreach ($t as $key=>$vo) {            $result['data'][0][$key]=$vo;        }        return json_encode($result);    }    private function netease_pickey($id)    {        $magic=str_split('3go8&$8*3*3h0k(2)2');        $song_id=str_split($id);        for ($i=0;$i<count($song_id);$i++) {            $song_id[$i]=chr(ord($song_id[$i])^ord($magic[$i%count($magic)]));        }        $result=base64_encode(md5(implode('', $song_id), 1));        $result=str_replace(array('/','+'), array('_','-'), $result);        return $result;    }    /**     * URL - 歌曲地址转换函数     * 用于返回不高于指定 bitRate 的歌曲地址(默认规范化)     */    private function netease_url($result)    {        $data=json_decode($result, 1);        if (isset($data['data'][0]['uf']['url'])) {            $data['data'][0]['url']=$data['data'][0]['uf']['url'];        }        if (isset($data['data'][0]['url'])) {            $url=array(                'url' => $data['data'][0]['url'],                'br'  => $data['data'][0]['br']/1000,            );        } else {            $url=array(                'url' => '',                'br'  => -1,            );        }        return json_encode($url);    }    private function tencent_url($result)    {        $data=json_decode($result, 1);        $GUID=mt_rand()%10000000000;        $API=array(            'method' => 'GET',            'url'    => 'https://c.y.qq.com/base/fcgi-bin/fcg_musicexpress.fcg',            'body'   => array(                'json'   => 3,                'guid'   => $GUID,                'format' => 'json',            ),        );        $KEY=json_decode($this->curl($API), 1);        $KEY=$KEY['key'];        $type=array(            'size_320mp3' => array(320,'M800','mp3'),            'size_192aac' => array(192,'C600','m4a'),            'size_128mp3' => array(128,'M500','mp3'),            'size_96aac'  => array(96 ,'C400','m4a'),            'size_48aac'  => array(48 ,'C200','m4a'),        );        foreach ($type as $key=>$vo) {            if ($data['data'][0]['file'][$key]&&$vo[0]<=$this->_TEMP['br']) {                $url=array(                    'url' => 'https://dl.stream.qqmusic.qq.com/'.$vo[1].$data['data'][0]['file']['media_mid'].'.'.$vo[2].'?vkey='.$KEY.'&guid='.$GUID.'&uid=0&fromtag=30',                    'br'  => $vo[0],                );                break;            }        }        if (!isset($url['url'])) {            $url=array(                'url' => '',                'br'  => -1,            );        }        return json_encode($url);    }    private function xiami_url($result)    {        $data=json_decode($result, 1);        if (!empty($data['location'])) {            $location = $data['location'];            $num = (int)$location[0];            $str = substr($location, 1);            $len = floor(strlen($str)/$num);            $sub = strlen($str) % $num;            $qrc = array();            $tmp = 0;            $urlt = '';            for (;$tmp<$sub;$tmp++) {                $qrc[$tmp] = substr($str, $tmp*($len+1), $len+1);            }            for (;$tmp<$num;$tmp++) {                $qrc[$tmp] = substr($str, $len*$tmp+$sub, $len);            }            for ($tmpa=0;$tmpa<$len+1;$tmpa++) {                for ($tmpb=0;$tmpb<$num;$tmpb++) {                    if (isset($qrc[$tmpb][$tmpa])) {                        $urlt.=$qrc[$tmpb][$tmpa];                    }                }            }            $urlt=str_replace('^', '0', urldecode($urlt));            $url=array(                'url' => str_replace('http://','https://',urldecode($urlt)),                'br'  => 320,            );        } else {            $url=array(                'url' => '',                'br'  => -1,            );        }        return json_encode($url);    }    private function kugou_url($result)    {        $data=json_decode($result, 1);        $max=0;        $url=array();        foreach ($data['data'][0]['relate_goods'] as $vo) {            if ($vo['info']['bitrate']<=$this->_TEMP['br']&&$vo['info']['bitrate']>$max) {                $API=array(                    'method' => 'GET',                    'url'    => 'http://trackercdn.kugou.com/i/v2/',                    'body'   => array(                        'hash'     => $vo['hash'],                        'key'      => md5($vo['hash'].'kgcloudv2'),                        'pid'      => 1,                        'behavior' => 'play',                        'cmd'      => '23',                        'version'  => 8400,                    ),                );                $t=json_decode($this->curl($API), 1);                if (isset($t['url'])) {                    $max=$t['bitRate']/1000;                    $url=array(                        'url' => $t['url'],                        'br'  => $t['bitRate']/1000,                    );                }            }        }        if (!isset($url['url'])) {            $url=array(                'url' => '',                'br'  => -1,            );        }        return json_encode($url);    }    private function baidu_url($result)    {        $data=json_decode($result, true);        $max=0;        $url=array();        foreach ($data['songurl']['url'] as $vo) {            if ($vo['file_bitrate']<=$this->_TEMP['br']&&$vo['file_bitrate']>$max) {                $url=array(                    'url' => $vo['file_link'],                    'br'  => $vo['file_bitrate'],                );            }        }        if (!isset($url['url'])) {            $url=array(                'url' => '',                'br'  => -1,            );        }        return json_encode($url);    }    /**     * 歌词处理模块     * 用于规范化歌词输出     */    private function netease_lyric($result)    {        if (!$this->_FORMAT) {            return $result;        }        $result=json_decode($result, 1);        $data=array(            'lyric'  => isset($result['lrc']['lyric'])?$result['lrc']['lyric']:'',            'tlyric' => isset($result['tlyric']['lyric'])?$result['tlyric']['lyric']:'',        );        return json_encode($data);    }    private function tencent_lyric($result)    {        $result=substr($result,18,-1);        if (!$this->_FORMAT) {            return $result;        }        $result=json_decode($result, 1);        $data=array(            'lyric'  => isset($result['lyric'])?base64_decode($result['lyric']):'',            'tlyric' => isset($result['trans'])?base64_decode($result['trans']):'',        );        return json_encode($data);    }    private function xiami_lyric($result)    {        if (!$this->_FORMAT) {            return $result;        }        $result=json_decode($result, 1);        $data='';        if(!empty($result['data']['song']['lyric'])){            $API=array('method'=>'GET','url'=>$result['data']['song']['lyric']);            $data=$this->curl($API);            $data=preg_replace('/<[^>]+>/', '', $data);        }        preg_match_all('/\[([\d:\.]+)\](.*)\s\[x-trans\](.*)/i',$data,$match);        if(sizeof($match[0])){            for($i=0;$i<sizeof($match[0]);$i++){                $A[]='['.$match[1][$i].']'.$match[2][$i];                $B[]='['.$match[1][$i].']'.$match[3][$i];            }            $arr=array(                'lyric'  => str_replace($match[0],$A,$data),                'tlyric' => str_replace($match[0],$B,$data),            );        }        else{            $arr=array(                'lyric'  => $data,                'tlyric' => '',            );        }        return json_encode($arr);    }    private function kugou_lyric($result)    {        if (!$this->_FORMAT) {            return $result;        }        $arr=array(            'lyric'  => $result,            'tlyric' => '',        );        return json_encode($arr);    }    private function baidu_lyric($result)    {        if (!$this->_FORMAT) {            return $result;        }        $result=json_decode($result, 1);        $data=array(            'lyric'  => isset($result['lrcContent'])?$result['lrcContent']:'',            'tlyric' => '',        );        return json_encode($data);    }    /**    * Format - 规范化函数    * 用于统一返回的参数,可用 ->format() 一次性开关开启    */    private function format_netease($data)    {        $result=array(            'id'        => $data['id'],            'name'      => $data['name'],            'artist'    => array(),            'album'     => $data['al']['name'],            'pic_id'    => isset($data['al']['pic_str'])?$data['al']['pic_str']:$data['al']['pic'],            'url_id'    => $data['id'],            'lyric_id'  => $data['id'],            'source'    => 'netease',        );        if (isset($data['al']['picUrl'])) {            preg_match('/\/(\d+)\./', $data['al']['picUrl'], $match);            $result['pic_id']=$match[1];        }        foreach ($data['ar'] as $vo) {            $result['artist'][]=$vo['name'];        }        return $result;    }    private function format_tencent($data)    {        if (isset($data['musicData'])) {            $data=$data['musicData'];        }        $result=array(            'id'        => $data['mid'],            'name'      => $data['name'],            'artist'    => array(),            'album'     => trim($data['album']['title']),            'pic_id'    => $data['album']['mid'],            'url_id'    => $data['mid'],            'lyric_id'  => $data['mid'],            'source'    => 'tencent',        );        foreach ($data['singer'] as $vo) {            $result['artist'][]=$vo['name'];        }        return $result;    }    private function format_xiami($data)    {        $result=array(            'id'       => $data['song_id'],            'name'     => $data['song_name'],            'artist'   => explode(';', isset($data['singers'])?$data['singers']:$data['artist_name']),            'album'    => $data['album_name'],            'pic_id'   => $data['song_id'],            'url_id'   => $data['song_id'],            'lyric_id' => $data['song_id'],            'source'   => 'xiami',        );        return $result;    }    private function format_kugou($data)    {        $result=array(            'id'       => $data['hash'],            'name'     => isset($data['filename'])?$data['filename']:$data['fileName'],            'artist'   => array(),            'album'    => isset($data['album_name'])?$data['album_name']:'',            'url_id'   => $data['hash'],            'pic_id'   => $data['hash'],            'lyric_id' => $data['hash'],            'source'   => 'kugou',        );        list($result['artist'], $result['name'])=explode(' - ', $result['name'], 2);        $result['artist']=explode('、', $result['artist']);        return $result;    }    private function format_baidu($data)    {        $result=array(            'id'       => $data['song_id'],            'name'     => $data['title'],            'artist'   => explode(',', $data['author']),            'album'    => $data['album_title'],            'pic_id'   => $data['song_id'],            'url_id'   => $data['song_id'],            'lyric_id' => $data['song_id'],            'source'   => 'baidu',        );        return $result;    }}
 |