├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── checkstyle-idea.xml ├── encodings.xml ├── gradle.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── cyl │ │ └── musicapi │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── cyl │ │ │ └── musicapi │ │ │ └── MainActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── cyl │ └── musicapi │ ├── ExampleUnitTest.kt │ └── LeetCode.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── musicapi ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libs │ └── tbs_sdk_thirdapp_v3.6.0.1310_43612_sharewithdownload_withoutGame_obfs_20180706_163319.jar ├── local.properties ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── cyl │ │ └── musicapi │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── dist │ │ │ ├── app.native.js │ │ │ └── dsbridge.js │ │ └── musicApi.html │ ├── java │ │ └── com │ │ │ └── cyl │ │ │ └── musicapi │ │ │ ├── AjaxHandler.kt │ │ │ ├── BaseApiImpl.kt │ │ │ ├── baidu │ │ │ ├── BaiduApiService.kt │ │ │ ├── BaiduArtistInfo.kt │ │ │ ├── BaiduList.kt │ │ │ ├── BaiduMusicList.kt │ │ │ ├── BaiduPlayMv.kt │ │ │ ├── BaiduSearchMerge.kt │ │ │ ├── BaiduSearchSug.kt │ │ │ ├── BaiduSongInfo.kt │ │ │ ├── RadioData.kt │ │ │ └── Suggestion.kt │ │ │ ├── bean │ │ │ ├── ArtistSongsData.kt │ │ │ ├── ArtistsData.kt │ │ │ ├── LyricInfo.kt │ │ │ ├── SearchData.kt │ │ │ ├── SongComment.kt │ │ │ ├── SongUrl.kt │ │ │ └── TopList.kt │ │ │ ├── dsbridge │ │ │ ├── CompletionHandler.java │ │ │ ├── DWebView.java │ │ │ └── OnReturnValue.java │ │ │ ├── kugou │ │ │ ├── KuGouApiService.kt │ │ │ └── KugouLyric.kt │ │ │ ├── netease │ │ │ ├── ArtistsInfo.kt │ │ │ ├── BannerBean.kt │ │ │ ├── CatListBean.kt │ │ │ ├── LoginInfo.kt │ │ │ ├── Mv.kt │ │ │ ├── MvComment.kt │ │ │ ├── MvInfo.kt │ │ │ ├── NeteaseApiService.kt │ │ │ ├── NeteasePlaylist.kt │ │ │ ├── PersonalFM.kt │ │ │ ├── PersonalizedInfo.kt │ │ │ ├── RecommendInfo.kt │ │ │ ├── SearchInfo.kt │ │ │ ├── TopList.kt │ │ │ ├── base │ │ │ │ └── Data.kt │ │ │ └── video │ │ │ │ └── VideoGroup.kt │ │ │ ├── playlist │ │ │ ├── ApiModel.kt │ │ │ ├── ErrorInfo.kt │ │ │ ├── MusicInfo.kt │ │ │ ├── PlaylistApiService.kt │ │ │ ├── PlaylistInfo.kt │ │ │ └── UserInfo.kt │ │ │ ├── qq │ │ │ ├── QQApiKey.java │ │ │ ├── QQApiModel.java │ │ │ ├── QQApiService.kt │ │ │ ├── QQApiServiceImpl.java │ │ │ └── QQLyricInfo.java │ │ │ └── xiami │ │ │ ├── XiamiModel.java │ │ │ ├── XiamiService.java │ │ │ └── XiamiServiceImpl.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── cyl │ └── musicapi │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 36 | 37 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MusicApi 2 | 3 | [![](https://jitpack.io/v/caiyonglong/musicapi.svg)](https://jitpack.io/#caiyonglong/musicapi) 4 | 5 | ## 主要功能点 6 | 7 | - 封装网易云、百度音乐、虾米音乐、QQ音乐Api 8 | - 通过[DSBridge for Android](https://github.com/wendux/DSBridge-Android) 解决Android跨域问题,Android端解析调用[js音乐API](https://github.com/sunzongzheng/musicApi)的api 9 | - 增加NeteaseMusicApi接口 10 | - 具体的接口实现请看主项目 [MusicLake](https://github.com/caiyonglong/MusicLake) 11 | 12 | ## DSbridge使用 13 | 通过BaseApiImpl,调用js方法拼接api请求地址,然后AjaxHandler收到请求地址,再通过okhhtp请求,获取返回数据,然后在回到js组装返回数据。最后返回一个json字符串,在BaseApiImpl 回调方法中gson解析成具体对象。 14 | 15 | 16 | ## 更新记录 17 | 18 | - 1.1.4 19 | - 更新字段类型长整型,导致歌单列表数据解析异常问题。 20 | - 1.1.2 21 | - 新增getAllNeteaseTopList、getAllQQTopList、getQQTopList、getTopList接口 22 | - 1.1.1 23 | - 更新netease接口字段解析 24 | 25 | 26 | 27 | ## Usage 28 | 29 | Step 1. Add the JitPack repository to your build file 30 | ​```gradle 31 | allprojects { 32 | repositories { 33 | ... 34 | maven { url 'https://jitpack.io' } 35 | } 36 | } 37 | ``` 38 | Step 2. Add the dependency 39 | 40 | ​```gradle 41 | 42 | dependencies { 43 | implementation 'com.github.caiyonglong:musicapi:1.1.4' 44 | } 45 | 46 | ``` 47 | 48 | 49 | ## 提示 50 | 51 | - assets/dist/app.native.js文件更新,同步[sunzongzheng/musicApi/dist/app.native.js](https://github.com/sunzongzheng/musicApi/blob/master/dist/app.native.js) 52 | 53 | 54 | 55 | ## API 56 | 57 | - 百度音乐Api接口定义 : BaiduApiService(具体实现在MusicLake) 58 | 59 | - 网易音乐Api接口定义 : NeteaseApiService(具体实现在MusicLake) 60 | 61 | - 在线歌单Api接口定义 : PlaylistApiService(具体实现在MusicLake) 62 | 63 | - 音乐播放Api接口[app.native.js](musicapi/src/main/assets/dist/app.native.js) : 同PC端Api接口[sunzongzheng/musicApi/dist/app.native.js](https://github.com/sunzongzheng/musicApi/blob/master/dist/app.native.js) 64 | 为了节省时间,减少维护成本,PC端和Android端使用同一api js,使用 DSbridge 解决Android跨域问题, 实现Android js交互 65 | 66 | - **BaseApiImpl**接口详情: 67 | 68 | - 搜索 69 | ``` 70 | /** 71 | * 搜索 72 | * 73 | * @param query 搜索文本 74 | * @param limit 每页多少歌曲 75 | * @param offset 偏移量 76 | * @param success 结果返回回调 77 | * @param fail 失败返回回调 78 | */ 79 | fun searchSong(query: String, limit: Int, offset: Int, success: (result: SearchData) -> Unit, fail: ((String?) -> Unit)? = null) { 80 | ..... 81 | } 82 | ``` 83 | - 按歌曲类型搜索 84 | ``` 85 | /** 86 | * 独立请求 87 | * @param query 搜索文本 88 | * @param type 歌曲类型 [QQ,XIAMI,NETEASE] 89 | * @param limit 每页多少歌曲 90 | * @param offset 偏移量 91 | * @param success 结果返回回调 92 | */ 93 | fun searchSongSingle(query: String, type: String, limit: Int, offset: Int, success: (result: SearchSingleData) -> Unit) { 94 | ..... 95 | } 96 | ``` 97 | - 获取歌曲详情 98 | ``` 99 | /** 100 | * 获取歌曲详情 101 | * @param vendor 歌曲类型 [qq,xiami,netease] 102 | * @param id 歌曲Id 103 | * @param success 结果返回回调 104 | * @param fail 失败返回回调 105 | */ 106 | fun getSongDetail(vendor: String, id: String, success: (result: SongDetail) -> Unit, fail: (() -> Unit)? = null) { 107 | ..... 108 | } 109 | ``` 110 | - 批量获取歌曲详情 111 | ``` 112 | /** 113 | * 批量获取歌曲详情 114 | * 115 | * @param vendor 歌曲类型 [qq,xiami,netease] 116 | * @param ids 歌曲Ids [101126,16435051,139808] 117 | * @param success 成功回调 118 | */ 119 | fun getBatchSongDetail(vendor: String, ids: Array, success: (result: BatchSongDetail) -> Unit) { 120 | ..... 121 | } 122 | ``` 123 | - 获取歌词信息 124 | ``` 125 | /** 126 | * 获取歌词信息 127 | * 128 | * @param vendor 歌曲类型 [qq,xiami,netease] 129 | * @param success 成功回调 130 | */ 131 | fun getLyricInfo(vendor: String, id: String, success: (result: LyricData) -> Unit) { 132 | ..... 133 | } 134 | ``` 135 | - 获取评论信息 136 | ``` 137 | /** 138 | * 获取评论信息 139 | * 140 | * @param vendor 歌曲类型 [qq,xiami,netease] 141 | * @param id 歌曲Id 142 | * @param success 成功回调 143 | */ 144 | fun getComment(vendor: String, id: String, success: (result: Any) -> Unit, fail: ((String) -> Unit)? = null) { 145 | ..... 146 | } 147 | ``` 148 | - 获取播放地址 149 | ``` 150 | /** 151 | * 获取播放地址 152 | * @param vendor 歌曲类型 [qq,xiami,netease] 153 | * @param id 歌曲Id 154 | * @param br 音质 默认12800 155 | * @param success 成功回调 156 | * @param fail 失败回调 157 | */ 158 | fun getSongUrl(vendor: String, id: String, br: Int = 128000, success: (result: SongBean) -> Unit, fail: (() -> Unit)? = null) { 159 | ..... 160 | } 161 | ``` 162 | - 获取歌手单曲列表 163 | ``` 164 | /** 165 | * 获取歌手单曲列表 166 | * @param vendor 歌曲类型 [qq,xiami,netease] 167 | * @param id 歌手ID 168 | * @param offset 偏移量 169 | * @param limit 每页限制 170 | * @param success 成功回调 171 | * @param fail 失败回调 172 | */ 173 | fun getArtistSongs(vendor: String, id: String, offset: Int, limit: Int, success: (result: ArtistSongsData) -> Unit, fail: ((String) -> Unit)? = null) { 174 | ..... 175 | } 176 | ``` 177 | - 获取歌单详情 178 | ``` 179 | /** 180 | * 获取歌单歌曲列表 181 | * @param vendor 歌曲类型 [qq,xiami,netease] 182 | * @param id 专辑ID 183 | * @param success 成功回调 184 | * @param fail 失败回调 185 | */ 186 | fun getPlaylistDetail(vendor: String, id: String, success: (result: ArtistSongs) -> Unit, fail: ((String) -> Unit)? = null) { 187 | ... 188 | } 189 | ``` 190 | - 获取专辑详情 191 | ``` 192 | /** 193 | * 获取专辑详情 194 | * @param vendor 歌曲类型 [qq,xiami,netease] 195 | * @param id 专辑ID 196 | * @param success 成功回调 197 | * @param fail 失败回调 198 | */ 199 | fun getAlbumDetail(vendor: String, id: String, success: (result: AlbumData) -> Unit, fail: ((String) -> Unit)? = null) { 200 | ..... 201 | } 202 | ``` 203 | - 获取歌手列表详情 204 | ``` 205 | /** 206 | * 获取歌手列表详情(qq歌手列表) 207 | * @param offset 偏移量 208 | * @param params 例:val params = mapOf("area" to area, "sex" to sex, "genre" to genre, "index" to index) 209 | * @param success 成功回调 210 | * @param fail 失败回调 211 | */ 212 | fun getArtists(offset: Int, params: Any, success: (result: ArtistsData) -> Unit, fail: ((String) -> Unit)? = null) { 213 | ..... 214 | } 215 | ``` 216 | - 获取任意平台歌手详情 217 | ``` 218 | /** 219 | * 获取任意平台歌手详情 220 | * id,专辑ID 221 | * @param ids 歌手ID列表 map(id,vendor) 歌手id 和 歌曲类型 [qq,xiami,netease] 222 | * @param success 成功回调 223 | * @param fail 失败回调 224 | */ 225 | fun getAnyVendorSongDetail(ids: MutableList>, success: (result: MutableList) -> Unit, fail: ((String) -> Unit)? = null) { 226 | ..... 227 | } 228 | ``` 229 | - 获取QQ音乐排行榜 230 | ``` 231 | fun getAllQQTopList(success: (result: List) -> Unit, fail: ((String) -> Unit)? = null) { 232 | ... 233 | } 234 | ``` 235 | - 获取网易云排行榜 236 | ``` 237 | fun getAllNeteaseTopList(success: (result: List) -> Unit, fail: ((String) -> Unit)? = null) { 238 | ... 239 | } 240 | ``` 241 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'kotlin-android-extensions' 5 | android { 6 | compileSdkVersion 29 7 | defaultConfig { 8 | applicationId "com.cyl.musicapi" 9 | minSdkVersion 21 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(dir: 'libs', include: ['*.jar']) 25 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 26 | implementation 'com.android.support:appcompat-v7:27.1.1' 27 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 28 | testImplementation 'junit:junit:4.12' 29 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 30 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 31 | 32 | // api project(':musicapi') 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/cyl/musicapi/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.cyl.musicapi", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/cyl/musicapi/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | class MainActivity : AppCompatActivity() { 7 | 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_main) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MusicApi 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/cyl/musicapi/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | 17 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 5)) 18 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 2)) 19 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 7)) 20 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 6)) 21 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 0)) 22 | // println(searchInsert(intArrayOf(1, 3, 5, 6), 1)) 23 | // println(searchInsert(intArrayOf(1, 3,x 5, 6), 3)) 24 | val result = mySqrt(3) 25 | // println("${result[0]},${result[1]}") 26 | println("$result") 27 | } 28 | 29 | 30 | /** 31 | * LeetCode 35. 搜索插入位置 32 | * 二分查找算法 33 | * 一个数组,两个标记,分别从两头往中间扫描 34 | */ 35 | fun searchInsert(nums: IntArray, target: Int): Int { 36 | var low = 0 37 | var high = nums.size - 1 38 | while (low <= high) { 39 | val middle = (low + high) / 2 40 | when { 41 | target == nums[middle] -> return middle 42 | target < nums[middle] -> high = middle - 1 43 | else -> low = middle + 1 44 | } 45 | } 46 | return low 47 | } 48 | 49 | 50 | /** 51 | * LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置 52 | * 二分查找算法 53 | */ 54 | fun searchRange(nums: IntArray, target: Int): IntArray { 55 | val array = intArrayOf(-1, -1) 56 | var low = 0 57 | var high = nums.size - 1 58 | var tmp = -1 59 | while (low <= high) { 60 | val middle = low + (-low + high) / 2 61 | if (target == nums[middle]) { 62 | //最小 63 | tmp = middle 64 | break 65 | } else if ( 66 | target < nums[middle]) { 67 | high = middle - 1 68 | } else { 69 | low = middle + 1 70 | } 71 | } 72 | 73 | if (tmp != -1) { 74 | array[0]= tmp 75 | array[1]= tmp 76 | while (array[0] > 0 && nums[array[0] - 1] == target) array[0]-- 77 | while (array[1] < nums.size - 1 && nums[array[1] + 1] == target) array[1]++ 78 | } 79 | return array 80 | } 81 | 82 | /** 83 | * x 的平方根 84 | */ 85 | fun mySqrt(x: Int): Int { 86 | var start =0 87 | if(x==0||x==1) return x 88 | var end= x 89 | while(startx/mid){ 92 | end = mid 93 | }else{ 94 | start = mid+1 95 | } 96 | } 97 | return end-1 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/test/java/com/cyl/musicapi/LeetCode.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi; 2 | 3 | import org.junit.Test; 4 | 5 | public class LeetCode { 6 | 7 | @Test 8 | public void test() { 9 | 10 | } 11 | 12 | public int guessNumber(int n) { 13 | int start = 1; 14 | int end = n; 15 | while (true) { 16 | int mid = start + (end - start) / 2; 17 | int res = guess(mid); 18 | if (res == -1) { 19 | end = mid - 1; 20 | } else if (res == 0) { 21 | return mid; 22 | } else if (res == 1) { 23 | start = mid + 1; 24 | } 25 | } 26 | } 27 | 28 | public int firstBadVersion(int n) { 29 | int start = 1; 30 | int end = n; 31 | while (start <= end) { 32 | int mid = start + (end - start) / 2; 33 | boolean res = isBadVersion(mid); 34 | if (res) { 35 | if(!isBadVersion(mid-1)){ 36 | return mid-1; 37 | }else { 38 | end = mid - 1; 39 | } 40 | } else { 41 | start = mid + 1; 42 | } 43 | } 44 | return 1; 45 | } 46 | 47 | /** 48 | * -1 : 我的数字比较小 49 | * 1 : 我的数字比较大 50 | * 0 : 恭喜!你猜对了! 51 | * 52 | * @param num 53 | * @return 54 | */ 55 | int guess(int num) { 56 | return 1; 57 | } 58 | 59 | boolean isBadVersion(int num) { 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.3.72' 5 | repositories { 6 | google() 7 | jcenter() 8 | maven { url "https://jitpack.io" } 9 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.1.0' 12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | google() 22 | jcenter() 23 | maven { url "https://jitpack.io" } 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | android.useAndroidX=true 15 | android.enableJetifier=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Aug 18 01:17:06 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /musicapi/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.idea -------------------------------------------------------------------------------- /musicapi/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'kotlin-android-extensions' 5 | 6 | //apply plugin: 'com.github.dcendents.android-maven' 7 | 8 | group = 'com.github.caiyonglong' 9 | android { 10 | compileSdkVersion 28 11 | 12 | defaultConfig { 13 | minSdkVersion 21 14 | targetSdkVersion 28 15 | versionCode 5 16 | versionName "1.0.4" 17 | 18 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 19 | 20 | } 21 | 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | 29 | } 30 | ext.retrofit_version = '2.4.0' 31 | ext.kotlin_version = '1.3.31' 32 | dependencies { 33 | implementation fileTree(include: ['*.jar'], dir: 'libs') 34 | 35 | implementation 'com.squareup.okhttp3:okhttp:3.12.6' 36 | implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0' 37 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 38 | testImplementation 'junit:junit:4.12' 39 | androidTestImplementation 'androidx.test:runner:1.2.0' 40 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 41 | implementation 'com.google.code.gson:gson:2.8.5' 42 | implementation 'io.reactivex.rxjava2:rxjava:2.2.10' 43 | implementation "com.squareup.retrofit2:retrofit:$retrofit_version" 44 | implementation files('libs/tbs_sdk_thirdapp_v3.6.0.1310_43612_sharewithdownload_withoutGame_obfs_20180706_163319.jar') 45 | 46 | implementation 'androidx.appcompat:appcompat:1.1.0' 47 | } 48 | 49 | // build a jar with source files 50 | //task sourcesJar(type: Jar) { 51 | // from android.sourceSets.main.java.srcDirs 52 | // classifier = 'sources' 53 | //} 54 | // 55 | //task javadoc(type: Javadoc) { 56 | // failOnError false 57 | // source = android.sourceSets.main.java.sourceFiles 58 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 59 | // classpath += configurations.compile 60 | //} 61 | // 62 | //// build a jar with javadoc 63 | //task javadocJar(type: Jar, dependsOn: javadoc) { 64 | // classifier = 'javadoc' 65 | // from javadoc.destinationDir 66 | //} 67 | // 68 | //artifacts { 69 | // archives sourcesJar 70 | // archives javadocJar 71 | //} 72 | -------------------------------------------------------------------------------- /musicapi/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/musicapi/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /musicapi/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 23 19:05:42 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /musicapi/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /musicapi/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /musicapi/libs/tbs_sdk_thirdapp_v3.6.0.1310_43612_sharewithdownload_withoutGame_obfs_20180706_163319.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caiyonglong/MusicApi/880067a5d6a3e959c613ddff070cc1385a54d71d/musicapi/libs/tbs_sdk_thirdapp_v3.6.0.1310_43612_sharewithdownload_withoutGame_obfs_20180706_163319.jar -------------------------------------------------------------------------------- /musicapi/local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Fri Aug 23 19:05:36 CST 2019 8 | sdk.dir=/Users/caiyonglong/Library/Android/sdk 9 | -------------------------------------------------------------------------------- /musicapi/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /musicapi/src/androidTest/java/com/cyl/musicapi/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.cyl.musicapi.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /musicapi/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /musicapi/src/main/assets/dist/dsbridge.js: -------------------------------------------------------------------------------- 1 | var bridge={default:this,call:function(b,a,c){var e="";"function"==typeof a&&(c=a,a={});a={data:void 0===a?null:a};if("function"==typeof c){var g="dscb"+window.dscb++;window[g]=c;a._dscbstub=g}a=JSON.stringify(a);if(window._dsbridge)e=_dsbridge.call(b,a);else if(window._dswk||-1!=navigator.userAgent.indexOf("_dsbridge"))e=prompt("_dsbridge="+b,a);return JSON.parse(e||"{}").data},register:function(b,a,c){c=c?window._dsaf:window._dsf;window._dsInit||(window._dsInit=!0,setTimeout(function(){bridge.call("_dsb.dsinit")}, 2 | 0));"object"==typeof a?c._obs[b]=a:c[b]=a},registerAsyn:function(b,a){this.register(b,a,!0)},hasNativeMethod:function(b,a){return this.call("_dsb.hasNativeMethod",{name:b,type:a||"all"})},disableJavascriptDialogBlock:function(b){this.call("_dsb.disableJavascriptDialogBlock",{disable:!1!==b})}}; 3 | !function(){if(!window._dsf){var b={_dsf:{_obs:{}},_dsaf:{_obs:{}},dscb:0,dsBridge:bridge,close:function(){bridge.call("_dsb.closePage")},_handleMessageFromNative:function(a){var e=JSON.parse(a.data),b={id:a.callbackId,complete:!0},c=this._dsf[a.method],d=this._dsaf[a.method],h=function(a,c){b.data=a.apply(c,e);bridge.call("_dsb.returnValue",b)},k=function(a,c){e.push(function(a,c){b.data=a;b.complete=!1!==c;bridge.call("_dsb.returnValue",b)});a.apply(c,e)};if(c)h(c,this._dsf);else if(d)k(d,this._dsaf); 4 | else if(c=a.method.split("."),!(2>c.length)){a=c.pop();var c=c.join("."),d=this._dsf._obs,d=d[c]||{},f=d[a];f&&"function"==typeof f?h(f,d):(d=this._dsaf._obs,d=d[c]||{},(f=d[a])&&"function"==typeof f&&k(f,d))}}},a;for(a in b)window[a]=b[a];bridge.register("_hasJavascriptMethod",function(a,b){b=a.split(".");if(2>b.length)return!(!_dsf[b]&&!_dsaf[b]);a=b.pop();b=b.join(".");return(b=_dsf._obs[b]||_dsaf._obs[b])&&!!b[a]})}}();//module.exports=bridge; -------------------------------------------------------------------------------- /musicapi/src/main/assets/musicApi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/AjaxHandler.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi 2 | 3 | import android.util.Base64 4 | import android.util.Log 5 | import com.cyl.musicapi.dsbridge.CompletionHandler 6 | import okhttp3.* 7 | import org.json.JSONObject 8 | import java.io.IOException 9 | import java.util.* 10 | import java.util.concurrent.TimeUnit 11 | 12 | //import wendu.dsbridge.CompletionHandler 13 | 14 | 15 | /** 16 | * Created by master on 2018/5/12. 17 | * Android 调用JS接口,返回的请求数据 18 | */ 19 | 20 | object AjaxHandler { 21 | val TAG = "AjaxHandler" 22 | fun onAjaxRequest(requestData: JSONObject, handler: CompletionHandler) { 23 | Log.d(TAG, "onAjaxRequest-----$requestData") 24 | // 定义响应数据结构 25 | val responseData = HashMap() 26 | responseData["statusCode"] = 0 27 | 28 | try { 29 | //获取超时时间 30 | val timeout = requestData.getInt("timeout") 31 | //新建okHttp请求 32 | val okHttpClient = OkHttpClient.Builder() 33 | .connectTimeout(timeout.toLong(), TimeUnit.MILLISECONDS) 34 | .build() 35 | 36 | // 判断是否需要加密返回结果,并且当responseType是数据流的时候加密 37 | var contentType = "" 38 | var encode = false 39 | val responseType = requestData.optString("responseType", null) 40 | if (responseType != null && responseType == "stream") { 41 | encode = true 42 | } 43 | 44 | val rb = Request.Builder() 45 | rb.url(requestData.getString("url")) 46 | val headers = requestData.getJSONObject("headers") 47 | 48 | // 设置请求头 49 | val iterator = headers.keys() 50 | while (iterator.hasNext()) { 51 | val key = iterator.next() as String 52 | val value = headers.getString(key) 53 | val lKey = key.toLowerCase() 54 | if (lKey == "cookie") { 55 | // Here you can use CookieJar to manage cookie in a unified way with you native code. 56 | // CookieManager cookieManager = CookieManager.getDefault().get(requestData.getString("url"), value) 57 | } 58 | if (lKey.toLowerCase() == "content-type") { 59 | contentType = value 60 | } 61 | rb.header(key, value) 62 | } 63 | 64 | // 新建POST的请求体 65 | if (requestData.getString("method") == "POST") { 66 | var data = "" 67 | if (requestData.getString("body") != null) { 68 | data = requestData.getString("body") 69 | } 70 | val requestBody = RequestBody 71 | .create(MediaType.parse(contentType), data) 72 | rb.post(requestBody) 73 | } 74 | // 创建并发送HTTP请求 75 | val call = okHttpClient.newCall(rb.build()) 76 | val finalEncode = encode 77 | call.enqueue(object : Callback { 78 | override fun onFailure(call: Call, e: IOException) { 79 | //失败返回 80 | responseData["responseText"] = e.message 81 | Log.e(TAG, "onFailure:----$responseData") 82 | handler.complete(JSONObject(responseData).toString()) 83 | } 84 | 85 | @Throws(IOException::class) 86 | override fun onResponse(call: Call, response: Response) { 87 | //成功返回 88 | 89 | 90 | val data: String = if (finalEncode) { 91 | Base64.encodeToString(response.body()!!.bytes(), Base64.DEFAULT) 92 | } else { 93 | response.body()!!.string() 94 | } 95 | Log.d(TAG, "onResponse:----$responseData") 96 | 97 | //如果需要编码,结果将由Base64编码并返回 If encoding is needed, the result is encoded by Base64 and returned 98 | Log.e("TAG", "onResponse:-----$data") 99 | responseData["responseText"] = data 100 | responseData["statusCode"] = response.code() 101 | responseData["statusMessage"] = response.message() 102 | val responseHeaders = response.headers().toMultimap() 103 | responseData["headers"] = responseHeaders 104 | 105 | Log.d(TAG, "onResponse:-----$responseData") 106 | handler.complete(JSONObject(responseData).toString()) 107 | } 108 | }) 109 | 110 | } catch (e: Exception) { 111 | Log.e("TAG", "抛出异常-----" + e.message) 112 | responseData["responseText"] = "音乐接口异常,${e.message}" 113 | handler.complete(JSONObject(responseData).toString()) 114 | } 115 | 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduApiService.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | import io.reactivex.Observable 4 | import okhttp3.ResponseBody 5 | import retrofit2.http.* 6 | 7 | /** 8 | * Created by yonglong on 2018/1/21. 9 | */ 10 | 11 | interface BaiduApiService { 12 | companion object { 13 | const val V1_TING = "v1/restserver/ting" 14 | 15 | const val SEARCH_CATALOGSUG = "baidu.ting.search.catalogSug" 16 | const val SEARCH_SUGGESTION = "baidu.ting.search.suggestion" 17 | const val SONG_LRC = "baidu.ting.song.lry " 18 | const val SONG_PLAY = "baidu.ting.song.play" 19 | const val GET_SONGINFO = "baidu.ting.song.getInfos" 20 | const val GET_ARTISTINFO = "baidu.ting.artist.getinfo" //获取歌手信息 21 | const val GET_ARTISTSONGLIST = "baidu.ting.artist.getSongList" //获取歌手的歌曲列表 22 | const val GET_ARTISTALUBMLIST = "baidu.ting.artist.getAlbumList" //获取歌手的专辑列表; 23 | const val GET_ALBUMINFO = "baidu.ting.album.getAlbumInfo" 24 | const val QUERY_MERGE = "baidu.ting.search.merge" 25 | const val GET_PLAY_MV = "baidu.ting.mv.playMV" 26 | 27 | const val GET_CATEGORY_LIST = "baidu.ting.radio.getCategoryList" 28 | const val GET_CHANNEL_SONG = "baidu.ting.radio.getChannelSong" 29 | 30 | const val GET_BILLCATEGORY = "baidu.ting.billboard.billCategory" //榜单 31 | const val GET_BILL_LIST = "baidu.ting.billboard.billList" 32 | 33 | const val PAGESIZE = 20 34 | 35 | fun getDownloadUrlBySongId(songId: String): String { 36 | return "http://ting.baidu.com/data/music/links?songIds=$songId" 37 | } 38 | } 39 | 40 | 41 | /** 42 | * 获取电台列表 43 | */ 44 | @GET("$V1_TING?version=5.6.5.0&method=$GET_CATEGORY_LIST") 45 | fun getRadioChannels(): Observable 46 | 47 | 48 | /** 49 | * 获取歌词 50 | */ 51 | @GET 52 | fun getBaiduLyric(@Url baseUrl: String): Observable 53 | 54 | /** 55 | * 获取歌手信息 56 | */ 57 | @GET("$V1_TING?method=$GET_ARTISTINFO") 58 | fun getArtistInfo(@Query("tinguid") tinguid: String, 59 | @Query("artistid") artistid: String): Observable 60 | 61 | 62 | /** 63 | * 获取音乐榜单 64 | */ 65 | @GET("$V1_TING?method=$GET_BILLCATEGORY") 66 | fun getBillPlaylist(): Observable 67 | 68 | /** 69 | * 获取音乐榜单歌曲列表 70 | */ 71 | @GET("$V1_TING?method=$GET_BILL_LIST") 72 | fun getBillMusicList(@Query("type") type: String, 73 | @Query("size") size: Int, 74 | @Query("offset") offset: Int): Observable 75 | 76 | 77 | @GET("$V1_TING?method=$SONG_PLAY") 78 | fun querySong(@Query("songid") songId: String): Observable 79 | 80 | /** 81 | * 搜索建议 82 | */ //http://musicapi.qianqian.com/v1/restserver/ting?method=baidu.ting.search.suggestion&query=Music 83 | @GET("$V1_TING?method=$SEARCH_SUGGESTION") 84 | fun getSearchSuggestion(@Query("query") query: String): Observable 85 | 86 | @GET("$V1_TING?method=$SEARCH_CATALOGSUG") 87 | fun querySug(@Query("query") query: String): Observable 88 | 89 | /** 90 | * 搜索 91 | */ 92 | @GET("$V1_TING?method=$QUERY_MERGE") 93 | fun queryMerge(@Query("query") query: String, 94 | @Query("page_no") pageNo: Int, 95 | @Query("page_size") pageSize: Int): Observable 96 | 97 | /** 98 | * 获取电台歌曲 99 | */ 100 | @GET("$V1_TING?version=5.6.5.0&method=$GET_CHANNEL_SONG") 101 | fun getRadioChannelSongs( 102 | @Query("channelname") channelName: String, 103 | @Query("pn") pn: Int = 0, 104 | @Query("rn") rn: Int = 10 105 | ): Observable 106 | 107 | /** 108 | * 获取mv信息 109 | */ 110 | @GET("$V1_TING?from=qianqian&method=$GET_PLAY_MV") 111 | fun getPlayMv(@Query("song_id") songId: String?): Observable 112 | 113 | /** 114 | * 获取歌曲信息 115 | */ 116 | @GET 117 | fun getTingSongInfo(@Url baseUrl: String): Observable 118 | 119 | @GET 120 | fun getTingSongLink(@Url baseUrl: String): Observable 121 | 122 | @Streaming 123 | @GET 124 | fun downloadFile(@Url downloadUrl: String, @HeaderMap params: Map): Observable 125 | 126 | /** 127 | * 获取歌手歌曲列表和基本信息 128 | */ 129 | @GET("$V1_TING?method=$GET_ARTISTSONGLIST") 130 | fun getArtistSongList(@Query("tinguid") tinguid: String, 131 | @Query("offset") offset: Int, 132 | @Query("limits") limits: Int = PAGESIZE): Observable 133 | 134 | /** 135 | * 获取歌手专辑列表 136 | */ 137 | @GET("$V1_TING?method=$GET_ARTISTALUBMLIST") 138 | fun getArtistAlbumList(@Query("tinguid") tinguid: String, 139 | @Query("offset") offset: Int, 140 | @Query("limits") limits: Int = PAGESIZE) 141 | : Observable 142 | 143 | /** 144 | * 获取专辑信息 145 | */ 146 | @GET("$V1_TING?method=$GET_ALBUMINFO") 147 | fun getAlbumInfo(@Query("album_id") albumId: String): Observable 148 | 149 | /** 150 | * 搜索歌词 151 | */ 152 | @GET("$V1_TING?method=$SONG_LRC") 153 | fun queryLrc(@Query("songid") songId: String): Observable 154 | 155 | } 156 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduArtistInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class BaiduArtistInfo(@SerializedName("comment_num") 7 | val commentNum: Int = 0, 8 | @SerializedName("country") 9 | val country: String = "", 10 | @SerializedName("piao_id") 11 | val piaoId: String = "", 12 | @SerializedName("gender") 13 | val gender: String = "", 14 | @SerializedName("albums_total") 15 | val albumsTotal: String = "", 16 | @SerializedName("collect_num") 17 | val collectNum: Int = 0, 18 | @SerializedName("source") 19 | val source: String = "", 20 | @SerializedName("hot") 21 | val hot: String = "", 22 | @SerializedName("avatar_s180") 23 | val avatarS180: String = "", 24 | @SerializedName("is_collect") 25 | val isCollect: Int = 0, 26 | @SerializedName("bloodtype") 27 | val bloodtype: String = "", 28 | @SerializedName("constellation") 29 | val constellation: String = "", 30 | @SerializedName("listen_num") 31 | val listenNum: String = "", 32 | @SerializedName("avatar_mini") 33 | val avatarMini: String = "", 34 | @SerializedName("intro") 35 | val intro: String = "", 36 | @SerializedName("nickname") 37 | val nickname: String = "", 38 | @SerializedName("company") 39 | val company: String = "", 40 | @SerializedName("mv_total") 41 | val mvTotal: Int = 0, 42 | @SerializedName("avatar_s1000") 43 | val avatarS1000: String = "", 44 | @SerializedName("info") 45 | val info: String = "", 46 | @SerializedName("share_num") 47 | val shareNum: Int = 0, 48 | @SerializedName("area") 49 | val area: String = "", 50 | @SerializedName("avatar_s500") 51 | val avatarS: String = "", 52 | @SerializedName("avatar_big") 53 | val avatarBig: String = "", 54 | @SerializedName("weight") 55 | val weight: String = "", 56 | @SerializedName("birth") 57 | val birth: String = "", 58 | @SerializedName("avatar_middle") 59 | val avatarMiddle: String = "", 60 | @SerializedName("avatar_small") 61 | val avatarSmall: String = "", 62 | @SerializedName("artist_id") 63 | val artistId: String = "", 64 | @SerializedName("url") 65 | val url: String = "", 66 | @SerializedName("firstchar") 67 | val firstchar: String = "", 68 | @SerializedName("aliasname") 69 | val aliasname: String = "", 70 | @SerializedName("songs_total") 71 | val songsTotal: String = "", 72 | @SerializedName("stature") 73 | val stature: String = "", 74 | @SerializedName("name") 75 | val name: String = "", 76 | @SerializedName("ting_uid") 77 | val tingUid: String = "") 78 | 79 | data class ArtistAlbumList( 80 | @SerializedName("albumlist") 81 | val albumlist: List?, 82 | @SerializedName("albumnums") 83 | val albumnums: String, 84 | @SerializedName("havemore") 85 | val havemore: Int 86 | ) 87 | 88 | data class Albumlist( 89 | @SerializedName("album_id") 90 | val albumId: String, 91 | @SerializedName("all_artist_id") 92 | val allArtistId: String, 93 | @SerializedName("all_artist_ting_uid") 94 | val allArtistTingUid: Any, 95 | @SerializedName("area") 96 | val area: Any, 97 | @SerializedName("artist_id") 98 | val artistId: String, 99 | @SerializedName("artist_ting_uid") 100 | val artistTingUid: String, 101 | @SerializedName("author") 102 | val author: String, 103 | @SerializedName("country") 104 | val country: String, 105 | @SerializedName("favorites_num") 106 | val favoritesNum: Any, 107 | @SerializedName("gender") 108 | val gender: Any, 109 | @SerializedName("hot") 110 | val hot: String, 111 | @SerializedName("info") 112 | val info: String, 113 | @SerializedName("language") 114 | val language: String, 115 | @SerializedName("pic_big") 116 | val picBig: String, 117 | @SerializedName("pic_radio") 118 | val picRadio: String, 119 | @SerializedName("pic_s180") 120 | val picS180: String, 121 | @SerializedName("pic_small") 122 | val picSmall: String, 123 | @SerializedName("prodcompany") 124 | val prodcompany: Any, 125 | @SerializedName("publishcompany") 126 | val publishcompany: String, 127 | @SerializedName("publishtime") 128 | val publishtime: String, 129 | @SerializedName("recommend_num") 130 | val recommendNum: Any, 131 | @SerializedName("songs_total") 132 | val songsTotal: String, 133 | @SerializedName("style_id") 134 | val styleId: Any, 135 | @SerializedName("styles") 136 | val styles: String, 137 | @SerializedName("title") 138 | val title: String 139 | ) 140 | 141 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduList.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class BaiduList(@SerializedName("error_code") 7 | val errorCode: Int = 0, 8 | @SerializedName("content") 9 | val content: List?) 10 | 11 | 12 | data class ContentItem(@SerializedName("pic_s210") 13 | val picS210: String = "", 14 | @SerializedName("web_url") 15 | val webUrl: String = "", 16 | @SerializedName("pic_s444") 17 | val picS444: String = "", 18 | @SerializedName("name") 19 | val name: String = "", 20 | @SerializedName("count") 21 | val count: Int = 0, 22 | @SerializedName("comment") 23 | val comment: String = "", 24 | @SerializedName("type") 25 | val type: Int = 0, 26 | @SerializedName("pic_s192") 27 | val picS192: String = "", 28 | @SerializedName("content") 29 | val content: List?, 30 | @SerializedName("pic_s260") 31 | val picS260: String = "") 32 | 33 | data class Item(@SerializedName("all_rate") 34 | val allRate: String = "", 35 | @SerializedName("song_id") 36 | val songId: String = "", 37 | @SerializedName("rank_change") 38 | val rankChange: String = "", 39 | @SerializedName("biaoshi") 40 | val biaoshi: String = "", 41 | @SerializedName("author") 42 | val author: String = "", 43 | @SerializedName("album_id") 44 | val albumId: String = "", 45 | @SerializedName("title") 46 | val title: String = "", 47 | @SerializedName("album_title") 48 | val albumTitle: String = "") 49 | 50 | 51 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduMusicList.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class SongListItem(@SerializedName("piao_id") 7 | val piaoId: String = "", 8 | @SerializedName("resource_type_ext") 9 | val resourceTypeExt: String = "", 10 | @SerializedName("mv_provider") 11 | val mvProvider: String = "", 12 | @SerializedName("artist_name") 13 | val artistName: String = "", 14 | @SerializedName("biaoshi") 15 | val biaoshi: String = "", 16 | @SerializedName("is_first_publish") 17 | val isFirstPublish: Int = 0, 18 | @SerializedName("del_status") 19 | val delStatus: String = "", 20 | @SerializedName("album_1000_1000") 21 | val pic1000: String = "", 22 | @SerializedName("korean_bb_song") 23 | val koreanBbSong: String = "", 24 | @SerializedName("title") 25 | val title: String = "", 26 | @SerializedName("pic_big") 27 | val picBig: String = "", 28 | @SerializedName("pic_huge") 29 | val picHuge: String = "", 30 | @SerializedName("all_rate") 31 | val allRate: String = "", 32 | @SerializedName("song_source") 33 | val songSource: String = "", 34 | @SerializedName("song_id") 35 | val songId: String = "", 36 | @SerializedName("album_500_500") 37 | val album500: String = "", 38 | @SerializedName("havehigh") 39 | val havehigh: Int = 0, 40 | @SerializedName("rank") 41 | val rank: String = "", 42 | @SerializedName("pic_premium") 43 | val picPremium: String = "", 44 | @SerializedName("album_800_800") 45 | val album800: String = "", 46 | @SerializedName("info") 47 | val info: String = "", 48 | @SerializedName("si_proxycompany") 49 | val siProxycompany: String = "", 50 | @SerializedName("has_mv_mobile") 51 | val hasMvMobile: Int = 0, 52 | @SerializedName("charge") 53 | val charge: Int = 0, 54 | @SerializedName("pic_radio") 55 | val picRadio: String = "", 56 | @SerializedName("learn") 57 | val learn: Int = 0, 58 | @SerializedName("author") 59 | val author: String = "", 60 | @SerializedName("pic_s500") 61 | val picS: String = "", 62 | @SerializedName("all_artist_id") 63 | val allArtistId: String = "", 64 | @SerializedName("resource_type") 65 | val resourceType: String = "", 66 | @SerializedName("has_filmtv") 67 | val hasFilmtv: String = "", 68 | @SerializedName("pic_small") 69 | val picSmall: String = "", 70 | @SerializedName("has_mv") 71 | val hasMv: Int = 0, 72 | @SerializedName("bitrate_fee") 73 | val bitrateFee: String = "", 74 | @SerializedName("all_artist_ting_uid") 75 | val allArtistTingUid: String = "", 76 | @SerializedName("artist_id") 77 | val artistId: String = "", 78 | @SerializedName("high_rate") 79 | val highRate: String = "", 80 | @SerializedName("versions") 81 | val versions: String = "", 82 | @SerializedName("album_id") 83 | val albumId: String = "", 84 | @SerializedName("copy_type") 85 | val copyType: String = "", 86 | @SerializedName("ting_uid") 87 | val tingUid: String = "", 88 | @SerializedName("album_title") 89 | val albumTitle: String = "") 90 | 91 | 92 | data class Billboard(@SerializedName("pic_s210") 93 | val picS: String = "", 94 | @SerializedName("billboard_type") 95 | val billboardType: Int = 0, 96 | @SerializedName("web_url") 97 | val webUrl: String = "", 98 | @SerializedName("pic_s640") 99 | val picS640: String = "", 100 | @SerializedName("pic_s444") 101 | val picS444: String = "", 102 | @SerializedName("havemore") 103 | val havemore: Int = 0, 104 | @SerializedName("name") 105 | val name: String = "", 106 | @SerializedName("billboard_no") 107 | val billboardNo: String = "", 108 | @SerializedName("comment") 109 | val comment: String = "", 110 | @SerializedName("pic_s192") 111 | val picS192: String = "", 112 | @SerializedName("update_date") 113 | val updateDate: String = "", 114 | @SerializedName("pic_s260") 115 | val picS260: String = "") 116 | 117 | 118 | data class BaiduMusicList(@SerializedName("song_list") 119 | val songList: List?, 120 | @SerializedName("error_code") 121 | val errorCode: Int = 0, 122 | @SerializedName("billboard") 123 | val billboard: Billboard) 124 | 125 | 126 | data class ArtistMusicList(@SerializedName("songlist") 127 | val songList: List?, 128 | @SerializedName("error_code") 129 | val errorCode: Int = 0, 130 | @SerializedName("havemore") 131 | val haveMore: Int = 0, 132 | @SerializedName("artistinfo") 133 | val artistinfo: BaiduArtistInfo?, 134 | @SerializedName("songnums") 135 | val songNums: Int = 0) 136 | 137 | 138 | data class AlbumSongList(@SerializedName("is_collect") 139 | val isCollect: Int = 0, 140 | @SerializedName("share_pic") 141 | val sharePic: String = "", 142 | @SerializedName("albumInfo") 143 | val albumInfo: AlbumDetailInfo, 144 | @SerializedName("share_title") 145 | val shareTitle: String = "", 146 | @SerializedName("songlist") 147 | val songlist: List?) 148 | 149 | 150 | data class AlbumDetailInfo(@SerializedName("comment_num") 151 | val commentNum: Int = 0, 152 | @SerializedName("country") 153 | val country: String = "", 154 | @SerializedName("pic_s1000") 155 | val picS: String = "", 156 | @SerializedName("resource_type_ext") 157 | val resourceTypeExt: String = "", 158 | @SerializedName("gender") 159 | val gender: String = "", 160 | @SerializedName("language") 161 | val language: String = "", 162 | @SerializedName("collect_num") 163 | val collectNum: Int = 0, 164 | @SerializedName("title") 165 | val title: String = "", 166 | @SerializedName("hot") 167 | val hot: String = "", 168 | @SerializedName("pic_big") 169 | val picBig: String = "", 170 | @SerializedName("listen_num") 171 | val listenNum: String = "", 172 | @SerializedName("price") 173 | val price: String = "", 174 | @SerializedName("favorites_num") 175 | val favoritesNum: Int = 0, 176 | @SerializedName("info") 177 | val info: String = "", 178 | @SerializedName("share_num") 179 | val shareNum: Int = 0, 180 | @SerializedName("area") 181 | val area: String = "", 182 | @SerializedName("ai_presale_flag") 183 | val aiPresaleFlag: String = "", 184 | @SerializedName("pic_radio") 185 | val picRadio: String = "", 186 | @SerializedName("my_num") 187 | val myNum: Int = 0, 188 | @SerializedName("author") 189 | val author: String = "", 190 | @SerializedName("pic_s500") 191 | val picS5: String = "", 192 | @SerializedName("all_artist_id") 193 | val allArtistId: String = "", 194 | @SerializedName("buy_url") 195 | val buyUrl: String = "", 196 | @SerializedName("pic_small") 197 | val picSmall: String = "", 198 | @SerializedName("publishcompany") 199 | val publishcompany: String = "", 200 | @SerializedName("all_artist_ting_uid") 201 | val allArtistTingUid: String = "", 202 | @SerializedName("artist_id") 203 | val artistId: String = "", 204 | @SerializedName("song_sale") 205 | val songSale: Int = 0, 206 | @SerializedName("songs_total") 207 | val songsTotal: String = "", 208 | @SerializedName("publishtime") 209 | val publishtime: String = "", 210 | @SerializedName("recommend_num") 211 | val recommendNum: Int = 0, 212 | @SerializedName("artist_ting_uid") 213 | val artistTingUid: String = "", 214 | @SerializedName("album_id") 215 | val albumId: String = "") 216 | 217 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduPlayMv.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class BaiduPlayMv(@SerializedName("result") 6 | val result: MvResult, 7 | @SerializedName("error_code") 8 | val errorCode: Int = 0) 9 | 10 | data class MvResult( 11 | @SerializedName("files") 12 | val files: Files, 13 | @SerializedName("max_definition") 14 | val maxDefinition: String, 15 | @SerializedName("min_definition") 16 | val minDefinition: String, 17 | @SerializedName("mv_info") 18 | val mvInfo: MvInfo, 19 | @SerializedName("share_pic") 20 | val sharePic: String, 21 | @SerializedName("share_url") 22 | val shareUrl: String, 23 | @SerializedName("video_info") 24 | val videoInfo: VideoInfo, 25 | @SerializedName("video_type") 26 | val videoType: String 27 | ) 28 | 29 | data class VideoInfo( 30 | @SerializedName("del_status") 31 | val delStatus: String, 32 | @SerializedName("distribution") 33 | val distribution: String, 34 | @SerializedName("mv_id") 35 | val mvId: String, 36 | @SerializedName("provider") 37 | val provider: String, 38 | @SerializedName("sourcepath") 39 | val sourcepath: String, 40 | @SerializedName("thumbnail") 41 | val thumbnail: String, 42 | @SerializedName("thumbnail2") 43 | val thumbnail2: String, 44 | @SerializedName("tvid") 45 | val tvid: String, 46 | @SerializedName("video_id") 47 | val videoId: String 48 | ) 49 | 50 | data class Files( 51 | @SerializedName("51") 52 | val x51: X31?, 53 | @SerializedName("41") 54 | val x41: X31?, 55 | @SerializedName("31") 56 | val x31: X31?, 57 | @SerializedName("21") 58 | val x21: X31? 59 | 60 | ) 61 | 62 | data class X31( 63 | @SerializedName("aspect_ratio") 64 | val aspectRatio: String, 65 | @SerializedName("definition") 66 | val definition: String, 67 | @SerializedName("file_duration") 68 | val fileDuration: String, 69 | @SerializedName("file_extension") 70 | val fileExtension: String, 71 | @SerializedName("file_format") 72 | val fileFormat: String, 73 | @SerializedName("file_link") 74 | val fileLink: String, 75 | @SerializedName("file_size") 76 | val fileSize: String, 77 | @SerializedName("player_param") 78 | val playerParam: String, 79 | @SerializedName("source_path") 80 | val sourcePath: String, 81 | @SerializedName("video_file_id") 82 | val videoFileId: String, 83 | @SerializedName("video_id") 84 | val videoId: String 85 | ) 86 | 87 | data class MvInfo( 88 | @SerializedName("aliastitle") 89 | val aliastitle: String, 90 | @SerializedName("all_artist_id") 91 | val allArtistId: String, 92 | @SerializedName("artist") 93 | val artist: String, 94 | @SerializedName("artist_id") 95 | val artistId: String, 96 | @SerializedName("artist_list") 97 | val artistList: List, 98 | @SerializedName("del_status") 99 | val delStatus: String, 100 | @SerializedName("mv_id") 101 | val mvId: String, 102 | @SerializedName("play_nums") 103 | val playNums: Int, 104 | @SerializedName("provider") 105 | val provider: String, 106 | @SerializedName("publishtime") 107 | val publishtime: String, 108 | @SerializedName("subtitle") 109 | val subtitle: String, 110 | @SerializedName("thumbnail") 111 | val thumbnail: String, 112 | @SerializedName("thumbnail2") 113 | val thumbnail2: String, 114 | @SerializedName("title") 115 | val title: String 116 | ) 117 | 118 | data class Artist( 119 | @SerializedName("artist_480_800") 120 | val artist480800: String, 121 | @SerializedName("artist_640_1136") 122 | val artist6401136: String, 123 | @SerializedName("artist_id") 124 | val artistId: String, 125 | @SerializedName("artist_name") 126 | val artistName: String, 127 | @SerializedName("avatar_mini") 128 | val avatarMini: String, 129 | @SerializedName("avatar_s180") 130 | val avatarS180: String, 131 | @SerializedName("avatar_s300") 132 | val avatarS300: String, 133 | @SerializedName("avatar_s500") 134 | val avatarS500: String, 135 | @SerializedName("avatar_small") 136 | val avatarSmall: String, 137 | @SerializedName("del_status") 138 | val delStatus: String, 139 | @SerializedName("ting_uid") 140 | val tingUid: String 141 | ) 142 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduSearchMerge.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class AlbumListItem(@SerializedName("resource_type_ext") 7 | val resourceTypeExt: String = "", 8 | @SerializedName("author") 9 | val author: String = "", 10 | @SerializedName("all_artist_id") 11 | val allArtistId: String = "", 12 | @SerializedName("publishtime") 13 | val publishtime: String = "", 14 | @SerializedName("album_desc") 15 | val albumDesc: String = "", 16 | @SerializedName("company") 17 | val company: String = "", 18 | @SerializedName("album_id") 19 | val albumId: String = "", 20 | @SerializedName("pic_small") 21 | val picSmall: String = "", 22 | @SerializedName("title") 23 | val title: String = "", 24 | @SerializedName("hot") 25 | val hot: Int = 0, 26 | @SerializedName("artist_id") 27 | val artistId: String = "") 28 | 29 | 30 | data class ArtistListItem(@SerializedName("country") 31 | val country: String = "", 32 | @SerializedName("song_num") 33 | val songNum: Int = 0, 34 | @SerializedName("album_num") 35 | val albumNum: Int = 0, 36 | @SerializedName("author") 37 | val author: String = "", 38 | @SerializedName("avatar_middle") 39 | val avatarMiddle: String = "", 40 | @SerializedName("ting_uid") 41 | val tingUid: String = "", 42 | @SerializedName("artist_desc") 43 | val artistDesc: String = "", 44 | @SerializedName("artist_source") 45 | val artistSource: String = "", 46 | @SerializedName("artist_id") 47 | val artistId: String = "") 48 | 49 | 50 | data class VideoInfoData(@SerializedName("total") 51 | val total: Int = 0) 52 | 53 | 54 | data class UserInfo(@SerializedName("total") 55 | val total: Int = 0) 56 | 57 | 58 | data class ArtistInfo(@SerializedName("total") 59 | val total: Int = 0, 60 | @SerializedName("artist_list") 61 | val artistList: List?) 62 | 63 | 64 | data class BaiduSearchMergeInfo(@SerializedName("result") 65 | val result: Result, 66 | @SerializedName("error_code") 67 | val errorCode: Int = 0) 68 | 69 | 70 | data class TopicInfo(@SerializedName("total") 71 | val total: Int = 0) 72 | 73 | 74 | data class Result(@SerializedName("artist_info") 75 | val artistInfo: ArtistInfo, 76 | @SerializedName("syn_words") 77 | val synWords: String = "", 78 | @SerializedName("user_info") 79 | val userInfo: UserInfo, 80 | @SerializedName("album_info") 81 | val albumInfo: AlbumInfo, 82 | @SerializedName("song_info") 83 | val songInfo: SongInfoRes, 84 | @SerializedName("tag_info") 85 | val tagInfo: TagInfo, 86 | @SerializedName("query") 87 | val query: String = "", 88 | @SerializedName("playlist_info") 89 | val playlistInfo: PlaylistInfo, 90 | @SerializedName("rqt_type") 91 | val rqtType: Int = 0, 92 | @SerializedName("video_info") 93 | val videoInfo: VideoInfoData, 94 | @SerializedName("topic_info") 95 | val topicInfo: TopicInfo) 96 | 97 | 98 | data class AlbumInfo(@SerializedName("album_list") 99 | val albumList: List?, 100 | @SerializedName("total") 101 | val total: Int = 0) 102 | 103 | 104 | data class TagInfo(@SerializedName("total") 105 | val total: Int = 0) 106 | 107 | 108 | data class SongInfoRes(@SerializedName("total") 109 | val total: Int = 0, 110 | @SerializedName("song_list") 111 | val songList: List?) 112 | 113 | 114 | data class PlaylistInfo(@SerializedName("total") 115 | val total: Int = 0) 116 | 117 | 118 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduSearchSug.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class SongSug(@SerializedName("resource_type_ext") 7 | val resourceTypeExt: String = "", 8 | @SerializedName("artistname") 9 | val artistname: String = "", 10 | @SerializedName("resource_type") 11 | val resourceType: String = "", 12 | @SerializedName("weight") 13 | val weight: String = "", 14 | @SerializedName("bitrate_fee") 15 | val bitrateFee: String = "", 16 | @SerializedName("has_mv") 17 | val hasMv: String = "", 18 | @SerializedName("control") 19 | val control: String = "", 20 | @SerializedName("songname") 21 | val songname: String = "", 22 | @SerializedName("yyr_artist") 23 | val yyrArtist: String = "", 24 | @SerializedName("encrypted_songid") 25 | val encryptedSongid: String = "", 26 | @SerializedName("resource_provider") 27 | val resourceProvider: String = "", 28 | @SerializedName("songid") 29 | val songid: String = "", 30 | @SerializedName("info") 31 | val info: String = "") 32 | 33 | 34 | data class ArtistSug(@SerializedName("yyr_artist") 35 | val yyrArtist: String = "", 36 | @SerializedName("artistname") 37 | val artistname: String = "", 38 | @SerializedName("weight") 39 | val weight: String = "", 40 | @SerializedName("artistid") 41 | val artistid: String = "", 42 | @SerializedName("artistpic") 43 | val artistpic: String = "") 44 | 45 | 46 | data class BaiduSearchSug(@SerializedName("song") 47 | val song: List?, 48 | @SerializedName("artist") 49 | val artist: List?, 50 | @SerializedName("album") 51 | val album: List?, 52 | @SerializedName("error_code") 53 | val errorCode: Int = 0, 54 | @SerializedName("order") 55 | val order: String = "") 56 | 57 | 58 | data class AlbumSug(@SerializedName("albumname") 59 | val albumname: String = "", 60 | @SerializedName("resource_type_ext") 61 | val resourceTypeExt: String = "", 62 | @SerializedName("artistname") 63 | val artistname: String = "", 64 | @SerializedName("weight") 65 | val weight: String = "", 66 | @SerializedName("albumid") 67 | val albumid: String = "", 68 | @SerializedName("artistpic") 69 | val artistpic: String = "") 70 | 71 | 72 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/BaiduSongInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | //"songList": [{ 7 | // "queryId": "265715650", 8 | // "songId": 265715650, 9 | // "songName": "\u5927\u9c7c", 10 | // "artistId": "164528737", 11 | // "artistName": "\u5468\u6df1", 12 | // "albumId": 265715651, 13 | // "albumName": "\u5927\u9c7c", 14 | // "songPicSmall": "http:\/\/qukufile2.qianqian.com\/data2\/pic\/0d359ec1be6f5365f92d4c83d3eeb022\/603758238\/603758238.jpg@s_2,w_90,h_90", 15 | // "songPicBig": "http:\/\/qukufile2.qianqian.com\/data2\/pic\/0d359ec1be6f5365f92d4c83d3eeb022\/603758238\/603758238.jpg@s_2,w_150,h_150", 16 | // "songPicRadio": "http:\/\/qukufile2.qianqian.com\/data2\/pic\/0d359ec1be6f5365f92d4c83d3eeb022\/603758238\/603758238.jpg@s_2,w_300,h_300", 17 | // "lrcLink": "http:\/\/qukufile2.qianqian.com\/data2\/lrc\/7a07a153b8a9a9d918bbee676b7d4118\/603149730\/603149730.lrc", 18 | // "version": "", 19 | // "copyType": 0, 20 | // "time": 313, 21 | // "linkCode": 22000, 22 | // "songLink": "http:\/\/zhangmenshiting.qianqian.com\/data2\/music\/a612909cdafecf20933bd2942c43421c\/596603939\/26571565036000128.mp3?xcode=ee75606752833ea05fa4084c7da1aa86", 23 | // "showLink": "http:\/\/zhangmenshiting.qianqian.com\/data2\/music\/a612909cdafecf20933bd2942c43421c\/596603939\/26571565036000128.mp3?xcode=ee75606752833ea05fa4084c7da1aa86", 24 | // "format": "mp3", 25 | // "rate": 128, 26 | // "size": 5021639, 27 | // "relateStatus": "0", 28 | // "resourceType": "0", 29 | // "source": "web" 30 | // }] 31 | data class SongItem(@SerializedName("songName") 32 | val songName: String = "", 33 | @SerializedName("albumName") 34 | val albumName: String = "", 35 | @SerializedName("linkCode") 36 | val linkCode: Int = 0, 37 | @SerializedName("format") 38 | val format: String = "", 39 | @SerializedName("albumId") 40 | val albumId: Int = 0, 41 | @SerializedName("artistId") 42 | val artistId: String = "", 43 | @SerializedName("ting_uid") 44 | val tingUid: String = "", 45 | @SerializedName("source") 46 | val source: String = "", 47 | @SerializedName("songPicBig") 48 | val songPicBig: String = "", 49 | @SerializedName("version") 50 | val version: String = "", 51 | @SerializedName("queryId") 52 | val queryId: String = "", 53 | @SerializedName("songLink") 54 | val songLink: String = "", 55 | @SerializedName("size") 56 | val size: Int = 0, 57 | @SerializedName("rate") 58 | val rate: Int = 0, 59 | @SerializedName("lrcLink") 60 | val lrcLink: String = "", 61 | @SerializedName("copyType") 62 | val copyType: Int = 0, 63 | @SerializedName("artistName") 64 | val artistName: String = "", 65 | @SerializedName("time") 66 | val time: Int = 0, 67 | @SerializedName("relateStatus") 68 | val relateStatus: String = "", 69 | @SerializedName("songPicSmall") 70 | val songPicSmall: String = "", 71 | @SerializedName("songId") 72 | val songId: Int = 0, 73 | @SerializedName("songPicRadio") 74 | val songPicRadio: String = "", 75 | @SerializedName("showLink") 76 | val showLink: String = "", 77 | @SerializedName("resourceType") 78 | val resourceType: String = "") 79 | 80 | 81 | data class Data(@SerializedName("xcode") 82 | val xcode: String = "", 83 | @SerializedName("songList") 84 | val songList: List?) 85 | 86 | 87 | data class BaiduSongInfo(@SerializedName("data") 88 | val data: Data, 89 | @SerializedName("errorCode") 90 | val errorCode: Int = 0) 91 | 92 | 93 | 94 | data class SongPlayRes( 95 | @SerializedName("bitrate") 96 | val bitrate: Bitrate, 97 | @SerializedName("error_code") 98 | val errorCode: Int, 99 | @SerializedName("songinfo") 100 | val songinfo: SongInfo 101 | ) 102 | 103 | data class Bitrate( 104 | @SerializedName("file_bitrate") 105 | val fileBitrate: Int, 106 | @SerializedName("file_duration") 107 | val fileDuration: Int, 108 | @SerializedName("file_extension") 109 | val fileExtension: String, 110 | @SerializedName("file_link") 111 | val fileLink: String, 112 | @SerializedName("file_size") 113 | val fileSize: Int, 114 | @SerializedName("free") 115 | val free: Int, 116 | @SerializedName("hash") 117 | val hash: String, 118 | @SerializedName("show_link") 119 | val showLink: String, 120 | @SerializedName("song_file_id") 121 | val songFileId: Int 122 | ) 123 | 124 | data class SongInfo( 125 | @SerializedName("album_id") 126 | val albumId: String, 127 | @SerializedName("album_no") 128 | val albumNo: String, 129 | @SerializedName("album_title") 130 | val albumTitle: String, 131 | @SerializedName("all_artist_id") 132 | val allArtistId: String, 133 | @SerializedName("all_artist_ting_uid") 134 | val allArtistTingUid: String, 135 | @SerializedName("all_rate") 136 | val allRate: String, 137 | @SerializedName("artist_id") 138 | val artistId: String, 139 | @SerializedName("author") 140 | val author: String, 141 | @SerializedName("bitrate_fee") 142 | val bitrateFee: String, 143 | @SerializedName("charge") 144 | val charge: Int, 145 | @SerializedName("copy_type") 146 | val copyType: String, 147 | @SerializedName("has_mv") 148 | val hasMv: Int, 149 | @SerializedName("has_mv_mobile") 150 | val hasMvMobile: Int, 151 | @SerializedName("havehigh") 152 | val havehigh: Int, 153 | @SerializedName("is_first_publish") 154 | val isFirstPublish: Int, 155 | @SerializedName("korean_bb_song") 156 | val koreanBbSong: String, 157 | @SerializedName("learn") 158 | val learn: Int, 159 | @SerializedName("lrclink") 160 | val lrclink: String, 161 | @SerializedName("piao_id") 162 | val piaoId: String, 163 | @SerializedName("pic_big") 164 | val picBig: String, 165 | @SerializedName("pic_huge") 166 | val picHuge: String, 167 | @SerializedName("pic_premium") 168 | val picPremium: String, 169 | @SerializedName("pic_radio") 170 | val picRadio: String, 171 | @SerializedName("pic_small") 172 | val picSmall: String, 173 | @SerializedName("play_type") 174 | val playType: Int, 175 | @SerializedName("relate_status") 176 | val relateStatus: String, 177 | @SerializedName("resource_type") 178 | val resourceType: String, 179 | @SerializedName("resource_type_ext") 180 | val resourceTypeExt: String, 181 | @SerializedName("si_proxycompany") 182 | val siProxycompany: String, 183 | @SerializedName("song_id") 184 | val songId: String, 185 | @SerializedName("song_source") 186 | val songSource: String, 187 | @SerializedName("special_type") 188 | val specialType: Int, 189 | @SerializedName("ting_uid") 190 | val tingUid: String, 191 | @SerializedName("title") 192 | val title: String, 193 | @SerializedName("toneid") 194 | val toneid: String 195 | ) -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/RadioData.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class RadioData(@SerializedName("result") 7 | val result: List?, 8 | @SerializedName("error_code") 9 | val errorCode: Int = 0) 10 | 11 | 12 | data class ResultItem(@SerializedName("channellist") 13 | val channellist: MutableList?, 14 | @SerializedName("title") 15 | val title: String = "", 16 | @SerializedName("cid") 17 | val cid: Int = 0) 18 | 19 | 20 | data class RadioChannel(@SerializedName("thumb") 21 | val thumb: String = "", 22 | @SerializedName("name") 23 | val name: String = "", 24 | @SerializedName("cate_name") 25 | val cateName: String = "", 26 | @SerializedName("cate_sname") 27 | val cateSname: String = "", 28 | @SerializedName("ch_name") 29 | val chName: String = "", 30 | @SerializedName("value") 31 | val value: Int = 0, 32 | @SerializedName("channelid") 33 | val channelid: String = "") 34 | 35 | 36 | data class RadioChannelData(@SerializedName("result") 37 | val result: ChannelInfo, 38 | @SerializedName("error_code") 39 | val errorCode: Int = 0) 40 | 41 | 42 | 43 | data class CHSongInfo(@SerializedName("all_rate") 44 | val allRate: String = "", 45 | @SerializedName("charge") 46 | val charge: Int = 0, 47 | @SerializedName("method") 48 | val method: Int = 0, 49 | @SerializedName("artist") 50 | val artist: String = "", 51 | @SerializedName("thumb") 52 | val thumb: String = "", 53 | @SerializedName("all_artist_id") 54 | val allArtistId: String = "", 55 | @SerializedName("resource_type") 56 | val resourceType: String = "", 57 | @SerializedName("havehigh") 58 | val havehigh: Int = 0, 59 | @SerializedName("title") 60 | val title: String = "", 61 | @SerializedName("songid") 62 | val songid: String?, 63 | @SerializedName("artist_id") 64 | val artistId: String = "", 65 | @SerializedName("flow") 66 | val flow: Int = 0) 67 | 68 | 69 | data class ChannelInfo(@SerializedName("channel") 70 | val channel: String = "", 71 | @SerializedName("count") 72 | val count: Any? = null, 73 | @SerializedName("ch_name") 74 | val chName: String = "", 75 | @SerializedName("artistid") 76 | val artistid: Any? = null, 77 | @SerializedName("avatar") 78 | val avatar: Any? = null, 79 | @SerializedName("songlist") 80 | val songlist: MutableList?, 81 | @SerializedName("channelid") 82 | val channelid: Any? = null) 83 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/baidu/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.baidu 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class Suggestion(@SerializedName("suggestion_list") 7 | val suggestionList: List?, 8 | @SerializedName("query") 9 | val query: String = "") 10 | 11 | 12 | data class BaiduLyric( 13 | @SerializedName("lrcContent") 14 | val lrcContent: String, 15 | @SerializedName("title") 16 | val title: String 17 | ) 18 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/ArtistSongsData.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.cyl.musicapi.playlist.MusicInfo 5 | import com.google.gson.annotations.SerializedName 6 | 7 | data class AlbumData(@SerializedName("data") 8 | val data: AlbumBean, 9 | @SerializedName("status") 10 | val status: Boolean = false, 11 | @SerializedName("msg") 12 | val msg: String = "") 13 | 14 | data class AlbumBean(@SerializedName("name") 15 | val name: String = "", 16 | @SerializedName("cover") 17 | val cover: String? = null, 18 | @SerializedName("desc") 19 | val desc: String? = null, 20 | @SerializedName("publishTime") 21 | val publishTime: Long, 22 | @SerializedName("artist") 23 | val artist: ArtistItem, 24 | @SerializedName("songs") 25 | val songs: List) 26 | 27 | data class ArtistSongs(@SerializedName("detail") 28 | val detail: ArtistItem, 29 | @SerializedName("songs") 30 | val songs: List) 31 | 32 | 33 | data class ArtistItem(@SerializedName("name") 34 | val name: String = "", 35 | @SerializedName("id") 36 | val id: String = "", 37 | @SerializedName("cover") 38 | val cover: String? = null, 39 | @SerializedName("desc") 40 | val desc: String? = null) 41 | 42 | 43 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/ArtistsData.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class ArtistsData(@SerializedName("data") 7 | val data: Artists, 8 | @SerializedName("status") 9 | val status: Boolean = false, 10 | @SerializedName("msg") 11 | val msg: String = "") 12 | 13 | 14 | data class SingerList(@SerializedName("data") 15 | val data: Artists, 16 | @SerializedName("code") 17 | val code: Int = 0) 18 | 19 | data class ArtistsDataInfo(@SerializedName("singerList") 20 | val singerList: SingerList, 21 | @SerializedName("code") 22 | val code: Int = 0) 23 | 24 | data class Artists(@SerializedName("area") 25 | val area: Int, 26 | @SerializedName("genre") 27 | val genre: Int, 28 | @SerializedName("index") 29 | val index: Int, 30 | @SerializedName("sex") 31 | val sex: Int, 32 | @SerializedName("singerlist") 33 | val singerList: MutableList, 34 | @SerializedName("tags") 35 | val tags: SingerTag, 36 | @SerializedName("total") 37 | val total: Int) 38 | 39 | data class SingerItem(@SerializedName("country") 40 | val country: String = "", 41 | @SerializedName("singer_id") 42 | val singer_id: String = "", 43 | @SerializedName("singer_mid") 44 | val singer_mid: String? = null, 45 | @SerializedName("singer_pic") 46 | val singer_pic: String? = null, 47 | @SerializedName("singer_name") 48 | val singer_name: String? = null) 49 | 50 | data class SingerTag(@SerializedName("area") 51 | val area: MutableList, 52 | @SerializedName("genre") 53 | val genre: MutableList, 54 | @SerializedName("index") 55 | val index: MutableList, 56 | @SerializedName("sex") 57 | val sex: MutableList) 58 | 59 | data class SingerCate( 60 | @SerializedName("id") 61 | val id: Int, 62 | @SerializedName("name") 63 | val name: String) 64 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/LyricInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class LyricData(@SerializedName("data") 7 | val data: LyricInfo, 8 | @SerializedName("status") 9 | val status: Boolean = false, 10 | @SerializedName("msg") 11 | val msg: String = "") 12 | 13 | data class LyricInfo(@SerializedName("translate") 14 | val translate: List>, 15 | @SerializedName("lyric") 16 | val lyric: List>) 17 | 18 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/SearchData.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.cyl.musicapi.playlist.MusicInfo 5 | import com.google.gson.annotations.SerializedName 6 | 7 | data class Qq(@SerializedName("total") 8 | val total: String = "", 9 | @SerializedName("songs") 10 | val songs: List?, 11 | @SerializedName("keyword") 12 | val keyword: String = "") 13 | 14 | data class SearchResult(@SerializedName("total") 15 | val total: String = "", 16 | @SerializedName("songs") 17 | val songs: List?) 18 | 19 | 20 | data class SearchData(@SerializedName("data") 21 | val data: Data, 22 | @SerializedName("status") 23 | val status: Boolean = false, 24 | @SerializedName("msg") 25 | val msg: String = "") 26 | 27 | data class SearchSingleData(@SerializedName("data") 28 | val data: SearchResult, 29 | @SerializedName("status") 30 | val status: Boolean = false, 31 | @SerializedName("msg") 32 | val msg: String = "") 33 | 34 | 35 | data class Xiami(@SerializedName("total") 36 | val total: String = "", 37 | @SerializedName("songs") 38 | val songs: List?) 39 | 40 | 41 | data class ArtistsItem(@SerializedName("name") 42 | val name: String = "", 43 | @SerializedName("id") 44 | val id: String = "") 45 | 46 | 47 | data class Album(@SerializedName("cover") 48 | val cover: String = "", 49 | @SerializedName("name") 50 | val name: String = "", 51 | @SerializedName("id") 52 | val id: String = "") 53 | 54 | 55 | data class Netease(@SerializedName("total") 56 | val total: Int? = 0, 57 | @SerializedName("songs") 58 | val songs: List? = null) 59 | 60 | 61 | data class Data(@SerializedName("qq") 62 | val qq: Qq, 63 | @SerializedName("xiami") 64 | val xiami: Xiami, 65 | @SerializedName("netease") 66 | val netease: Netease) 67 | 68 | 69 | data class SongDetail(@SerializedName("data") 70 | val data: MusicInfo, 71 | @SerializedName("status") 72 | val status: Boolean = false, 73 | @SerializedName("msg") 74 | val msg: String = "") 75 | 76 | data class BatchSongDetail(@SerializedName("data") 77 | val data: List, 78 | @SerializedName("status") 79 | val status: Boolean = false, 80 | @SerializedName("msg") 81 | val msg: String = "", 82 | @SerializedName("log") 83 | val log: LogDetail?) 84 | 85 | data class AnyBatchSongDetail(@SerializedName("data") 86 | val data: List, 87 | @SerializedName("status") 88 | val status: Boolean = false, 89 | @SerializedName("msg") 90 | val msg: String = "", 91 | @SerializedName("log") 92 | val log: LogDetail?) 93 | 94 | data class LogDetail(@SerializedName("msg") 95 | val msg: String) -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/SongComment.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class SongCommentData(@SerializedName("data") 7 | val data: CommentData?, 8 | @SerializedName("status") 9 | val status: Boolean = false, 10 | @SerializedName("msg") 11 | val msg: String = "") 12 | 13 | data class User(@SerializedName("avatarUrl") 14 | val avatarUrl: String = "", 15 | @SerializedName("nickname") 16 | val nickname: String = "", 17 | @SerializedName("remarkName") 18 | val remarkName: String? = null, 19 | @SerializedName("userId") 20 | val userId: String = "") 21 | 22 | class SongComment() { 23 | var userId: String = "" 24 | var avatarUrl: String = "" 25 | var nick: String = "" 26 | var commentId: String = "" 27 | var content: String = "" 28 | var time: Long = 0 29 | var type: String = "" 30 | } 31 | 32 | 33 | data class QQComment(@SerializedName("avatarurl") 34 | val avatarurl: String = "", 35 | @SerializedName("nick") 36 | val nick: String = "", 37 | @SerializedName("commentid") 38 | val commentid: String = "", 39 | @SerializedName("rootcommentcontent") 40 | val rootcommentcontent: String = "", 41 | @SerializedName("rootcommentid") 42 | val rootcommentid: String = "", 43 | @SerializedName("middlecommentcontent") 44 | val middlecommentcontent: Any? = null, 45 | @SerializedName("rootcommentnick") 46 | val rootcommentnick: String = "", 47 | @SerializedName("time") 48 | val time: Long = 0, 49 | @SerializedName("uin") 50 | val uin: String = "") 51 | 52 | 53 | data class XiamiComment(@SerializedName("author") 54 | val author: Boolean = false, 55 | @SerializedName("isDelete") 56 | val isDelete: Boolean = false, 57 | @SerializedName("nickName") 58 | val nickName: String = "", 59 | @SerializedName("isReport") 60 | val isReport: Boolean = false, 61 | @SerializedName("isLiked") 62 | val isLiked: Boolean = false, 63 | @SerializedName("topFlag") 64 | val topFlag: Int = 0, 65 | @SerializedName("avatar") 66 | val avatar: String = "", 67 | @SerializedName("gmtCreate") 68 | val gmtCreate: Long = 0, 69 | @SerializedName("message") 70 | val message: String = "", 71 | @SerializedName("userId") 72 | val userId: Int = 0, 73 | @SerializedName("isOfficial") 74 | val isOfficial: Int = 0, 75 | @SerializedName("objectType") 76 | val objectType: Int = 0, 77 | @SerializedName("visits") 78 | val visits: Int = 0, 79 | @SerializedName("commentId") 80 | val commentId: Int = 0, 81 | @SerializedName("isHot") 82 | val isHot: Boolean = false, 83 | @SerializedName("objectId") 84 | val objectId: Int = 0, 85 | @SerializedName("likes") 86 | val likes: Int = 0) 87 | 88 | 89 | data class NeteaseComment(@SerializedName("beReplied") 90 | val beReplied: List?, 91 | @SerializedName("commentId") 92 | val commentId: Long = 0, 93 | @SerializedName("time") 94 | val time: Long = 0, 95 | @SerializedName("user") 96 | val user: User, 97 | @SerializedName("content") 98 | val content: String = "") 99 | 100 | 101 | data class CommentData(@SerializedName("total") 102 | val total: Int = 0, 103 | @SerializedName("comments") 104 | val comments: List?) 105 | 106 | 107 | data class BeRepliedItem(@SerializedName("user") 108 | val user: User, 109 | @SerializedName("content") 110 | val content: String = "", 111 | @SerializedName("status") 112 | val status: Int = 0) 113 | 114 | 115 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/SongUrl.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class SongBean(@SerializedName("data") 7 | val data: UrlData, 8 | @SerializedName("status") 9 | val status: Boolean = false, 10 | @SerializedName("msg") 11 | val msg: String = "") 12 | 13 | 14 | data class UrlData(@SerializedName("url") 15 | val url: String = "") 16 | 17 | 18 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/bean/TopList.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.bean 2 | 3 | import com.cyl.musicapi.playlist.MusicInfo 4 | import com.google.gson.annotations.SerializedName 5 | 6 | /** 7 | * musicApi base json 8 | */ 9 | data class BaseApiBean(@SerializedName("data") 10 | val data: T, 11 | @SerializedName("status") 12 | val status: Boolean = false, 13 | @SerializedName("msg") 14 | val msg: String = "") 15 | 16 | data class TopListBean(@SerializedName("cover") 17 | val cover: String = "", 18 | @SerializedName("playCount") 19 | val playCount: Long = 0, 20 | @SerializedName("id") 21 | val id: String? = "", 22 | @SerializedName("name") 23 | val name: String? = null, 24 | @SerializedName("description") 25 | val description: String = "", 26 | @SerializedName("list") 27 | val list: List?) 28 | 29 | 30 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/dsbridge/CompletionHandler.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.dsbridge; 2 | 3 | /** 4 | * Created by du on 16/12/31. 5 | */ 6 | 7 | public interface CompletionHandler { 8 | void complete(T retValue); 9 | void complete(); 10 | void setProgressData(T value); 11 | } 12 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/dsbridge/OnReturnValue.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.dsbridge; 2 | 3 | /** 4 | * Created by du on 16/12/31. 5 | */ 6 | 7 | public interface OnReturnValue { 8 | void onValue(T retValue); 9 | } 10 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/kugou/KuGouApiService.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.kugou 2 | 3 | import io.reactivex.Observable 4 | import retrofit2.http.GET 5 | import retrofit2.http.Query 6 | 7 | interface KuGouApiService { 8 | 9 | @GET("search?ver=1&man=yes&client=pc") 10 | fun searchLyric(@Query("keyword") songName: String, @Query("duration") duration: String): Observable 11 | 12 | @GET("download?ver=1&client=pc&fmt=lrc&charset=utf8") 13 | fun getRawLyric(@Query("id") id: String, @Query("accesskey") accesskey: String): Observable 14 | 15 | } 16 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/kugou/KugouLyric.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.kugou 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class KugouLyric(@SerializedName("ugc") 6 | val ugc: Int = 0, 7 | @SerializedName("proposal") 8 | val proposal: String = "", 9 | @SerializedName("candidates") 10 | val candidates: MutableList?, 11 | @SerializedName("ugccount") 12 | val ugccount: Int = 0, 13 | @SerializedName("keyword") 14 | val keyword: String = "", 15 | @SerializedName("info") 16 | val info: String = "", 17 | @SerializedName("status") 18 | val status: Int = 0) 19 | 20 | data class KugouLyricInfo(@SerializedName("charset") 21 | val charset: String = "", 22 | @SerializedName("fmt") 23 | val fmt: String = "", 24 | @SerializedName("content") 25 | val content: String = "", 26 | @SerializedName("info") 27 | val info: String = "", 28 | @SerializedName("status") 29 | val status: Int = 0) 30 | 31 | data class Candidates(@SerializedName("song") 32 | val song: String = "", 33 | @SerializedName("hitlayer") 34 | val hitlayer: Int = 0, 35 | @SerializedName("singer") 36 | val singer: String = "", 37 | @SerializedName("language") 38 | val language: String = "", 39 | @SerializedName("originame") 40 | val originame: String = "", 41 | @SerializedName("duration") 42 | val duration: Int = 0, 43 | @SerializedName("transuid") 44 | val transuid: String = "", 45 | @SerializedName("score") 46 | val score: Int = 0, 47 | @SerializedName("uid") 48 | val uid: String = "", 49 | @SerializedName("transname") 50 | val transname: String = "", 51 | @SerializedName("accesskey") 52 | val accesskey: String = "", 53 | @SerializedName("adjust") 54 | val adjust: Int = 0, 55 | @SerializedName("nickname") 56 | val nickname: String = "", 57 | @SerializedName("soundname") 58 | val soundname: String = "", 59 | @SerializedName("krctype") 60 | val krctype: Int = 0, 61 | @SerializedName("origiuid") 62 | val origiuid: String = "", 63 | @SerializedName("id") 64 | val id: String = "", 65 | @SerializedName("sounduid") 66 | val sounduid: String = "") 67 | 68 | 69 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/ArtistsInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | 6 | data class ArtistsInfo(@SerializedName("code") 7 | val code: Int = 0, 8 | @SerializedName("list") 9 | val list: List) 10 | 11 | 12 | data class ArtistInfo(@SerializedName("lastRank") 13 | val lastRank: Int = 0, 14 | @SerializedName("img1v1Url") 15 | val imgVUrl: String = "", 16 | @SerializedName("musicSize") 17 | val musicSize: Int = 0, 18 | @SerializedName("img1v1Id") 19 | val imgVId: Long = 0, 20 | @SerializedName("albumSize") 21 | val albumSize: Int = 0, 22 | @SerializedName("picUrl") 23 | val picUrl: String = "", 24 | @SerializedName("score") 25 | val score: Int = 0, 26 | @SerializedName("topicPerson") 27 | val topicPerson: Int = 0, 28 | @SerializedName("briefDesc") 29 | val briefDesc: String = "", 30 | @SerializedName("name") 31 | val name: String = "", 32 | @SerializedName("id") 33 | val id: Int = 0, 34 | @SerializedName("picId") 35 | val picId: Long = 0, 36 | @SerializedName("trans") 37 | val trans: String = "") 38 | 39 | 40 | data class List(@SerializedName("artists") 41 | val artists: MutableList?, 42 | @SerializedName("updateTime") 43 | val updateTime: Long = 0, 44 | @SerializedName("type") 45 | val type: Int = 0) 46 | 47 | 48 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/BannerBean.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | class BannerResult(@SerializedName("banners") 6 | val banners: MutableList, 7 | @SerializedName("code") 8 | val code: Int = 0) 9 | 10 | //"picUrl": "http://p1.music.126.net/iYHFy0iwiiOHbNuMHYJBIQ==/109951163594094421.jpg", 11 | //"url": "/album?id=73471010", 12 | //"targetId": "73471010", 13 | //"backgroundUrl": "http://p1.music.126.net/hT8TZVuVtumtTZ2JcqKgLg==/109951163594097306.jpg", 14 | //"targetType": "10", 15 | //"monitorType": "", 16 | //"monitorImpress": "", 17 | //"monitorClick": "" 18 | class BannerBean(@SerializedName("imageUrl") 19 | val picUrl: String, 20 | @SerializedName("url") 21 | val url: String, 22 | @SerializedName("targetId") 23 | val targetId: String, 24 | @SerializedName("backgroundUrl") 25 | val backgroundUrl: String, 26 | @SerializedName("targetType") 27 | val targetType: String, 28 | @SerializedName("typeTitle") 29 | val typeTitle: String, 30 | @SerializedName("monitorType") 31 | val monitorType: String, 32 | @SerializedName("monitorImpress") 33 | val monitorImpress: String, 34 | @SerializedName("monitorClick") 35 | val monitorClick: String) -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/CatListBean.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class All(@SerializedName("imgUrl") 7 | val imgUrl: String = "", 8 | @SerializedName("imgId") 9 | val imgId: Long = 0, 10 | @SerializedName("resourceCount") 11 | val resourceCount: Int = 0, 12 | @SerializedName("name") 13 | val name: String = "", 14 | @SerializedName("type") 15 | val type: Int = 0, 16 | @SerializedName("category") 17 | val category: Int = 0, 18 | @SerializedName("hot") 19 | val hot: Boolean = false, 20 | @SerializedName("resourceType") 21 | val resourceType: Int = 0) 22 | 23 | data class Categories(@SerializedName("0") 24 | val c0: String = "", 25 | @SerializedName("1") 26 | val c1: String = "", 27 | @SerializedName("2") 28 | val c2: String = "", 29 | @SerializedName("3") 30 | val c3: String = "", 31 | @SerializedName("4") 32 | val c4: String = "") 33 | 34 | data class SubItem(@SerializedName("imgUrl") 35 | val imgUrl: String = "", 36 | @SerializedName("imgId") 37 | val imgId: Int = 0, 38 | @SerializedName("resourceCount") 39 | val resourceCount: Int = 0, 40 | @SerializedName("name") 41 | val name: String = "", 42 | @SerializedName("type") 43 | val type: Int = 0, 44 | @SerializedName("category") 45 | val category: Int = 0, 46 | @SerializedName("hot") 47 | val hot: Boolean = false, 48 | @SerializedName("resourceType") 49 | val resourceType: Int = 0) 50 | 51 | 52 | data class CatListBean(@SerializedName("all") 53 | val all: All, 54 | @SerializedName("sub") 55 | val sub: MutableList?, 56 | @SerializedName("code") 57 | val code: Int = 0, 58 | @SerializedName("categories") 59 | val categories: Categories) 60 | 61 | 62 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/LoginInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class Account(@SerializedName("salt") 7 | val salt: String = "", 8 | @SerializedName("vipType") 9 | val vipType: Int = 0, 10 | @SerializedName("userName") 11 | val userName: String = "", 12 | @SerializedName("type") 13 | val type: Int = 0, 14 | @SerializedName("ban") 15 | val ban: Int = 0, 16 | @SerializedName("anonimousUser") 17 | val anonimousUser: Boolean = false, 18 | @SerializedName("createTime") 19 | val createTime: Long = 0, 20 | @SerializedName("tokenVersion") 21 | val tokenVersion: Int = 0, 22 | @SerializedName("id") 23 | val id: Long = 0, 24 | @SerializedName("whitelistAuthority") 25 | val whitelistAuthority: Int = 0, 26 | @SerializedName("baoyueVersion") 27 | val baoyueVersion: Int = 0, 28 | @SerializedName("viptypeVersion") 29 | val viptypeVersion: Long = 0, 30 | @SerializedName("donateVersion") 31 | val donateVersion: Int = 0, 32 | @SerializedName("status") 33 | val status: Int = 0) 34 | 35 | 36 | data class LoginInfo(@SerializedName("clientId") 37 | val clientId: String = "", 38 | @SerializedName("code") 39 | val code: Int = 0, 40 | @SerializedName("msg") 41 | val msg: String = "", 42 | @SerializedName("loginType") 43 | val loginType: Int = 0, 44 | @SerializedName("profile") 45 | val profile: Profile, 46 | @SerializedName("bindings") 47 | val bindings: MutableList?, 48 | @SerializedName("effectTime") 49 | val effectTime: Long = 0, 50 | @SerializedName("account") 51 | val account: Account) 52 | 53 | 54 | data class BindingsItem(@SerializedName("expiresIn") 55 | val expiresIn: Int = 0, 56 | @SerializedName("expired") 57 | val expired: Boolean = false, 58 | @SerializedName("tokenJsonStr") 59 | val tokenJsonStr: String = "", 60 | @SerializedName("refreshTime") 61 | val refreshTime: Long = 0, 62 | @SerializedName("id") 63 | val id: Long = 0, 64 | @SerializedName("type") 65 | val type: Int = 0, 66 | @SerializedName("userId") 67 | val userId: Long = 0, 68 | @SerializedName("url") 69 | val url: String = "") 70 | 71 | 72 | data class Profile(@SerializedName("detailDescription") 73 | val detailDescription: String = "", 74 | @SerializedName("birthday") 75 | val birthday: Long = 0, 76 | @SerializedName("backgroundUrl") 77 | val backgroundUrl: String = "", 78 | @SerializedName("gender") 79 | val gender: Int = 0, 80 | @SerializedName("city") 81 | val city: Int = 0, 82 | @SerializedName("signature") 83 | val signature: String = "", 84 | @SerializedName("description") 85 | val description: String = "", 86 | @SerializedName("remarkName") 87 | val remarkName: String? = null, 88 | @SerializedName("accountStatus") 89 | val accountStatus: Int = 0, 90 | @SerializedName("avatarImgId") 91 | val avatarImgId: Long = 0, 92 | @SerializedName("defaultAvatar") 93 | val defaultAvatar: Boolean = false, 94 | @SerializedName("avatarImgIdStr") 95 | val avatarImgIdStr: String = "", 96 | @SerializedName("backgroundImgIdStr") 97 | val backgroundImgIdStr: String = "", 98 | @SerializedName("province") 99 | val province: Int = 0, 100 | @SerializedName("nickname") 101 | val nickname: String = "", 102 | @SerializedName("djStatus") 103 | val djStatus: Int = 0, 104 | @SerializedName("avatarUrl") 105 | val avatarUrl: String = "", 106 | @SerializedName("authStatus") 107 | val authStatus: Int = 0, 108 | @SerializedName("vipType") 109 | val vipType: Int = 0, 110 | @SerializedName("followed") 111 | val followed: Boolean = false, 112 | @SerializedName("userId") 113 | val userId: Long = 0, 114 | @SerializedName("mutual") 115 | val mutual: Boolean = false, 116 | @SerializedName("authority") 117 | val authority: Int = 0, 118 | @SerializedName("backgroundImgId") 119 | val backgroundImgId: Long = 0, 120 | @SerializedName("userType") 121 | val userType: Int = 0) 122 | 123 | 124 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/Mv.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/MvComment.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class User(@SerializedName("locationInfo") 7 | val locationInfo: Any? = null, 8 | @SerializedName("avatarUrl") 9 | val avatarUrl: String = "", 10 | @SerializedName("authStatus") 11 | val authStatus: Int = 0, 12 | @SerializedName("nickname") 13 | val nickname: String = "", 14 | @SerializedName("vipType") 15 | val vipType: Int = 0, 16 | @SerializedName("expertTags") 17 | val expertTags: Any? = null, 18 | @SerializedName("remarkName") 19 | val remarkName: Any? = null, 20 | @SerializedName("userType") 21 | val userType: Int = 0, 22 | @SerializedName("userId") 23 | val userId: String = "", 24 | @SerializedName("experts") 25 | val experts: Any? = null) 26 | 27 | 28 | data class MvComment(@SerializedName("total") 29 | val total: Int = 0, 30 | @SerializedName("code") 31 | val code: Int = 0, 32 | @SerializedName("comments") 33 | val comments: MutableList?, 34 | @SerializedName("hotComments") 35 | val hotComments: MutableList?, 36 | @SerializedName("more") 37 | val more: Boolean = false, 38 | @SerializedName("userId") 39 | val userId: Int = 0, 40 | @SerializedName("moreHot") 41 | val moreHot: Boolean = false, 42 | @SerializedName("isMusician") 43 | val isMusician: Boolean = false) 44 | 45 | 46 | data class CommentsItemInfo(@SerializedName("isRemoveHotComment") 47 | val isRemoveHotComment: Boolean = false, 48 | @SerializedName("commentId") 49 | val commentId: Long = 0, 50 | @SerializedName("likedCount") 51 | val likedCount: Int = 0, 52 | @SerializedName("time") 53 | val time: Long = 0, 54 | @SerializedName("user") 55 | val user: User, 56 | @SerializedName("liked") 57 | val liked: Boolean = false, 58 | @SerializedName("content") 59 | val content: String = "", 60 | @SerializedName("pendantData") 61 | val pendantData: Any? = null) 62 | 63 | 64 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/MvInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class MvInfo(@SerializedName("code") 7 | val code: Int = 0, 8 | @SerializedName("data") 9 | val data: MutableList?, 10 | @SerializedName("hasMore") 11 | val hasMore: Boolean = false, 12 | @SerializedName("updateTime") 13 | val updateTime: Long = 0) 14 | 15 | 16 | data class MvInfoDetail(@SerializedName("lastRank") 17 | val lastRank: Int = 0, 18 | @SerializedName("artistId") 19 | val artistId: Int = 0, 20 | @SerializedName("cover") 21 | val cover: String = "", 22 | @SerializedName("duration") 23 | val duration: Long = 0, 24 | @SerializedName("playCount") 25 | val playCount: Long = 0, 26 | @SerializedName("score") 27 | val score: Int = 0, 28 | @SerializedName("subed") 29 | val subed: Boolean = false, 30 | @SerializedName("briefDesc") 31 | val briefDesc: String = "", 32 | @SerializedName("artists") 33 | val artists: MutableList?, 34 | @SerializedName("name") 35 | val name: String = "", 36 | @SerializedName("artistName") 37 | val artistName: String = "", 38 | @SerializedName("id") 39 | val id: String = "", 40 | @SerializedName("mark") 41 | val mark: Int = 0, 42 | @SerializedName("desc") 43 | val desc: String = "") 44 | 45 | 46 | data class MvDetailInfo(@SerializedName("code") 47 | val code: Int = 0, 48 | @SerializedName("data") 49 | val data: MvInfoDetailInfo) 50 | 51 | 52 | data class SimilarMvInfo(@SerializedName("code") 53 | val code: Int = 0, 54 | @SerializedName("mvs") 55 | val data: MutableList?) 56 | 57 | data class MvInfoDetailInfo( 58 | @SerializedName("artistId") 59 | var artistId: Int, 60 | @SerializedName("artistName") 61 | var artistName: String, 62 | @SerializedName("artists") 63 | var artists: MutableList, 64 | @SerializedName("briefDesc") 65 | var briefDesc: String, 66 | @SerializedName("brs") 67 | var brs: MutableList
, 68 | @SerializedName("commentCount") 69 | var commentCount: Long, 70 | @SerializedName("commentThreadId") 71 | var commentThreadId: String, 72 | @SerializedName("cover") 73 | var cover: String, 74 | @SerializedName("coverId") 75 | var coverId: Long, 76 | @SerializedName("coverId_str") 77 | var coverIdStr: String, 78 | @SerializedName("desc") 79 | var desc: String?, 80 | @SerializedName("duration") 81 | var duration: Long, 82 | @SerializedName("id") 83 | var id: Int, 84 | @SerializedName("nType") 85 | var nType: Int, 86 | @SerializedName("name") 87 | var name: String, 88 | @SerializedName("playCount") 89 | var playCount: Long, 90 | @SerializedName("price") 91 | var price: Any, 92 | @SerializedName("publishTime") 93 | var publishTime: String, 94 | @SerializedName("shareCount") 95 | var shareCount: Long, 96 | @SerializedName("subCount") 97 | var subCount: Long, 98 | @SerializedName("videoGroup") 99 | var videoGroup: MutableList 100 | ) 101 | 102 | data class MvArtist( 103 | @SerializedName("followed") 104 | var followed: Boolean, 105 | @SerializedName("id") 106 | var id: Int, 107 | @SerializedName("img1v1Url") 108 | var img1v1Url: String, 109 | @SerializedName("name") 110 | var name: String 111 | ) 112 | 113 | data class Br( 114 | @SerializedName("br") 115 | var br: Long, 116 | @SerializedName("point") 117 | var point: Int, 118 | @SerializedName("size") 119 | var size: Int 120 | ) 121 | 122 | data class VideoGroup( 123 | @SerializedName("id") 124 | var id: Int, 125 | @SerializedName("name") 126 | var name: String, 127 | @SerializedName("type") 128 | var type: Int 129 | ) 130 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/NeteaseApiService.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.cyl.musicapi.netease.base.NeteaseBaseData 4 | import com.cyl.musicapi.netease.base.NeteaseVideoBaseData 5 | import com.cyl.musicapi.netease.video.* 6 | import com.cyl.musicapi.netease.video.Creator 7 | import com.cyl.musicapi.netease.video.VideoGroup 8 | import io.reactivex.Observable 9 | import retrofit2.http.* 10 | 11 | /** 12 | * Created by yonglong on 2017/9/11. 13 | */ 14 | interface NeteaseApiService { 15 | // @Headers({"referer: http://music.163.com"}) 16 | @GET("top/playlist") 17 | fun getTopPlaylist(@Query("cat") cat: String? = null, @Query("limit") limit: Int): Observable 18 | 19 | @GET("/top/playlist/highquality") 20 | fun getTopPlaylistHigh(@QueryMap map: MutableMap): Observable 21 | 22 | @GET("/playlist/detail") 23 | fun getPlaylistDetail(@Query("id") id: String): Observable 24 | 25 | // @Headers({"referer: http://music.163.com"}) 26 | @GET("/toplist/artist") 27 | fun getTopArtists(@Query("offset") offset: Int, @Query("limit") limit: Int): Observable 28 | 29 | /** 30 | * 获取最新mv 31 | */ 32 | @GET("/mv/first") 33 | fun getNewestMv(@Query("limit") limit: Int): Observable 34 | 35 | /** 36 | * 搜索 37 | */ 38 | @GET 39 | fun searchNetease(@Url url: String): Observable 40 | 41 | /** 42 | * 获取mv排行榜 43 | */ 44 | @GET("/top/mv") 45 | fun getTopMv(@Query("offset") offset: Int, @Query("limit") limit: Int): Observable 46 | 47 | @GET("/mv/detail") 48 | fun getMvDetailInfo(@Query("mvid") mvid: String): Observable 49 | 50 | @GET("simi/mv") 51 | fun getSimilarMv(@Query("mvid") mvid: String): Observable 52 | 53 | @GET("comment/{type}") 54 | fun getMvComment(@Path("type") type: String, @Query("id") id: String, @Query("offset") offset: Int = 0): Observable 55 | 56 | @GET("search/hot") 57 | fun getHotSearchInfo(): Observable 58 | 59 | @GET("playlist/catlist") 60 | fun getCatList(): Observable 61 | 62 | @GET("banner") 63 | fun getBanner(): Observable 64 | 65 | @GET("login/cellphone") 66 | fun loginPhone(@Query("phone") phone: String, @Query("password") password: String): Observable 67 | 68 | @GET("login") 69 | fun loginEmail(@Query("email") email: String, @Query("password") password: String): Observable 70 | 71 | /** 72 | * 注销登录 73 | */ 74 | @GET("logout") 75 | fun logout(): Observable 76 | 77 | /** 78 | * 获取登录状态 79 | */ 80 | @GET("/login/status") 81 | fun getLoginStatus(): Observable 82 | 83 | /** 84 | * 获取每日推荐歌曲(需登录) 85 | */ 86 | @GET("recommend/songs") 87 | fun recommendSongs(): Observable> 88 | 89 | /** 90 | * 获取每日推荐歌单(需登录) 91 | */ 92 | @GET("recommend/resource") 93 | fun recommendPlaylist(): Observable 94 | 95 | /** 96 | * 获取推荐歌单 97 | */ 98 | @GET("/personalized") 99 | fun personalizedPlaylist(): Observable 100 | 101 | /** 102 | * 获取推荐Mv 103 | */ 104 | @GET("/personalized/mv") 105 | fun personalizedMv(): Observable 106 | 107 | /** 108 | * 获取用户歌单 109 | */ 110 | @GET("/user/playlist") 111 | fun getUserPlaylist(@Query("uid") uid: String): Observable 112 | 113 | /** 114 | * 获取音乐榜单 115 | */ 116 | @GET("/toplist/detail") 117 | fun getTopList(): Observable 118 | 119 | /** 120 | * 获取私人FM 121 | */ 122 | @GET("/personal_fm") 123 | fun getPersonalFM(): Observable 124 | 125 | /** 126 | * 获取视频分类列表 127 | */ 128 | @GET("/video/category/list") 129 | fun getVideoGroupList(): Observable>> 130 | 131 | /** 132 | * 获取视频分类列表 133 | */ 134 | @GET("/video/group") 135 | fun getVideoList(@Query("id") id: String, @Query("offset") offset: Int = 0): Observable> 136 | 137 | /** 138 | * 获取视频详情 139 | */ 140 | @GET("/video/detail") 141 | fun getVideoDetailInfo(@Query("id") id: String): Observable>> 142 | 143 | /** 144 | * 获取相关视频列表 145 | */ 146 | @GET("/related/allvideo") 147 | fun getRelatedVideoList(@Query("id") id: String): Observable>>>> 148 | 149 | /** 150 | * 获取视频播放地址 151 | */ 152 | @GET("/video/url") 153 | fun getVideoUrlInfo(@Query("id") id: String): Observable 154 | 155 | /** 156 | * 获取MV播放地址 157 | */ 158 | @GET("/mv/url") 159 | fun getMvUrlInfo(@Query("id") id: String): Observable 160 | } 161 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/PersonalFM.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class PersonalFMData(@SerializedName("no") 7 | val no: Int = 0, 8 | @SerializedName("copyright") 9 | val copyright: Int = 0, 10 | @SerializedName("dayPlays") 11 | val dayPlays: Int = 0, 12 | @SerializedName("fee") 13 | val fee: Int = 0, 14 | @SerializedName("privilege") 15 | val privilege: Privilege, 16 | @SerializedName("mMusic") 17 | val mMusic: MMusic, 18 | @SerializedName("bMusic") 19 | val bMusic: BMusic, 20 | @SerializedName("duration") 21 | val duration: Int = 0, 22 | @SerializedName("score") 23 | val score: Int = 0, 24 | @SerializedName("rtype") 25 | val rtype: Int = 0, 26 | @SerializedName("starred") 27 | val starred: Boolean = false, 28 | @SerializedName("artists") 29 | val artists: MutableList?, 30 | @SerializedName("popularity") 31 | val popularity: Int = 0, 32 | @SerializedName("playedNum") 33 | val playedNum: Int = 0, 34 | @SerializedName("hearTime") 35 | val hearTime: Int = 0, 36 | @SerializedName("starredNum") 37 | val starredNum: Int = 0, 38 | @SerializedName("id") 39 | val id: Long = 0, 40 | @SerializedName("alg") 41 | val alg: String = "", 42 | @SerializedName("album") 43 | val album: Album, 44 | @SerializedName("lMusic") 45 | val lMusic: LMusic, 46 | @SerializedName("ringtone") 47 | val ringtone: String = "", 48 | @SerializedName("commentThreadId") 49 | val commentThreadId: String = "", 50 | @SerializedName("copyFrom") 51 | val copyFrom: String = "", 52 | @SerializedName("ftype") 53 | val ftype: Long = 0, 54 | @SerializedName("copyrightId") 55 | val copyrightId: Long = 0, 56 | @SerializedName("hMusic") 57 | val hMusic: HMusic, 58 | @SerializedName("mvid") 59 | val mvid: Long = 0, 60 | @SerializedName("name") 61 | val name: String = "", 62 | @SerializedName("disc") 63 | val disc: String = "", 64 | @SerializedName("position") 65 | val position: Int = 0, 66 | @SerializedName("mark") 67 | val mark: Int = 0, 68 | @SerializedName("status") 69 | val status: Int = 0) 70 | 71 | 72 | data class PersonalFM(@SerializedName("code") 73 | val code: Int = 0, 74 | @SerializedName("data") 75 | val data: MutableList?, 76 | @SerializedName("popAdjust") 77 | val popAdjust: Boolean = false) 78 | 79 | 80 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/PersonalizedInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class PersonalizedInfo(@SerializedName("result") 6 | val result: MutableList?, 7 | @SerializedName("code") 8 | val code: Int = 0, 9 | @SerializedName("category") 10 | val category: Int = 0, 11 | @SerializedName("hasTaste") 12 | val hasTaste: Boolean = false) 13 | 14 | /** 15 | *推荐歌单 result数组中的一条数据 16 | { 17 | "id": 2774618537, 18 | "type": 0, 19 | "name": "深夜我没有睡着, 我只是藏进了歌里", 20 | "copywriter": "编辑推荐:明天开始一切都会好的,祝你幸福!", 21 | "picUrl": "https://p1.music.126.net/KnD58aUg88-4SSEo6XnQbg==/109951164107137763.jpg", 22 | "canDislike": false, 23 | "playCount": 3562901.2, 24 | "trackCount": 45, 25 | "highQuality": false, 26 | "alg": "featured" 27 | 28 | 29 | //推荐mv 新增字段 30 | "duration": 282000 31 | "subed": false, 32 | "artists": [ 33 | { 34 | "id": 99292, 35 | "name": "Pentatonix" 36 | } 37 | ], 38 | "artistName": "Pentatonix", 39 | "artistId": 99292, 40 | 41 | }, 42 | */ 43 | data class PersonalizedItem(@SerializedName("id") 44 | val id: Long = 0, 45 | @SerializedName("type") 46 | val type: Int = 0, 47 | @SerializedName("name") 48 | val name: String = "", 49 | @SerializedName("copywriter") 50 | val copywriter: String = "", 51 | @SerializedName("picUrl") 52 | val picUrl: String = "", 53 | @SerializedName("canDislike") 54 | val canDislike: Boolean = false, 55 | @SerializedName("playCount") 56 | val playCount: Long = 0, 57 | @SerializedName("trackCount") 58 | val trackCount: Int = 0, 59 | @SerializedName("highQuality") 60 | val highQuality: Boolean = false, 61 | 62 | @SerializedName("duration") 63 | val duration: Long = 0, 64 | @SerializedName("subed") 65 | val subed: Boolean = false, 66 | @SerializedName("artists") 67 | val artists: MutableList?, 68 | @SerializedName("artistName") 69 | val artistName: String = "", 70 | @SerializedName("artistId") 71 | val artistId: Int = 0, 72 | 73 | @SerializedName("alg") 74 | val alg: String = "") 75 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/RecommendInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | /** 6 | * Created by cyl on 2018/11/6. 7 | */ 8 | 9 | data class RecommendSongsInfo( 10 | @SerializedName("dailySongs") 11 | val dailySongs: MutableList?, 12 | @SerializedName("recommendReasons") 13 | val recommendReasons: MutableList?) 14 | 15 | data class Reason(@SerializedName("reason") 16 | val reason: String, 17 | @SerializedName("songId") 18 | val songId: String) 19 | 20 | data class RecommendPlaylist(@SerializedName("recommend") 21 | val recommend: MutableList?, 22 | @SerializedName("code") 23 | val code: Int = 0, 24 | @SerializedName("msg") 25 | val msg: String = "", 26 | @SerializedName("featureFirst") 27 | val featureFirst: Boolean = false, 28 | @SerializedName("haveRcmdSongs") 29 | val haveRcmdSongs: Boolean = false) 30 | 31 | data class BMusic(@SerializedName("extension") 32 | val extension: String = "", 33 | @SerializedName("size") 34 | val size: Int = 0, 35 | @SerializedName("volumeDelta") 36 | val volumeDelta: Double = 0.0, 37 | @SerializedName("name") 38 | val name: String = "", 39 | @SerializedName("bitrate") 40 | val bitrate: Int = 0, 41 | @SerializedName("playTime") 42 | val playTime: Int = 0, 43 | @SerializedName("id") 44 | val id: String, 45 | @SerializedName("dfsId") 46 | val dfsId: Int = 0, 47 | @SerializedName("sr") 48 | val sr: Int = 0) 49 | 50 | 51 | data class Artist(@SerializedName("picUrl") 52 | val picUrl: String = "", 53 | @SerializedName("img1v1Url") 54 | val imgVUrl: String = "", 55 | @SerializedName("briefDesc") 56 | val briefDesc: String = "", 57 | @SerializedName("musicSize") 58 | val musicSize: Int = 0, 59 | @SerializedName("name") 60 | val name: String = "", 61 | @SerializedName("img1v1Id") 62 | val imgVId: Int = 0, 63 | @SerializedName("id") 64 | val id: String, 65 | @SerializedName("picId") 66 | val picId: Int = 0, 67 | @SerializedName("albumSize") 68 | val albumSize: Int = 0, 69 | @SerializedName("trans") 70 | val trans: String = "") 71 | 72 | 73 | data class MMusic(@SerializedName("extension") 74 | val extension: String = "", 75 | @SerializedName("size") 76 | val size: Int = 0, 77 | @SerializedName("volumeDelta") 78 | val volumeDelta: Double = 0.0, 79 | @SerializedName("name") 80 | val name: String = "", 81 | @SerializedName("bitrate") 82 | val bitrate: Int = 0, 83 | @SerializedName("playTime") 84 | val playTime: Int = 0, 85 | @SerializedName("id") 86 | val id: String, 87 | @SerializedName("dfsId") 88 | val dfsId: Int = 0, 89 | @SerializedName("sr") 90 | val sr: Int = 0) 91 | 92 | 93 | data class ArtistsItem(@SerializedName("picUrl") 94 | val picUrl: String = "", 95 | @SerializedName("img1v1Url") 96 | val imgVUrl: String = "", 97 | @SerializedName("briefDesc") 98 | val briefDesc: String = "", 99 | @SerializedName("musicSize") 100 | val musicSize: Int = 0, 101 | @SerializedName("name") 102 | val name: String = "", 103 | @SerializedName("img1v1Id") 104 | val imgVId: Int = 0, 105 | @SerializedName("id") 106 | val id: Long, 107 | @SerializedName("picId") 108 | val picId: Int = 0, 109 | @SerializedName("albumSize") 110 | val albumSize: Int = 0, 111 | @SerializedName("trans") 112 | val trans: String = "") 113 | 114 | 115 | data class Album(@SerializedName("transName") 116 | val transName: String = "", 117 | @SerializedName("publishTime") 118 | val publishTime: Long = 0, 119 | @SerializedName("picId_str") 120 | val picIdStr: String = "", 121 | @SerializedName("artist") 122 | val artist: Artist, 123 | @SerializedName("blurPicUrl") 124 | val blurPicUrl: String = "", 125 | @SerializedName("description") 126 | val description: String = "", 127 | @SerializedName("commentThreadId") 128 | val commentThreadId: String = "", 129 | @SerializedName("pic") 130 | val pic: Long = 0, 131 | @SerializedName("type") 132 | val type: String = "", 133 | @SerializedName("tags") 134 | val tags: String = "", 135 | @SerializedName("picUrl") 136 | val picUrl: String = "", 137 | @SerializedName("companyId") 138 | val companyId: Int = 0, 139 | @SerializedName("size") 140 | val size: Int = 0, 141 | @SerializedName("briefDesc") 142 | val briefDesc: String = "", 143 | @SerializedName("copyrightId") 144 | val copyrightId: Int = 0, 145 | @SerializedName("artists") 146 | val artists: MutableList?, 147 | @SerializedName("name") 148 | val name: String = "", 149 | @SerializedName("company") 150 | val company: String = "", 151 | @SerializedName("subType") 152 | val subType: String = "", 153 | @SerializedName("id") 154 | val id: String, 155 | @SerializedName("picId") 156 | val picId: Long = 0, 157 | @SerializedName("status") 158 | val status: Int = 0) 159 | 160 | 161 | data class Privilege(@SerializedName("st") 162 | val st: Int = 0, 163 | @SerializedName("flag") 164 | val flag: Int = 0, 165 | @SerializedName("subp") 166 | val subp: Int = 0, 167 | @SerializedName("fl") 168 | val fl: Int = 0, 169 | @SerializedName("fee") 170 | val fee: Int = 0, 171 | @SerializedName("dl") 172 | val dl: Int = 0, 173 | @SerializedName("cp") 174 | val cp: Int = 0, 175 | @SerializedName("preSell") 176 | val preSell: Boolean = false, 177 | @SerializedName("cs") 178 | val cs: Boolean = false, 179 | @SerializedName("toast") 180 | val toast: Boolean = false, 181 | @SerializedName("maxbr") 182 | val maxbr: Int = 0, 183 | @SerializedName("id") 184 | val id: String, 185 | @SerializedName("pl") 186 | val pl: Int = 0, 187 | @SerializedName("sp") 188 | val sp: Int = 0, 189 | @SerializedName("payed") 190 | val payed: Int = 0) 191 | 192 | 193 | data class LMusic(@SerializedName("extension") 194 | val extension: String = "", 195 | @SerializedName("size") 196 | val size: Int = 0, 197 | @SerializedName("volumeDelta") 198 | val volumeDelta: Double = 0.0, 199 | @SerializedName("name") 200 | val name: String = "", 201 | @SerializedName("bitrate") 202 | val bitrate: Int = 0, 203 | @SerializedName("playTime") 204 | val playTime: Int = 0, 205 | @SerializedName("id") 206 | val id: String, 207 | @SerializedName("dfsId") 208 | val dfsId: Int = 0, 209 | @SerializedName("sr") 210 | val sr: Int = 0) 211 | 212 | 213 | data class HMusic(@SerializedName("extension") 214 | val extension: String = "", 215 | @SerializedName("size") 216 | val size: Int = 0, 217 | @SerializedName("volumeDelta") 218 | val volumeDelta: Double = 0.0, 219 | @SerializedName("name") 220 | val name: String = "", 221 | @SerializedName("bitrate") 222 | val bitrate: Int = 0, 223 | @SerializedName("playTime") 224 | val playTime: Int = 0, 225 | @SerializedName("id") 226 | val id: String, 227 | @SerializedName("dfsId") 228 | val dfsId: Int = 0, 229 | @SerializedName("sr") 230 | val sr: Int = 0) 231 | 232 | 233 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/SearchInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class SearchInfo(@SerializedName("result") 7 | val result: Result, 8 | @SerializedName("code") 9 | val code: Int = 0) 10 | 11 | data class HotsItem(@SerializedName("first") 12 | val first: String = "", 13 | @SerializedName("second") 14 | val second: Int = 0) 15 | 16 | data class Result(@SerializedName("hots") 17 | val hots: MutableList?, 18 | @SerializedName("playlists") 19 | val playlists: MutableList?, 20 | @SerializedName("playlistCount") 21 | val playlistCount: Int, 22 | @SerializedName("mvs") 23 | val mvs: MutableList?, 24 | @SerializedName("mvCount") 25 | val mvCount: Int, 26 | @SerializedName("artists") 27 | val artists: MutableList?, 28 | @SerializedName("artistCount") 29 | val artistCount: Int) 30 | 31 | 32 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/TopList.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | 6 | data class TopList( 7 | @SerializedName("artistToplist") 8 | val artistToplist: ArtistToplist, 9 | @SerializedName("code") 10 | val code: Int, 11 | @SerializedName("list") 12 | val list: MutableList 13 | ) 14 | 15 | data class ArtistToplist( 16 | @SerializedName("coverUrl") 17 | val coverUrl: String, 18 | @SerializedName("name") 19 | val name: String, 20 | @SerializedName("position") 21 | val position: Int, 22 | @SerializedName("upateFrequency") 23 | val upateFrequency: String, 24 | @SerializedName("updateFrequency") 25 | val updateFrequency: String 26 | ) 27 | 28 | 29 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/netease/base/Data.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.netease.base 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | /** 6 | * 获取视频分类列表通用数据类 7 | */ 8 | data class NeteaseBaseData(@SerializedName("code") 9 | val code: Int = 0, 10 | @SerializedName("data") 11 | val data: T?, 12 | @SerializedName("message") 13 | val message: String?) 14 | 15 | /** 16 | * 视频列表返回基类 17 | */ 18 | data class NeteaseVideoBaseData(@SerializedName("code") 19 | val code: Int = 0, 20 | @SerializedName("datas") 21 | val data: MutableList?, 22 | @SerializedName("msg") 23 | val msg: String = "", 24 | @SerializedName("message") 25 | val message: String?, 26 | @SerializedName("hasmore") 27 | val hasmore: Boolean = false, 28 | @SerializedName("rcmdLimit") 29 | val rcmdLimit: Int = 0) -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/ApiModel.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | /** 4 | * Created by D22434 on 2018/1/3. 5 | * 基类 6 | */ 7 | 8 | class ApiModel(var msg: String?, var status: String?, var data: T?) 9 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/ErrorInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class ErrorInfo(@SerializedName("msg") 6 | val msg: String = "") -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/MusicInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | /** 7 | * 数据结构 8 | * http://rap2.taobao.org/repository/editor?id=9460&itf=52687 9 | */ 10 | 11 | data class ArtistsItem(@SerializedName("id") 12 | val id: String = "", 13 | @SerializedName("name") 14 | val name: String = "") 15 | 16 | data class Album(@SerializedName("id") 17 | val id: String? = "", 18 | @SerializedName("name") 19 | val name: String? = "", 20 | @SerializedName("cover") 21 | val cover: String? = "") 22 | 23 | data class MusicInfo(@SerializedName("id") 24 | var id: String?, 25 | @SerializedName("songId") 26 | val songId: String? = null, 27 | @SerializedName("name") 28 | val name: String? = "", 29 | @SerializedName("artists") 30 | val artists: List?, 31 | @SerializedName("album") 32 | val album: Album?, 33 | @SerializedName("vendor") 34 | var vendor: String? = "", 35 | @SerializedName("dl") 36 | val dl: Boolean = false, 37 | @SerializedName("cp") 38 | val cp: Boolean = false, 39 | @SerializedName("quality") 40 | val quality: QualityBean?) 41 | 42 | data class QualityBean(@SerializedName("192") 43 | val high: Boolean = false, 44 | @SerializedName("320") 45 | val hq: Boolean = false, 46 | @SerializedName("999") 47 | val sq: Boolean = false) 48 | 49 | data class CollectBatchBean(@SerializedName("ids") 50 | val ids: List? = null, 51 | @SerializedName("vendor") 52 | val vendor: String? = null) 53 | 54 | data class CollectBatch2Bean(@SerializedName("collects") 55 | val collects: MutableList? = null) 56 | 57 | data class CollectDetail(@SerializedName("id") 58 | val id: String, 59 | @SerializedName("vendor") 60 | val vendor: String) 61 | 62 | data class CollectResult(@SerializedName("failedList") 63 | val failedList: List?) 64 | 65 | data class CollectFailed(@SerializedName("id") 66 | val id: String?, 67 | @SerializedName("msg") 68 | val msg: String?) 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/PlaylistApiService.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | 4 | import io.reactivex.Observable 5 | import okhttp3.ResponseBody 6 | import retrofit2.http.* 7 | 8 | /** 9 | * Created by master on 2018/4/5. 10 | */ 11 | 12 | interface PlaylistApiService { 13 | /** 14 | * 获取歌单 15 | * 16 | * @param token 秘钥 17 | * @return 18 | */ 19 | @GET("playlist") 20 | fun getOnlinePlaylist(@Header("accesstoken") token: String): Observable 21 | 22 | /** 23 | * 获取歌单数据 24 | * 25 | * @param token 秘钥 26 | * @param id 歌单id 27 | * @return 28 | */ 29 | @GET("playlist/{id}") 30 | fun getMusicList(@Header("accesstoken") token: String, @Path("id") id: String): Observable 31 | 32 | /** 33 | * 删除歌单 34 | * 35 | * @param token 秘钥 36 | * @param id 歌单id 37 | * @return 38 | */ 39 | @DELETE("playlist") 40 | fun deleteMusic(@Header("accesstoken") token: String, @Query("id") id: String): Observable 41 | 42 | 43 | /** 44 | * 重命名歌单 45 | * 46 | * @param token 秘钥 47 | * @param id 歌单id 48 | * @param playlist 歌单信息 49 | * @return 50 | */ 51 | @PUT("playlist/{id}") 52 | @Headers("Content-Type: application/json") 53 | fun renameMusic(@Header("accesstoken") token: String, @Path("id") id: String, @Body playlist: PlaylistInfo): Observable 54 | 55 | /** 56 | * 新建歌单 57 | * 58 | * @param token 59 | * @return 60 | */ 61 | @POST("playlist") 62 | @Headers("Content-Type: application/json") 63 | fun createPlaylist(@Header("accesstoken") token: String, @Body playlist: PlaylistInfo): Observable 64 | 65 | /** 66 | * 收藏歌曲 67 | * 68 | * @param token 69 | * @param id 歌单id 70 | * @param musicInfo 歌曲信息 71 | * @return 72 | */ 73 | @POST("playlist/{id}") 74 | @Headers("Content-Type: application/json") 75 | fun collectMusic(@Header("accesstoken") token: String, @Path("id") id: String, @Body musicInfo: MusicInfo): Observable 76 | 77 | /** 78 | * 取消收藏歌曲 79 | * 80 | * @param token 秘钥 81 | * @return 82 | */ 83 | @DELETE("playlist/{id}") 84 | fun disCollectMusic(@Header("accesstoken") token: String, @Path("id") id: String, @Query("id") songid: String): Observable 85 | 86 | /** 87 | * 获取用户信息 88 | * 89 | * @param token 90 | * @param openid 91 | * @return 92 | */ 93 | @GET("auth/qq/android") 94 | fun getUserInfo(@Query("access_token") token: String, 95 | @Query("openid") openid: String): Observable 96 | 97 | 98 | } 99 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/PlaylistInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class PlaylistInfo( 7 | @SerializedName("name") 8 | val name: String = "", 9 | @SerializedName("description") 10 | val description: String? = null, 11 | @SerializedName("cover") 12 | val cover: String? = null, 13 | @SerializedName("playCount") 14 | val playCount: Long = 0, 15 | @SerializedName("id") 16 | val id: String = "", 17 | @SerializedName("total") 18 | val total: Int = 0, 19 | @SerializedName("list") 20 | val list: MutableList? = null) 21 | 22 | 23 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/playlist/UserInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.playlist 2 | 3 | 4 | import com.google.gson.annotations.SerializedName 5 | 6 | data class UserInfo(@SerializedName("nickname") 7 | val nickname: String = "", 8 | @SerializedName("avatar") 9 | val avatar: String = "", 10 | @SerializedName("token") 11 | val token: String = "", 12 | @SerializedName("id") 13 | val id: Int = 0) -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/qq/QQApiKey.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.qq; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by yonglong on 2018/1/14. 7 | */ 8 | 9 | public class QQApiKey { 10 | /** 11 | * code : 0 12 | * sip : ["http://dl.stream.qqmusic.qq.com/","http://isure.stream.qqmusic.qq.com/"] 13 | * thirdip : ["http://thirdparty.gtimg.com/abcd1234/","http://thirdparty.gtimg.com/abcd1234/"] 14 | * testfile2g : C100003mAan70zUy5O.m4a 15 | * testfilewifi : C100003mAan70zUy5O.m4a 16 | * key : 8DA0CDC57B9BA57AB488AA1E582875CF2D41DF9201581863B24AF3758164C7D9C6AB21B33668F55E556262EB60AF60979EE8E0A0C1921C87 17 | */ 18 | private int code; 19 | private String testfile2g; 20 | private String testfilewifi; 21 | private String key; 22 | private List sip; 23 | private List thirdip; 24 | 25 | public int getCode() { 26 | return code; 27 | } 28 | 29 | public void setCode(int code) { 30 | this.code = code; 31 | } 32 | 33 | public String getTestfile2g() { 34 | return testfile2g; 35 | } 36 | 37 | public void setTestfile2g(String testfile2g) { 38 | this.testfile2g = testfile2g; 39 | } 40 | 41 | public String getTestfilewifi() { 42 | return testfilewifi; 43 | } 44 | 45 | public void setTestfilewifi(String testfilewifi) { 46 | this.testfilewifi = testfilewifi; 47 | } 48 | 49 | public String getKey() { 50 | return key; 51 | } 52 | 53 | public void setKey(String key) { 54 | this.key = key; 55 | } 56 | 57 | public List getSip() { 58 | return sip; 59 | } 60 | 61 | public void setSip(List sip) { 62 | this.sip = sip; 63 | } 64 | 65 | public List getThirdip() { 66 | return thirdip; 67 | } 68 | 69 | public void setThirdip(List thirdip) { 70 | this.thirdip = thirdip; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/qq/QQApiService.kt: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.qq 2 | 3 | import com.cyl.musicapi.bean.ArtistsData 4 | import com.cyl.musicapi.bean.ArtistsDataInfo 5 | import io.reactivex.Observable 6 | import okhttp3.ResponseBody 7 | import retrofit2.http.GET 8 | import retrofit2.http.HeaderMap 9 | import retrofit2.http.Headers 10 | import retrofit2.http.Query 11 | import retrofit2.http.QueryMap 12 | import retrofit2.http.Streaming 13 | import retrofit2.http.Url 14 | 15 | /** 16 | * Created by D22434 on 2018/1/5. 17 | */ 18 | 19 | interface QQApiService { 20 | //http://c.y.qq.com/soso/fcgi-bin/search_cp? 21 | /* 22 | 'p': page, 23 | 'n': limit, 24 | 'w': key, 25 | 'aggr': 1, 26 | 'lossless': 1, 27 | 'cr': 1 28 | */ 29 | @Headers("referer: https://y.qq.com/portal/player.html") 30 | @GET("soso/fcgi-bin/search_cp?") 31 | fun searchByQQ(@QueryMap params: Map): Observable 32 | 33 | @Headers("referer: https://y.qq.com/portal/player.html") 34 | @GET("/cgi-bin/musicu.fcg?") 35 | fun getQQArtists(@Query("data") data: String): Observable 36 | 37 | @Headers("referer: https://y.qq.com/portal/player.html") 38 | @GET("/cgi-bin/musicu.fcg?") 39 | fun getQQArtists1(@Query("data") data: String): Observable 40 | 41 | } 42 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/qq/QQApiServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.qq;//package com.cyl.musicapi.qq; 2 | // 3 | //import android.util.Base64; 4 | // 5 | //import com.cyl.musiclake.common.Constants; 6 | //import com.cyl.musiclake.bean.Music; 7 | //import com.cyl.musiclake.api.net.ApiManager; 8 | //import com.cyl.musiclake.utils.FileUtils; 9 | //import com.cyl.musiclake.utils.LogUtil; 10 | // 11 | //import java.io.UnsupportedEncodingException; 12 | //import java.util.ArrayList; 13 | //import java.util.HashMap; 14 | //import java.util.List; 15 | //import java.util.Map; 16 | // 17 | //import io.reactivex.Observable; 18 | // 19 | ///** 20 | // * Created by D22434 on 2018/1/5. 21 | // */ 22 | // 23 | //public class QQApiServiceImpl { 24 | // private static final String TAG = "QQApiServiceImpl"; 25 | // 26 | // public static QQApiService getApiService() { 27 | // return ApiManager.getInstance().create(QQApiService.class, "http://c.y.qq.com/"); 28 | // } 29 | // 30 | // /** 31 | // * @param 32 | // * @return 33 | // */ 34 | // @SuppressWarnings({"unchecked", "varargs"}) 35 | // public static Observable> search(String key, int limit, int page) { 36 | // Map params = new HashMap<>(); 37 | // params.put("p", String.valueOf(page)); //page 38 | // params.put("n", String.valueOf(limit));//limit 39 | // params.put("w", key);// key 40 | // params.put("aggr", "1"); 41 | // params.put("cr", "1"); 42 | // params.put("lossless", "1"); 43 | // params.put("format", "json"); 44 | // return getApiService().searchByQQ(params) 45 | // .flatMap(qqApiModel -> { 46 | // List musicList = new ArrayList<>(); 47 | // List songList = qqApiModel.getData().getSong().getList(); 48 | // for (int i = 0; i < songList.size(); i++) { 49 | // QQApiModel.DataBean.SongBean.ListBean song = songList.get(i); 50 | // Music music = new Music(); 51 | // music.setType(Constants.QQ); 52 | // music.setOnline(true); 53 | // music.setMid(song.getSongmid()); 54 | // music.setTitle(song.getSongname()); 55 | // String artists = song.getSinger().get(0).getName(); 56 | // String artistIds = song.getSinger().get(0).getId() + ""; 57 | // for (int j = 1; j < song.getSinger().size(); j++) { 58 | // artists += "," + song.getSinger().get(j).getName(); 59 | // artistIds += "," + song.getSinger().get(j).getId(); 60 | // } 61 | // music.setArtist(artists); 62 | // music.setArtistId(artistIds); 63 | // music.setAlbum(song.getAlbumname()); 64 | // music.setAlbumId(String.valueOf(song.getAlbumid())); 65 | // music.setDuration(song.getPubtime()); 66 | // //qq音乐播放地址前缀,代表音乐品质 M500一般,M800高 67 | //// music.setPrefix(song.getSize128() != 0 ? "M500" : "M800"); 68 | // String cover = "https://y.gtimg.cn/music/photo_new/T002R300x300M000" + song.getAlbummid() + ".jpg"; 69 | // String coverBig = "https://y.gtimg.cn/music/photo_new/T002R500x500M000" + song.getAlbummid() + ".jpg"; 70 | // String coverSmall = "https://y.gtimg.cn/music/photo_new/T002R150x150M000" + song.getAlbummid() + ".jpg"; 71 | // music.setCoverUri(cover); 72 | // music.setCoverBig(coverBig); 73 | // music.setCoverSmall(coverSmall); 74 | // musicList.add(music); 75 | // } 76 | // LogUtil.e("search", page + "--" + limit + "qq :" + musicList.size()); 77 | // return Observable.fromArray(musicList); 78 | // }); 79 | // } 80 | // 81 | // @SuppressWarnings({"unchecked", "varargs"}) 82 | // public static Observable getMusicInfo(Music music) { 83 | // double guid = Math.floor(Math.random() * 1000000000); 84 | // String requestUrl = Constants.BASE_URL_QQ_MUSIC_KEY + "json=3&guid=" + guid + "&format=json"; 85 | // return getApiService().getTokenKey(requestUrl) 86 | // .flatMap(qqApiKey -> { 87 | // String key = qqApiKey.getKey(); 88 | // String url = Constants.BASE_URL_QQ_MUSIC_URL + 89 | // "M500" + music.getId() + ".mp3?vkey=" + key + "&guid=" + guid + "&fromtag=30"; 90 | // LogUtil.e(TAG, url); 91 | // music.setUri(url); 92 | // return Observable.fromArray(music); 93 | // }); 94 | // 95 | // } 96 | // 97 | // @SuppressWarnings({"unchecked", "varargs"}) 98 | // public static Observable getQQLyric(Music music) { 99 | // //本地歌词路径 100 | // String mLyricPath = FileUtils.getLrcDir() + music.getTitle() + "-" + music.getArtist() + ".lrc"; 101 | // //网络歌词 102 | // String mLyricUrl = "https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid=" + music.getId() + "&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0"; 103 | // if (FileUtils.exists(mLyricPath)) { 104 | // return Observable.create(emitter -> { 105 | // try { 106 | // String lyric = FileUtils.readFile(mLyricPath); 107 | // emitter.onNext(lyric); 108 | // emitter.onComplete(); 109 | // } catch (Exception e) { 110 | // emitter.onError(e); 111 | // } 112 | // }); 113 | // } 114 | // return getApiService().getQQLyric(mLyricUrl) 115 | // .flatMap(qqLyricInfo -> { 116 | // System.out.println(mLyricUrl); 117 | // System.out.println(qqLyricInfo.toString()); 118 | // String lyric = null; 119 | // byte[] asByte = Base64.decode(qqLyricInfo.getLyric(), Base64.DEFAULT); 120 | // try { 121 | // lyric = new String(asByte, "utf-8"); 122 | // } catch (UnsupportedEncodingException e) { 123 | // e.printStackTrace(); 124 | // } 125 | // //保存文件 126 | // boolean save = FileUtils.writeByteArrayToFile(asByte, mLyricPath); 127 | // LogUtil.e("保存网络歌词:" + save); 128 | // return Observable.fromArray(lyric); 129 | // }); 130 | // } 131 | //} 132 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/qq/QQLyricInfo.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.qq; 2 | 3 | /** 4 | * Created by D22434 on 2018/1/16. 5 | */ 6 | 7 | public class QQLyricInfo { 8 | /** 9 | * retcode : 0 10 | * code : 0 11 | * subcode : 0 12 | * lyric : W3RpOuS9oOi/mOimgeaIkeaAjuagtyAo44CK5aaI5aaI5YOP6Iqx5YS/5LiA5qC344CL55S16KeG5Ymn54mH5bC+5puyfOOAiuWmguaenOaIkeeIseS9oOOAi+eUteinhuWJp+aPkuabsildClthcjrolpvkuYvosKZdClthbDrmhI/lpJZdCltieTpdCltvZmZzZXQ6MF0KWzAwOjAwLjQ2XeS9oOi/mOimgeaIkeaAjuagtyAo44CK5aaI5aaI5YOP6Iqx5YS/5LiA5qC344CL55S16KeG5Ymn54mH5bC+5puyfOOAiuWmguaenOaIkeeIseS9oOOAi+eUteinhuWJp+aPkuabsikgLSDolpvkuYvosKYKWzAwOjAxLjkwXeivje+8muiWm+S5i+iwpgpbMDA6MDIuMDhd5puy77ya6Jab5LmL6LCmClswMDowMi40OF0KWzAwOjI0LjUzXeS9oOWBnOWcqOS6hui/meadoeaIkeS7rOeGn+aCieeahOihlwpbMDA6MjguNDNdClswMDozNC41M13miorkvaDlh4blpIflpb3nmoTlj7Dor43lhajlv7XkuIDpgY0KWzAwOjM4LjMxXQpbMDA6NDIuMzRd5oiR6L+Y5Zyo6YCe5by6IOivtOedgOiwjgpbMDA6NDUuODVdClswMDo0Ny4wMV3kuZ/msqHog73lipvpga7mjKEg5L2g5Y6755qE5pa55ZCRClswMDo1MS40Ml0KWzAwOjUyLjk0XeiHs+WwkeWIhuW8gOeahOaXtuWAmeaIkeiQveiQveWkp+aWuQpbMDA6NTkuNDJdClswMTowNC41N13miJHlkI7mnaXpg73kvJrpgInmi6nnu5Xov4fpgqPmnaHooZcKWzAxOjA4LjQzXQpbMDE6MTQuMzVd5Y+I5aSa5biM5pyb5Zyo5Y+m5LiA5p2h6KGX6IO96YGH6KeBClswMToxOC40Nl0KWzAxOjIyLjIxXeaAneW/teWcqOmAnuW8uiDkuI3ogq/lv5gKWzAxOjI1Ljk1XQpbMDE6MjYuNjNd5oCq5oiR5rKh6IO95Yqb6Lef6ZqPIOS9oOWOu+eahOaWueWQkQpbMDE6MzEuNTVdClswMTozMi43MF3oi6XotorniLHotorooqvliqgg6LaK6KaB6JC96JC95aSn5pa5ClswMTozOS4zNl0KWzAxOjQyLjA0XeS9oOi/mOimgeaIkeaAjuagtyDopoHmgI7moLcKWzAxOjQ2LjI4XQpbMDE6NDYuODld5L2g56qB54S25p2l55qE55+t5L+h5bCx5aSf5oiR5oKy5LykClswMTo1MS4xNl0KWzAxOjUxLjg2XeaIkeayoeiDveWKm+mBl+W/mCDkvaDkuI3nlKjmj5DphpLmiJEKWzAxOjU2LjQ0XQpbMDE6NTcuMDhd5ZOq5oCV57uT5bGA5bCx6L+Z5qC3ClswMjowMS4wOV0KWzAyOjAyLjA1XeaIkei/mOiDveaAjuagtyDog73mgI7moLcKWzAyOjA2LjIxXQpbMDI6MDYuODdd5pyA5ZCO6L+Y5LiN5piv6JC95b6X5oOF5Lq655qE56uL5Zy6ClswMjoxMS4zM10KWzAyOjExLjg4XeS9oOS7juadpeS4jeS8muaDsyDmiJHkvZXlv4Xov5nmoLcKWzAyOjIwLjA1XQpbMDI6NDQuNzJd5oiR5oWi5oWi55qE5Zue5Yiw6Ieq5bex55qE55Sf5rS75ZyIClswMjo0OC43MV0KWzAyOjU0LjM3XeS5n+W8gOWni+WPr+S7peaOpeinpuaWsOeahOS6uumAiQpbMDI6NTguNThdClswMzowMi4yNF3niLHkvaDliLDmnIDlkI4g5LiN55eb5LiN55eSClswMzowNi4xNV0KWzAzOjA3LjI2XeeVmeiogOWcqOiuoei+gyDosIHniLHov4fkuIDlnLoKWzAzOjExLjI1XQpbMDM6MTIuOTBd5oiR5Ymp5LiL5LiA5bygIOayoeWQjuaClOeahOaooeagtwpbMDM6MTkuMTVdClswMzoyMi4wNl3kvaDov5jopoHmiJHmgI7moLcg6KaB5oCO5qC3ClswMzoyNi4xNl0KWzAzOjI2Ljg1XeS9oOWNg+S4h+S4jeimgeWcqOaIkeWpmuekvOeahOeOsOWcugpbMDM6MzEuMTNdClswMzozMS45MV3miJHlkKzlrozkvaDniLHnmoTmrYwg5bCx5LiK5LqG6L2mClswMzozNi43N10KWzAzOjM3LjUzXeeIsei/h+S9oOW+iOWAvOW+lwpbMDM6NDAuOThdClswMzo0MS45M13miJHkuI3opoHkvaDmgI7moLcg5rKh5oCO5qC3ClswMzo0Ni4wNl0KWzAzOjQ2Ljk1XeaIkemZquS9oOi1sOeahOi3r+S9oOS4jeiDveW/mApbMDM6NTAuODldClswMzo1Mi4wNV3lm6DkuLrpgqPmmK/miJEg5pyA5b+r5LmQ55qE5pe25YWJClswNDowMC4wNF0KWzA0OjA0LjM0XeWQjuadpeaIkeeahOeUn+a0u+i/mOeul+eQhuaDswpbMDQ6MDguNTNdClswNDoxNC41MV3msqHkuLrkvaDokL3liLDlraTljZXnmoTkuIvlnLoKWzA0OjE4LjUwXQpbMDQ6MjIuMzZd5pyJ5LiA5aSp5pma5LiKIOaipuS4gOWcugpbMDQ6MjUuODhdClswNDoyNy4wNV3kvaDnmb3lj5Hoi43oi40g6K+05bim5oiR5rWB5rWqClswNDozMS41OV0KWzA0OjMzLjIzXeaIkei/mOaYr+ayoeeKueixqyDlsLHpmo/kvaDljrvlpKnloIIKWzA0OjQwLjA3XQpbMDQ6NDMuMzVd5LiN566h6IO95oCO5qC3IOaIkeiDvemZquS9oOWIsOWkqeS6rg== 13 | * trans : 14 | */ 15 | 16 | private int retcode; 17 | private int code; 18 | private int subcode; 19 | private String lyric; 20 | private String trans; 21 | 22 | public int getRetcode() { 23 | return retcode; 24 | } 25 | 26 | public void setRetcode(int retcode) { 27 | this.retcode = retcode; 28 | } 29 | 30 | public int getCode() { 31 | return code; 32 | } 33 | 34 | public void setCode(int code) { 35 | this.code = code; 36 | } 37 | 38 | public int getSubcode() { 39 | return subcode; 40 | } 41 | 42 | public void setSubcode(int subcode) { 43 | this.subcode = subcode; 44 | } 45 | 46 | public String getLyric() { 47 | return lyric; 48 | } 49 | 50 | public void setLyric(String lyric) { 51 | this.lyric = lyric; 52 | } 53 | 54 | public String getTrans() { 55 | return trans; 56 | } 57 | 58 | public void setTrans(String trans) { 59 | this.trans = trans; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/xiami/XiamiService.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.xiami; 2 | 3 | import java.util.Map; 4 | 5 | import io.reactivex.Observable; 6 | import okhttp3.ResponseBody; 7 | import retrofit2.http.GET; 8 | import retrofit2.http.HeaderMap; 9 | import retrofit2.http.Headers; 10 | import retrofit2.http.QueryMap; 11 | import retrofit2.http.Streaming; 12 | import retrofit2.http.Url; 13 | 14 | /** 15 | * Created by yonglong on 2018/1/15. 16 | */ 17 | 18 | public interface XiamiService { 19 | 20 | //http://c.y.qq.com/soso/fcgi-bin/search_cp? 21 | /* 22 | 'p': page, 23 | 'n': limit, 24 | 'w': key, 25 | 'aggr': 1, 26 | 'lossless': 1, 27 | 'cr': 1 28 | */ 29 | @GET 30 | Observable getSongUrl(@Url String baseUrl); 31 | 32 | @Headers({"referer: http://h.xiami.com/"}) 33 | @GET("web?") 34 | Observable searchByXiaMi(@QueryMap Map params); 35 | 36 | // @Headers({"referer: http://h.xiami.com/"}) 37 | @GET 38 | Observable getXiamiLyric(@Url String baseUrl); 39 | 40 | @Streaming 41 | @GET 42 | Observable downloadFile(@Url String downloadUrl, @HeaderMap Map params); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /musicapi/src/main/java/com/cyl/musicapi/xiami/XiamiServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi.xiami;//package com.cyl.musicapi.xiami; 2 | // 3 | //import com.cyl.musiclake.bean.Music; 4 | //import com.cyl.musiclake.common.Constants; 5 | //import com.cyl.musiclake.api.net.ApiManager; 6 | //import com.cyl.musiclake.utils.FileUtils; 7 | //import com.cyl.musiclake.utils.LogUtil; 8 | // 9 | //import java.util.ArrayList; 10 | //import java.util.HashMap; 11 | //import java.util.List; 12 | //import java.util.Map; 13 | // 14 | //import io.reactivex.Observable; 15 | // 16 | ///** 17 | // * Created by yonglong on 2018/1/15. 18 | // */ 19 | // 20 | //public class XiamiServiceImpl { 21 | // 22 | // private static final String TAG = "XiamiServiceImpl"; 23 | // 24 | // public static XiamiService getApiService() { 25 | // return ApiManager.getInstance().create(XiamiService.class, Constants.BASE_XIAMI_URL); 26 | // } 27 | // 28 | // /** 29 | // * 搜索虾米音乐 30 | // * 31 | // * @param key 关键字 32 | // * @param limit 33 | // * @param page 34 | // * @return 35 | // */ 36 | // @SuppressWarnings({"unchecked", "varargs"}) 37 | // public static Observable> search(String key, int limit, int page) { 38 | // Map params = new HashMap<>(); 39 | // params.put("v", "2.0"); //page 40 | // params.put("page", String.valueOf(page)); //page 41 | // params.put("limit", String.valueOf(limit));//limit 42 | // params.put("key", key);// key 43 | // params.put("r", "search/songs"); 44 | // params.put("app_key", "1"); 45 | // params.put("format", "json"); 46 | // return getApiService().searchByXiaMi(params) 47 | // .flatMap(xiaMiModel -> { 48 | // List musicList = new ArrayList<>(); 49 | // List songs = xiaMiModel.getData().getSongs(); 50 | // for (int i = 0; i < songs.size(); i++) { 51 | // XiamiModel.DataBean.SongsBean song = songs.get(i); 52 | // Music music = new Music(); 53 | // music.setType(Constants.XIAMI); 54 | // music.setOnline(true); 55 | // music.setMid(String.valueOf(song.getSong_id())); 56 | // music.setTitle(song.getSong_name()); 57 | // music.setArtist(song.getArtist_name()); 58 | // music.setArtistId(String.valueOf(song.getArtist_id())); 59 | // music.setAlbum(song.getAlbum_name()); 60 | // music.setAlbumId(String.valueOf(song.getAlbum_id())); 61 | // music.setUri(song.getListen_file()); 62 | // String cover = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_250w_250h"; 63 | // String coverBig = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_400w_400h"; 64 | // String coverSmall = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_150w_150h"; 65 | // music.setCoverUri(cover); 66 | // music.setCoverBig(coverBig); 67 | // music.setCoverSmall(coverSmall); 68 | // music.setLyric(song.getLyric()); 69 | // musicList.add(music); 70 | // } 71 | // LogUtil.e("search", page + "--" + limit + "xiami :" + musicList.size()); 72 | // return Observable.fromArray(musicList); 73 | // }); 74 | // } 75 | // 76 | // @SuppressWarnings({"unchecked", "varargs"}) 77 | // public static Observable getMusicInfo(Music musicInfo) { 78 | // Map params = new HashMap<>(); 79 | // params.put("v", "2.0"); //page 80 | // params.put("page", "1"); //page 81 | // params.put("limit", "1");//limit 82 | // params.put("key", musicInfo.getTitle() + "-" + musicInfo.getArtist());// key 83 | // params.put("r", "search/songs"); 84 | // params.put("app_key", "1"); 85 | // params.put("format", "json"); 86 | // return getApiService().searchByXiaMi(params) 87 | // .flatMap(xiaMiModel -> { 88 | // List musicList = new ArrayList<>(); 89 | // List songs = xiaMiModel.getData().getSongs(); 90 | // for (int i = 0; i < songs.size(); i++) { 91 | // XiamiModel.DataBean.SongsBean song = songs.get(i); 92 | // Music music = new Music(); 93 | // music.setType(Constants.XIAMI); 94 | // music.setOnline(true); 95 | // music.setMid(String.valueOf(song.getSong_id())); 96 | // music.setTitle(song.getSong_name()); 97 | // music.setArtist(song.getArtist_name()); 98 | // music.setArtistId(String.valueOf(song.getArtist_id())); 99 | // music.setAlbum(song.getAlbum_name()); 100 | // music.setAlbumId(String.valueOf(song.getAlbum_id())); 101 | // music.setUri(song.getListen_file()); 102 | // String cover = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_250w_250h"; 103 | // String coverBig = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_400w_400h"; 104 | // String coverSmall = song.getAlbum_logo() + "@1e_1c_0i_1o_100Q_150w_150h"; 105 | // music.setCoverUri(cover); 106 | // music.setCoverBig(coverBig); 107 | // music.setCoverSmall(coverSmall); 108 | // music.setLyric(song.getLyric()); 109 | // musicList.add(music); 110 | // } 111 | // LogUtil.e("search", "xiami :" + musicList.size()); 112 | // return Observable.fromArray(musicList.get(0)); 113 | // }); 114 | // } 115 | // 116 | // 117 | // @SuppressWarnings({"unchecked", "varargs"}) 118 | // public static Observable getXimaiLyric(Music music) { 119 | // //本地歌词路径 120 | // String mLyricPath = FileUtils.getLrcDir() + music.getTitle() + "-" + music.getArtist() + ".lrc"; 121 | // //网络歌词 122 | // String mLyricUrl = music.getLyric(); 123 | // if (FileUtils.exists(mLyricPath)) { 124 | // return Observable.create(emitter -> { 125 | // try { 126 | // String lyric = FileUtils.readFile(mLyricPath); 127 | // emitter.onNext(lyric); 128 | // emitter.onComplete(); 129 | // } catch (Exception e) { 130 | // emitter.onError(e); 131 | // } 132 | // }); 133 | // } 134 | // return getApiService().getXiamiLyric(mLyricUrl) 135 | // .flatMap(xiaMiLyricInfo -> { 136 | // String lyric = xiaMiLyricInfo.string(); 137 | // //保存文件 138 | // boolean save = FileUtils.writeText(mLyricPath, lyric); 139 | // LogUtil.e("保存网络歌词:" + save); 140 | // return Observable.fromArray(lyric); 141 | // }); 142 | // } 143 | //} 144 | -------------------------------------------------------------------------------- /musicapi/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | musicapi 3 | 4 | -------------------------------------------------------------------------------- /musicapi/src/test/java/com/cyl/musicapi/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.cyl.musicapi; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':musicapi', ':musicapi' 2 | --------------------------------------------------------------------------------