diff --git a/README.md b/README.md index 8cdac8b..4e4f2c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -Listen 1 (Chrome Extension) V1.6.1 +Listen 1 (Chrome Extension) V1.6.2 ========== -(最后更新于2018年05月30日) +(最后更新于2018年06月05日) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) @@ -45,6 +45,10 @@ Firefox打包安装 更新日志 ------- +`2018-06-05` +* 增加酷狗音乐的支持 +* 增加全局的快捷键的支持 (代码来自@mu-yu) + `2018-05-30` * 修复QQ音乐无法播放的问题(感谢@noschoollee 提供修复方案) diff --git a/js/app.js b/js/app.js index 06bf648..6b2b06d 100644 --- a/js/app.js +++ b/js/app.js @@ -11,11 +11,11 @@ } var app = angular.module('listenone', ['angularSoundManager', 'ui-notification', 'loWebManager', 'cfp.hotkeys', 'lastfmClient', 'githubClient']) - + app.config( [ '$compileProvider', function( $compileProvider ) - { + { $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|moz-extension|file):/); } ]); @@ -48,7 +48,7 @@ app.run(['angularPlayer', 'Notification', 'loWeb', function(angularPlayer, Notification, loWeb) { angularPlayer.setBootstrapTrack( loWeb.bootstrapTrack( - function(){}, + function(){}, function(){ Notification.info('版权原因无法播放,请搜索其他平台'); }) @@ -66,7 +66,7 @@ break; case 2: return "单曲循环"; - break; + break; } }; }); @@ -81,6 +81,9 @@ if (sourceId == 2) { return 'qq'; } + if (sourceId == 4) { + return 'kugou'; + } } // control main view of page, it can be called any place @@ -109,7 +112,7 @@ $scope.lastfm = lastfm; $scope.github = github; - + $scope.$on('isdoubanlogin:update', function(event, data) { $scope.isDoubanLogin = data; }); @@ -137,7 +140,7 @@ } $scope.is_window_hidden = 0; $scope.resetWindow(); - + if ($scope.window_url_stack.length > 0 && $scope.window_url_stack[$scope.window_url_stack.length-1] == '/now_playing') { // if now playing is top, pop it $scope.window_url_stack.splice(-1,1); @@ -152,7 +155,7 @@ loWeb.get(url).success(function(data) { if (data.status == '0') { - Notification.info(data.reason); + Notification.info(data.reason); $scope.popWindow(); return; } @@ -221,7 +224,7 @@ index = Math.floor(Math.random() * (max - min + 1)) + min; } angularPlayer.playTrack($scope.songs[index].id); - + }); }, 0); }); @@ -306,7 +309,7 @@ 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function() { - Notification.success('添加到歌单成功'); + Notification.success('添加到歌单成功'); $scope.closeDialog(); // add to current playing list if (option_id == $scope.current_list_id) { @@ -338,7 +341,7 @@ } }).success(function() { $rootScope.$broadcast('myplaylist:update'); - Notification.success('添加到歌单成功'); + Notification.success('添加到歌单成功'); $scope.closeDialog(); }); }; @@ -386,7 +389,7 @@ $scope.showPlaylist($scope.list_id); }); }; - + $scope.removeSongFromPlaylist = function(song, list_id) { var url = '/remove_track_from_myplaylist'; @@ -406,7 +409,7 @@ if (index > -1) { $scope.songs.splice(index, 1); } - Notification.success('删除成功'); + Notification.success('删除成功'); }); } @@ -769,7 +772,7 @@ return; } angularPlayer.addTrackArray(localCurrentPlaying); - + var localPlayerSettings = localStorage.getObject('player-settings'); if (localPlayerSettings == null) { return; @@ -1071,11 +1074,12 @@ app.controller('InstantSearchController', ['$scope', '$http', '$timeout', 'angularPlayer', 'loWeb', function($scope, $http, $timeout, angularPlayer, loWeb) { + $scope.originpagelog = [1, 1, 1, 1, 1]; // [网易,虾米,QQ,NULL,酷狗] $scope.tab = 0; $scope.keywords = ''; $scope.loading = false; - $scope.curpagelog = [1,1,1]; // [网易,虾米,QQ] - $scope.totalpagelog = [1,1,1]; + $scope.curpagelog = $scope.originpagelog.slice(0); + $scope.totalpagelog = $scope.originpagelog.slice(0); $scope.curpage = 1; $scope.totalpage = 1; @@ -1107,7 +1111,7 @@ // if searchStr is still the same.. // go ahead and retrieve the data if (tmpStr === $scope.keywords) - { + { performSearch(); } }); @@ -1125,9 +1129,9 @@ function updateCurrentPage(cp){ if(cp === -1){ // when search words changes,pagenums should be reset. - $scope.curpagelog = [1,1,1]; + $scope.curpagelog = $scope.originpagelog.slice(0); $scope.curpage = 1; - } + } else if(cp >= 0) $scope.curpage = $scope.curpagelog[$scope.tab] = cp; else // only tab changed @@ -1136,12 +1140,12 @@ function updateTotalPage(totalItem){ if(totalItem === -1) { - $scope.totalpagelog = [1,1,1]; + $scope.totalpagelog = $scope.originpagelog.slice(0); $scope.totalpage = 1; } else if(totalItem >=0) $scope.totalpage=$scope.totalpagelog[$scope.tab] = Math.ceil(totalItem/20); - else + else //just switch tab $scope.totalpage=$scope.totalpagelog[$scope.tab]; } @@ -1192,11 +1196,11 @@ var headerHeight = 90; var footerHeight = 90; element.css('height', (w.height() - headerHeight - footerHeight) + 'px' ); - }; - w.bind('resize', function () { - changeHeight(); // when window size gets changed - }); - changeHeight(); // when page loads + }; + w.bind('resize', function () { + changeHeight(); // when window size gets changed + }); + changeHeight(); // when page loads }; }); @@ -1284,7 +1288,7 @@ function(angularPlayer, $document, $rootScope) { return function(scope, element, attrs) { var x; - var container; + var container; var mode = attrs.mode; function onMyMousedown() { @@ -1370,8 +1374,8 @@ }; }]); - app.controller('MyPlayListController', ['$http','$scope', '$timeout', - 'angularPlayer', 'loWeb', + app.controller('MyPlayListController', ['$http','$scope', '$timeout', + 'angularPlayer', 'loWeb', function($http, $scope, $timeout, angularPlayer, loWeb){ $scope.myplaylists = []; @@ -1400,7 +1404,7 @@ function($http, $scope, $timeout, angularPlayer, loWeb){ $scope.result = []; $scope.tab = 0; - $scope.loading = true + $scope.loading = true $scope.changeTab = function(newTab){ $scope.tab = newTab; @@ -1435,9 +1439,9 @@ }; }]); - // app.controller('ImportController', ['$http', + // app.controller('ImportController', ['$http', // '$httpParamSerializerJQLike', '$scope', '$interval', - // '$timeout', '$rootScope', 'Notification', 'angularPlayer', + // '$timeout', '$rootScope', 'Notification', 'angularPlayer', // function($http, $httpParamSerializerJQLike, $scope, // $interval, $timeout, $rootScope, Notification, angularPlayer){ // $scope.validcode_url = ""; @@ -1510,8 +1514,8 @@ // $scope.start = function() { // // stops any running interval to avoid two intervals running at the same time - // $scope.stop(); - + // $scope.stop(); + // // store the interval promise // promise = $interval(poll, 1000); // }; diff --git a/js/background.js b/js/background.js index eb865fe..53c81ba 100644 --- a/js/background.js +++ b/js/background.js @@ -15,7 +15,7 @@ function hack_referer_header(details) { referer_value = "http://m.xiami.com/"; } - if ((details.url.indexOf("y.qq.com/") != -1) || + if ((details.url.indexOf("y.qq.com/") != -1) || (details.url.indexOf("qqmusic.qq.com/") != -1) || (details.url.indexOf("music.qq.com/") != -1) || (details.url.indexOf("imgcache.qq.com/") != -1)) { @@ -51,7 +51,7 @@ function hack_referer_header(details) { value: referer_value }); } - + blockingResponse.requestHeaders = headers; return blockingResponse; }; @@ -71,4 +71,4 @@ chrome.runtime.onMessage.addListener( Github.handleCallback(code); sendResponse(); } -); \ No newline at end of file +); diff --git a/js/loweb.js b/js/loweb.js index 34f36ad..1622e62 100644 --- a/js/loweb.js +++ b/js/loweb.js @@ -10,10 +10,13 @@ function getProviderByName(sourceName) { if (sourceName == 'qq') { return qq; } + if (sourceName == 'kugou') { + return kugou; + } } function getAllProviders(){ - return [netease, xiami, qq]; + return [netease, xiami, qq, kugou]; } function getProviderByItemId(itemId) { @@ -27,6 +30,9 @@ function getProviderByItemId(itemId) { if (prefix == 'qq') { return qq; } + if (prefix == 'kg') { + return kugou; + } if (prefix == 'my') { return myplaylist; } @@ -67,7 +73,7 @@ function($rootScope, $log, $http, $httpParamSerializerJQLike) { var url = '/playlist?list_id=' + list_id; return { success: function(fn) { - provider.get_playlist(url, $http, $httpParamSerializerJQLike).success(function(data){ + provider.get_playlist(url, $http, $httpParamSerializerJQLike).success(function(data){ myplaylist.save_myplaylist(data); fn(); }); diff --git a/js/provider/kugou.js b/js/provider/kugou.js new file mode 100644 index 0000000..8435722 --- /dev/null +++ b/js/provider/kugou.js @@ -0,0 +1,370 @@ +var kugou = (function() { + 'use strict'; + + function kg_convert_song(song) { + var track = { + 'id': 'kgtrack_' + song.FileHash, + 'title': song.SongName, + 'artist': '', + 'artist_id': '', + 'album': song.AlbumName, + 'album_id': 'kgalbum_' + song.AlbumID, + 'source': 'kugou', + 'source_url': 'http://www.kugou.com/song/#hash=' + song.FileHash + '&album_id=' + song.AlbumID, + 'img_url': '', + 'url': 'kgtrack_' + song.FileHash, + 'lyric_url': song.FileHash + }; + var singer_id = song.SingerId; + var singer_name = song.SingerName; + if (song.SingerId instanceof Array) { + singer_id = singer_id[0]; + singer_name = singer_name.split('、')[0]; + } + track['artist'] = singer_name; + track['artist_id'] = 'kgartist_' + singer_id; + return track; + } + + var kg_search = function(url, hm, se) { + return { + success: function(fn) { + var keyword = getParameterByName('keywords', url); + var curpage = getParameterByName('curpage', url); + var target_url = "http://songsearch.kugou.com/" + + "song_search_v2?keyword=" + keyword + "&page=" + curpage; + hm({ + url: target_url, + method: 'GET', + transformResponse: undefined + }) + .then(function(response){ + var data = response.data + data = JSON.parse(data); + var tracks = [] + $.each(data.data.lists, function(index, item){ + var track = kg_convert_song(item); + // Add singer img + target_url = 'http://www.kugou.com/yy/index.php?' + + 'r=play/getdata&hash=' + track.lyric_url; + hm({ + url: target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + track.img_url = data.data.img; + }); + tracks.push(track); + }); + return fn({"result": tracks, "total": data.data.total}); + }); + } + }; + } + + var kg_get_playlist = function(url, hm, se) { + return { + success: function(fn) { + var list_id = getParameterByName('list_id', url).split('_').pop(); + var target_url = 'http://m.kugou.com/plist/list/' + list_id + '?json=true'; + + hm.get(target_url).then(function(response){ + var data = response.data; + + var info = { + 'cover_img_url': data.info.list.imgurl ? + data.info.list.imgurl.replace('{size}', '400') : '', + 'title': data.info.list.specialname, + 'id': 'kgplaylist_' + data.info.list.specialid, + 'source_url': 'http://www.kugou.com/yy/special/single/{size}.html' + .replace('{size}', data.info.list.specialid) + }; + + var tracks = []; + $.each(data.list.list.info, function(index, item){ + target_url = 'http://m.kugou.com/app/i/getSongInfo.php?' + + 'cmd=playInfo&hash=' + item.hash; + + var track = { + 'id': 'kgtrack_' + item.hash, + 'title': '', + 'artist': '', + 'artist_id': '', + 'album': '', + 'album_id': 'kgalbum_' + item.album_id, + 'source': 'kugou', + 'source_url': 'http://www.kugou.com/song/#hash=' + + item.hash + '&album_id=' + item.album_id, + 'img_url': '', + 'url': 'xmtrack_' + item.hash, + 'lyric_url': item.hash + }; + // Fix song info + hm.get(target_url).then(function(response){ + var data = response.data; + track['title'] = data.songName; + track['artist'] = data.singerId == 0 ? + '未知' : data.singerName; + track['artist_id'] = 'kgartist_' + data.singerId; + track['img_url'] = data.imgUrl.replace('{size}', '400'); + }); + // Fix album + target_url = 'http://mobilecdnbj.kugou.com/api/v3/album/info?albumid=' + + item.album_id; + hm.get(target_url).then(function(response){ + var data = response.data; + track['album'] = data.status ? data.data.albumname : ''; + }); + tracks.push(track); + }); + return fn({"tracks":tracks, "info":info}); + }); + } + }; + } + + var kg_artist = function(url, hm, se) { + return { + success: function(fn) { + var artist_id = getParameterByName('list_id', url).split('_').pop(); + var target_url = 'http://mobilecdnbj.kugou.com/api/v3/singer/info?singerid=' + artist_id + hm({ + url:target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + var info = { + 'cover_img_url': data.data.imgurl.replace('{size}', '400'), + 'title': data.data.singername, + 'id': 'kgartist_' + artist_id, + 'source_url': 'http://www.kugou.com/singer/{id}.html'.replace('{id}', artist_id) + } + target_url = 'http://mobilecdnbj.kugou.com/api/v3/singer/song?singerid=' + + artist_id + '&page=1&pagesize=30'; + hm({ + url:target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + var tracks = [] + $.each(data.data.info, function(index, item){ + var track = { + 'id': 'kgtrack_' + item.hash, + 'title': '', 'artist': '', 'artist_id': info['id'], + 'album': '', + 'album_id': 'kgalbum_' + item.album_id, + 'source': 'kugou', + 'source_url': 'http://www.kugou.com/song/#hash=' + + item.hash + '&album_id=' + item.album_id, + 'img_url': '', + 'url': 'kgtrack_' + item.hash, + 'lyric_url': item.hash + }; + var one = item.filename.split('-'); + track['title'] = $.trim(one[1]); + track['artist'] = $.trim(one[0]); + // Fix album name and img + target_url = 'http://www.kugou.com/yy/index.php?' + + 'r=play/getdata&hash=' + item.hash; + hm({ + url: 'http://mobilecdnbj.kugou.com/api/v3/album/info?albumid=' + item.album_id, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; data = JSON.parse(data); + track['album'] = data.status ? data.data.albumname : ''; + }); + hm({ + url: target_url, method: 'GET', transformResponse: undefined + }).then(function(response){ + var data = JSON.parse(response.data); + track['img_url'] = data.data.img; + }); + tracks.push(track); + }); + return fn({"tracks":tracks,"info": info}); + }); + }); + } + }; + } + + var kg_bootstrap_track = function(sound, track, success, failure, hm, se) { + var target_url = 'http://trackercdnbj.kugou.com/i/v2/?cmd=23&pid=1&behavior=download'; + var song_id = track.id.slice('kgtrack_'.length); + var key = MD5(song_id + 'kgcloudv2'); + target_url = target_url + '&hash=' + song_id + '&key=' + key; + + hm({ + url: target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + if (data.status) { + sound.url = data.url; + success(); + } else { + failure(); + } + }); + } + + var kg_lyric = function(url, hm, se) { + var track_id = getParameterByName('track_id', url).split('_').pop(); + var lyric_url = 'http://www.kugou.com/yy/index.php?r=play/getdata&hash=' + + track_id; + return { + success: function(fn) { + hm({ + url: lyric_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + return fn({'lyric': data.data.lyrics}); + }); + } + }; + } + + var kg_album = function(url, hm, se) { + return { + success: function(fn) { + var album_id = getParameterByName('list_id', url).split('_').pop(); + var target_url = 'http://mobilecdnbj.kugou.com/api/v3/album/info?' + + 'albumid=' + album_id; + + var info, tracks = []; + // info + hm({ + url: target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + + info = { + 'cover_img_url': data.data.imgurl.replace('{size}', '400'), + 'title': data.data.albumname, + 'id': 'kgalbum_' + data.data.albumid, + 'source_url': 'http://www.kugou.com/album/{id}.html' + .replace('{id}', data.data.albumid) + }; + }); + + target_url = 'http://mobilecdnbj.kugou.com/api/v3/album/song?' + + 'albumid=' + album_id + '&page=1&pagesize=-1' + hm({ + url: target_url, + method: 'GET', + transformResponse: undefined + }).then(function(response){ + var data = response.data; + data = JSON.parse(data); + + $.each(data.data.info, function(index, item){ + var track = { + 'id': 'kgtrack_' + item.hash, + 'title': '', + 'artist': '', + 'artist_id': '', + 'album': info['title'], + 'album_id': 'kgalbum_' + album_id, + 'source': 'kugou', + 'source_url': 'http://www.kugou.com/song/#hash=' + + item.hash + '&album_id=' + album_id, + 'img_url': '', + 'url': 'xmtrack_' + item.hash, + 'lyric_url': item.hash + }; + // Fix other data + target_url = 'http://m.kugou.com/app/i/getSongInfo.php?' + + 'cmd=playInfo&hash=' + item.hash; + hm({ + url: target_url, method: 'GET', transformResponse: undefined + }).then(function(response){ + var data = JSON.parse(response.data); + track['title'] = data.songName; + track['artist'] = data.singerId == 0 ? + '未知' : data.singerName; + track['artist_id'] = 'kgartist_' + data.singerId; + track['img_url'] = data.imgUrl.replace('{size}', '400'); + }); + tracks.push(track); + }); + return fn({"tracks": tracks,"info": info}); + }); + } + }; + } + + var kg_show_playlist = function(url, hm) { + var offset = getParameterByName('offset',url); + if (offset == undefined) { offset = 0; } + var page = offset / 30 + 1; + var target_url = 'http://m.kugou.com/plist/index' + + '&json=true&page=' + offset; + return { + success: function(fn) { + var result = []; + hm.get(target_url).then(function(response){ + var data = response.data; + var total = data.plist.total; + $.each(data.plist.list.info, function(index, item){ + var plist = { + 'cover_img_url': item.imgurl ? item.imgurl.replace('{size}', '400') : '', + 'title': item.specialname, + 'id': 'kgplaylist_' + item.specialid, + 'source_url': 'http://www.kugou.com/yy/special/single/{size}.html'.replace('{size}', item.specialid) + }; + result.push(plist); + }); + return fn({"result":result}); + }); + } + }; + } + + var kg_parse_url = function(url) { + var result = undefined; + var match = /\/\/www.kugou.com\/yy\/special\/single\/([0-9]+).html/.exec(url); + if (match != null) { + var playlist_id = match[1]; + result = {'type': 'playlist', 'id': 'kgplaylist_' + playlist_id}; + } + return result; + } + + var get_playlist = function(url, hm, se) { + var list_id = getParameterByName('list_id', url).split('_')[0]; + if (list_id == 'kgplaylist') { + return kg_get_playlist(url, hm, se); + } + if (list_id == 'kgalbum') { + return kg_album(url, hm, se); + } + if (list_id == 'kgartist') { + return kg_artist(url, hm, se); + } + } + +return { + show_playlist: kg_show_playlist, + get_playlist: get_playlist, + parse_url: kg_parse_url, + bootstrap_track: kg_bootstrap_track, + search: kg_search, + lyric: kg_lyric, +}; + +})(); diff --git a/js/provider/xiami.js b/js/provider/xiami.js index 0e7f2c8..b288580 100644 --- a/js/provider/xiami.js +++ b/js/provider/xiami.js @@ -26,7 +26,7 @@ var xiami = (function() { for (var i=0; i + @@ -227,6 +228,7 @@
虾米
QQ音乐
+
酷狗音乐
@@ -270,6 +272,7 @@
  • 虾米
  • QQ音乐
  • 豆瓣
  • +
  • 酷狗音乐