mirror of
https://github.com/czp3009/bilibili-api.git
synced 2025-02-19 20:50:28 +08:00
增加 API
This commit is contained in:
parent
eb588f5798
commit
075d880f53
11
README.md
11
README.md
@ -55,7 +55,7 @@ https://app.bilibili.com
|
||||
|
||||
BilibiliClient().appAPI
|
||||
|
||||
为 app 提供通用接口, 例如获取个人信息. 完整示例如下
|
||||
总站 API. 获取个人信息的完整示例如下:
|
||||
|
||||
runBlocking {
|
||||
val bilibiliClient = BilibiliClient().apply {
|
||||
@ -70,7 +70,14 @@ https://api.vc.bilibili.com
|
||||
|
||||
BilibiliClient().vcAPI
|
||||
|
||||
小视频有关的接口.
|
||||
小视频.
|
||||
|
||||
# member
|
||||
https://member.bilibili.com
|
||||
|
||||
BilibiliClient().memberAPI
|
||||
|
||||
创作中心.
|
||||
|
||||
# License
|
||||
GPL V3
|
||||
|
@ -24,6 +24,11 @@ object BaseUrl {
|
||||
*/
|
||||
const val vc = "https://api.vc.bilibili.com"
|
||||
|
||||
/**
|
||||
* 创作中心
|
||||
*/
|
||||
const val member = "https://member.bilibili.com"
|
||||
|
||||
/**
|
||||
* 直播
|
||||
*/
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.hiczp.bilibili.api
|
||||
|
||||
import com.hiczp.bilibili.api.app.AppAPI
|
||||
import com.hiczp.bilibili.api.member.MemberAPI
|
||||
import com.hiczp.bilibili.api.message.MessageAPI
|
||||
import com.hiczp.bilibili.api.passport.PassportAPI
|
||||
import com.hiczp.bilibili.api.passport.model.LoginResponse
|
||||
@ -84,15 +85,15 @@ class BilibiliClient(
|
||||
"ts" to { Instant.now().epochSecond.toString() }
|
||||
)
|
||||
|
||||
private val defaultCommonQueryParamInterceptor = CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray)
|
||||
private val defaultQuerySignInterceptor = SortAndSignInterceptor(ParamType.QUERY, billingClientProperties.appSecret)
|
||||
private val defaultFormSignInterceptor = SortAndSignInterceptor(ParamType.FORM_URL_ENCODED, billingClientProperties.appSecret)
|
||||
|
||||
/**
|
||||
* 用户鉴权相关的接口
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val passportAPI by lazy {
|
||||
createAPI<PassportAPI>(BaseUrl.passport, logLevel,
|
||||
createAPI<PassportAPI>(BaseUrl.passport,
|
||||
defaultCommonHeaderInterceptor,
|
||||
CommonParamInterceptor(ParamType.FORM_URL_ENCODED,
|
||||
"appkey" to { billingClientProperties.appKey },
|
||||
@ -102,7 +103,7 @@ class BilibiliClient(
|
||||
"platform" to { billingClientProperties.platform },
|
||||
"ts" to { Instant.now().epochSecond.toString() }
|
||||
),
|
||||
defaultFormSignInterceptor
|
||||
SortAndSignInterceptor(ParamType.FORM_URL_ENCODED, billingClientProperties.appSecret)
|
||||
)
|
||||
}
|
||||
|
||||
@ -111,7 +112,7 @@ class BilibiliClient(
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val messageAPI by lazy {
|
||||
createAPI<MessageAPI>(BaseUrl.message, logLevel,
|
||||
createAPI<MessageAPI>(BaseUrl.message,
|
||||
defaultCommonHeaderInterceptor,
|
||||
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray,
|
||||
"actionKey" to { "appkey" },
|
||||
@ -122,13 +123,13 @@ class BilibiliClient(
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供一些通用信息
|
||||
* 总站 API
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val appAPI by lazy {
|
||||
createAPI<AppAPI>(BaseUrl.app, logLevel,
|
||||
createAPI<AppAPI>(BaseUrl.app,
|
||||
defaultCommonHeaderInterceptor,
|
||||
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray),
|
||||
defaultCommonQueryParamInterceptor,
|
||||
defaultQuerySignInterceptor
|
||||
)
|
||||
}
|
||||
@ -138,7 +139,7 @@ class BilibiliClient(
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val vcAPI by lazy {
|
||||
createAPI<VcAPI>(BaseUrl.vc, logLevel,
|
||||
createAPI<VcAPI>(BaseUrl.vc,
|
||||
defaultCommonHeaderInterceptor,
|
||||
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray,
|
||||
"_device" to { billingClientProperties.platform },
|
||||
@ -152,6 +153,17 @@ class BilibiliClient(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创作中心
|
||||
*/
|
||||
val memberAPI by lazy {
|
||||
createAPI<MemberAPI>(BaseUrl.member,
|
||||
defaultCommonHeaderInterceptor,
|
||||
defaultCommonQueryParamInterceptor,
|
||||
defaultQuerySignInterceptor
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 登陆
|
||||
* v3 登陆接口会同时返回 cookies 和 token
|
||||
@ -207,32 +219,31 @@ class BilibiliClient(
|
||||
loginResponse = null
|
||||
}
|
||||
|
||||
private inline fun <reified T : Any> createAPI(
|
||||
baseUrl: String,
|
||||
vararg interceptors: Interceptor
|
||||
) = Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(gsonConverterFactory)
|
||||
.addCallAdapterFactory(coroutineCallAdapterFactory)
|
||||
.client(OkHttpClient.Builder().apply {
|
||||
interceptors.forEach {
|
||||
addInterceptor(it)
|
||||
}
|
||||
addInterceptor(FailureResponseInterceptor)
|
||||
//log
|
||||
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
|
||||
addNetworkInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
|
||||
}
|
||||
}.build())
|
||||
.build()
|
||||
.create(T::class.java)
|
||||
|
||||
companion object {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private val gsonConverterFactory = GsonConverterFactory.create()
|
||||
private val coroutineCallAdapterFactory = CoroutineCallAdapterFactory()
|
||||
private val traceIdFormat = SimpleDateFormat("yyyyMMddHHmm000ss")
|
||||
private fun generateTraceId() = traceIdFormat.format(Date())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private val gsonConverterFactory = GsonConverterFactory.create()
|
||||
private val coroutineCallAdapterFactory = CoroutineCallAdapterFactory()
|
||||
private inline fun <reified T : Any> createAPI(
|
||||
baseUrl: String,
|
||||
logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.NONE,
|
||||
vararg interceptors: Interceptor
|
||||
) = Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(gsonConverterFactory)
|
||||
.addCallAdapterFactory(coroutineCallAdapterFactory)
|
||||
.client(OkHttpClient.Builder().apply {
|
||||
interceptors.forEach {
|
||||
addInterceptor(it)
|
||||
}
|
||||
addInterceptor(FailureResponseInterceptor)
|
||||
//log
|
||||
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
|
||||
addNetworkInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
|
||||
}
|
||||
}.build())
|
||||
.build()
|
||||
.create(T::class.java)
|
||||
|
@ -1,16 +1,14 @@
|
||||
package com.hiczp.bilibili.api.app
|
||||
|
||||
import com.hiczp.bilibili.api.app.model.IndexPage
|
||||
import com.hiczp.bilibili.api.app.model.Mine
|
||||
import com.hiczp.bilibili.api.app.model.MyInfo
|
||||
import com.hiczp.bilibili.api.app.model.Sidebar
|
||||
import com.hiczp.bilibili.api.app.model.*
|
||||
import kotlinx.coroutines.Deferred
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* 提供通用信息的接口
|
||||
* 总站 API
|
||||
*/
|
||||
@Suppress("DeferredIsResult")
|
||||
interface AppAPI {
|
||||
@ -34,12 +32,12 @@ interface AppAPI {
|
||||
fun sidebar(): Deferred<Sidebar>
|
||||
|
||||
/**
|
||||
* 首页内容
|
||||
* 首页内容(客户端通过解析返回的内容来生成页面内容, 下同)
|
||||
* 首页 -> 推荐
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/x/v2/feed/index")
|
||||
fun index(
|
||||
fun homePage(
|
||||
@Query("ad_extra") adExtra: String? = null,
|
||||
@Query("autoplay_card") autoplayCard: Int = 0,
|
||||
@Query("banner_hash") bannerHash: String? = null,
|
||||
@ -50,11 +48,74 @@ interface AppAPI {
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("force_host") forceHost: Int = 0,
|
||||
@Query("idx") index: Long = Instant.now().epochSecond,
|
||||
@Query("login_event") loginEvent: Int = 2,
|
||||
@Query("login_event") loginEvent: Int = 0,
|
||||
@Query("network") network: String = "mobile",
|
||||
@Query("open_event") openEvent: String? = null,
|
||||
@Query("pull") pull: Boolean = true,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("recsys_mode") recsysMode: Int = 0
|
||||
): Deferred<IndexPage>
|
||||
): Deferred<HomePage>
|
||||
|
||||
/**
|
||||
* 热门页面
|
||||
* 首页 -> 热门
|
||||
*/
|
||||
@GET("/x/v2/show/popular/index")
|
||||
fun popularPage(
|
||||
@Query("fnval") fnVal: Int = 16,
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("force_host") forceHost: Int = 0,
|
||||
@Query("idx") index: Long = 0,
|
||||
@Query("last_param") lastParam: String? = null,
|
||||
@Query("login_event") loginEvent: Int = 0,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("ver") ver: Long? = null //ver 的值为上一次请求该接口时的 timestamp-1
|
||||
): Deferred<PopularPage>
|
||||
|
||||
/**
|
||||
* 视频页面
|
||||
* 包含视频基本信息, 推荐和广告
|
||||
*
|
||||
* @param aid 视频的唯一标识
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/x/v2/view")
|
||||
fun view(
|
||||
@Query("ad_extra") adExtra: String? = null,
|
||||
@Query("aid") aid: Long,
|
||||
@Query("autoplay") autoplay: Int = 0,
|
||||
@Query("fnval") fnVal: Int = 16,
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("force_host") forceHost: Int = 0,
|
||||
@Query("from") from: Int? = null,
|
||||
@Query("plat") plat: Int = 0,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("trackid") trackId: String? = null //all_10.shylf-ai-recsys-120.1550674524909.237
|
||||
): Deferred<View>
|
||||
|
||||
//TODO 这里的 appkey 变为 iVGUTjsxvpLeuDCf
|
||||
/**
|
||||
* 获得视频的播放地址
|
||||
*
|
||||
* @param expire 默认为下个月的这一天的时间戳
|
||||
* @param mid 当前用户 ID
|
||||
* @param cid 在 view() 接口的返回值里
|
||||
* @param aid 视频的唯一标识
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/x/playurl")
|
||||
fun playUrl(
|
||||
@Query("device") device: String = "android",
|
||||
@Query("expire") expire: Long = Calendar.getInstance().apply { add(Calendar.MONTH, 1) }.toInstant().epochSecond,
|
||||
@Query("force_host") forceHost: Int = 0,
|
||||
@Query("mid") mid: Long? = null,
|
||||
@Query("fnval") fnVal: Int = 16,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("npcybs") npcybs: Int = 0,
|
||||
@Query("cid") cid: Long? = null,
|
||||
@Query("otype") otype: String = "json",
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("buvid") buildVersionId: String? = null,
|
||||
@Query("aid") aid: Long
|
||||
): Deferred<PlayUrl>
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.app.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class IndexPage(
|
||||
data class HomePage(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("data")
|
80
src/main/kotlin/com/hiczp/bilibili/api/app/model/PlayUrl.kt
Normal file
80
src/main/kotlin/com/hiczp/bilibili/api/app/model/PlayUrl.kt
Normal file
@ -0,0 +1,80 @@
|
||||
package com.hiczp.bilibili.api.app.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class PlayUrl(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("data")
|
||||
var `data`: Data,
|
||||
@SerializedName("message")
|
||||
var message: String, // 0
|
||||
@SerializedName("ttl")
|
||||
var ttl: Int // 1
|
||||
) {
|
||||
data class Data(
|
||||
@SerializedName("accept_description")
|
||||
var acceptDescription: List<String>,
|
||||
@SerializedName("accept_format")
|
||||
var acceptFormat: String, // flv720,flv480,flv360
|
||||
@SerializedName("accept_quality")
|
||||
var acceptQuality: List<Int>,
|
||||
@SerializedName("dash")
|
||||
var dash: Dash,
|
||||
@SerializedName("fnval")
|
||||
var fnval: Int, // 16
|
||||
@SerializedName("fnver")
|
||||
var fnver: Int, // 0
|
||||
@SerializedName("format")
|
||||
var format: String, // flv480
|
||||
@SerializedName("from")
|
||||
var from: String, // local
|
||||
@SerializedName("quality")
|
||||
var quality: Int, // 32
|
||||
@SerializedName("result")
|
||||
var result: String, // suee
|
||||
@SerializedName("seek_param")
|
||||
var seekParam: String, // start
|
||||
@SerializedName("seek_type")
|
||||
var seekType: String, // offset
|
||||
@SerializedName("timelength")
|
||||
var timelength: Int, // 443737
|
||||
@SerializedName("video_codecid")
|
||||
var videoCodecid: Int, // 7
|
||||
@SerializedName("video_project")
|
||||
var videoProject: Boolean // true
|
||||
) {
|
||||
data class Dash(
|
||||
@SerializedName("audio")
|
||||
var audio: List<Audio>,
|
||||
@SerializedName("video")
|
||||
var video: List<Video>
|
||||
) {
|
||||
data class Video(
|
||||
@SerializedName("backup_url")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 980114
|
||||
@SerializedName("base_url")
|
||||
var baseUrl: String, // http://112.13.92.195/upgcxcode/86/69/77356986/77356986-1-30064.m4s?expires=1550682900&platform=android&ssig=vLwE2fl303BrUu1wF1grNQ&oi=3670888805&trid=cf1bde09d63149168c0a0a997a3757d8&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("codecid")
|
||||
var codecid: Int, // 7
|
||||
@SerializedName("id")
|
||||
var id: Int // 64
|
||||
)
|
||||
|
||||
data class Audio(
|
||||
@SerializedName("backup_url")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 67125
|
||||
@SerializedName("base_url")
|
||||
var baseUrl: String, // http://117.148.189.5/upgcxcode/86/69/77356986/77356986-1-30216.m4s?expires=1550682900&platform=android&ssig=LlSJk_i74xGEjSOwmjUYzA&oi=3670888805&trid=cf1bde09d63149168c0a0a997a3757d8&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("codecid")
|
||||
var codecid: Int, // 0
|
||||
@SerializedName("id")
|
||||
var id: Int // 30216
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
446
src/main/kotlin/com/hiczp/bilibili/api/app/model/View.kt
Normal file
446
src/main/kotlin/com/hiczp/bilibili/api/app/model/View.kt
Normal file
@ -0,0 +1,446 @@
|
||||
package com.hiczp.bilibili.api.app.model
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class View(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("data")
|
||||
var `data`: Data,
|
||||
@SerializedName("message")
|
||||
var message: String, // 0
|
||||
@SerializedName("ttl")
|
||||
var ttl: Int // 1
|
||||
) {
|
||||
data class Data(
|
||||
@SerializedName("aid")
|
||||
var aid: Int, // 44172743
|
||||
@SerializedName("attribute")
|
||||
var attribute: Int, // 16512
|
||||
@SerializedName("cid")
|
||||
var cid: Int, // 77356986
|
||||
@SerializedName("cm_config")
|
||||
var cmConfig: CmConfig,
|
||||
@SerializedName("cms")
|
||||
var cms: List<Cm>,
|
||||
@SerializedName("copyright")
|
||||
var copyright: Int, // 1
|
||||
@SerializedName("ctime")
|
||||
var ctime: Int, // 1550654012
|
||||
@SerializedName("desc")
|
||||
var desc: String,
|
||||
@SerializedName("dimension")
|
||||
var dimension: Dimension,
|
||||
@SerializedName("dislike_reasons")
|
||||
var dislikeReasons: List<DislikeReason>,
|
||||
@SerializedName("dm_seg")
|
||||
var dmSeg: Int, // 1
|
||||
@SerializedName("duration")
|
||||
var duration: Int, // 444
|
||||
@SerializedName("dynamic")
|
||||
var `dynamic`: String, // #流浪地球##木星##太阳#
|
||||
@SerializedName("elec")
|
||||
var elec: Elec,
|
||||
@SerializedName("owner")
|
||||
var owner: Owner,
|
||||
@SerializedName("owner_ext")
|
||||
var ownerExt: OwnerExt,
|
||||
@SerializedName("pages")
|
||||
var pages: List<Page>,
|
||||
@SerializedName("pic")
|
||||
var pic: String, // http://i0.hdslb.com/bfs/archive/783445f04541299ee84de21a2479cce88d8268ff.jpg
|
||||
@SerializedName("pubdate")
|
||||
var pubdate: Int, // 1550654012
|
||||
@SerializedName("relates")
|
||||
var relates: List<Relate>,
|
||||
@SerializedName("req_user")
|
||||
var reqUser: ReqUser,
|
||||
@SerializedName("rights")
|
||||
var rights: Rights,
|
||||
@SerializedName("staff")
|
||||
var staff: List<Staff>,
|
||||
@SerializedName("stat")
|
||||
var stat: Stat,
|
||||
@SerializedName("state")
|
||||
var state: Int, // 0
|
||||
@SerializedName("tag")
|
||||
var tag: List<Tag>,
|
||||
@SerializedName("tid")
|
||||
var tid: Int, // 96
|
||||
@SerializedName("title")
|
||||
var title: String, // 模拟流浪地球进入木星的洛希极限,太阳要膨胀吞没地球这事是真的吗?
|
||||
@SerializedName("tname")
|
||||
var tname: String, // 星海
|
||||
@SerializedName("videos")
|
||||
var videos: Int // 1
|
||||
) {
|
||||
data class Cm(
|
||||
@SerializedName("ad_info")
|
||||
var adInfo: JsonElement, // {}
|
||||
@SerializedName("client_ip")
|
||||
var clientIp: String, // 218.205.81.101
|
||||
@SerializedName("index")
|
||||
var index: Int, // 1
|
||||
@SerializedName("is_ad_loc")
|
||||
var isAdLoc: Boolean, // true
|
||||
@SerializedName("request_id")
|
||||
var requestId: String, // 1550675871470q172a22a56a79q738
|
||||
@SerializedName("rsc_id")
|
||||
var rscId: Int, // 2337
|
||||
@SerializedName("src_id")
|
||||
var srcId: Int // 2338
|
||||
)
|
||||
|
||||
data class Owner(
|
||||
@SerializedName("face")
|
||||
var face: String, // http://i1.hdslb.com/bfs/face/9a586d1ef659b322af150c925976a134ad046a74.jpg
|
||||
@SerializedName("mid")
|
||||
var mid: Int, // 393484294
|
||||
@SerializedName("name")
|
||||
var name: String // 娱乐酱鸭
|
||||
)
|
||||
|
||||
data class Elec(
|
||||
@SerializedName("elec_set")
|
||||
var elecSet: ElecSet,
|
||||
@SerializedName("list")
|
||||
var list: List<Any>,
|
||||
@SerializedName("show")
|
||||
var show: Boolean // true
|
||||
) {
|
||||
data class ElecSet(
|
||||
@SerializedName("elec_list")
|
||||
var elecList: List<Elec>,
|
||||
@SerializedName("elec_theme")
|
||||
var elecTheme: Int, // 0
|
||||
@SerializedName("integrity_rate")
|
||||
var integrityRate: Double, // 10.0
|
||||
@SerializedName("rmb_rate")
|
||||
var rmbRate: Double, // 10.0
|
||||
@SerializedName("round_mode")
|
||||
var roundMode: Int // 0
|
||||
) {
|
||||
data class Elec(
|
||||
@SerializedName("elec_num")
|
||||
var elecNum: Int, // 0
|
||||
@SerializedName("is_customize")
|
||||
var isCustomize: Int, // 1
|
||||
@SerializedName("max_elec")
|
||||
var maxElec: Int, // 99999
|
||||
@SerializedName("min_elec")
|
||||
var minElec: Int, // 20
|
||||
@SerializedName("title")
|
||||
var title: String // 自定义
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class ReqUser(
|
||||
@SerializedName("attention")
|
||||
var attention: Int, // -999
|
||||
@SerializedName("coin")
|
||||
var coin: Int, // 0
|
||||
@SerializedName("dislike")
|
||||
var dislike: Int, // 0
|
||||
@SerializedName("favorite")
|
||||
var favorite: Int, // 0
|
||||
@SerializedName("like")
|
||||
var like: Int // 0
|
||||
)
|
||||
|
||||
data class Stat(
|
||||
@SerializedName("aid")
|
||||
var aid: Int, // 44172743
|
||||
@SerializedName("coin")
|
||||
var coin: Int, // 23
|
||||
@SerializedName("danmaku")
|
||||
var danmaku: Int, // 19
|
||||
@SerializedName("dislike")
|
||||
var dislike: Int, // 0
|
||||
@SerializedName("favorite")
|
||||
var favorite: Int, // 10
|
||||
@SerializedName("his_rank")
|
||||
var hisRank: Int, // 0
|
||||
@SerializedName("like")
|
||||
var like: Int, // 35
|
||||
@SerializedName("now_rank")
|
||||
var nowRank: Int, // 0
|
||||
@SerializedName("reply")
|
||||
var reply: Int, // 11
|
||||
@SerializedName("share")
|
||||
var share: Int, // 0
|
||||
@SerializedName("view")
|
||||
var view: Int // 1995
|
||||
)
|
||||
|
||||
data class OwnerExt(
|
||||
@SerializedName("assists")
|
||||
var assists: Any?, // null
|
||||
@SerializedName("fans")
|
||||
var fans: Int, // 275
|
||||
@SerializedName("official_verify")
|
||||
var officialVerify: OfficialVerify,
|
||||
@SerializedName("vip")
|
||||
var vip: Vip
|
||||
) {
|
||||
data class OfficialVerify(
|
||||
@SerializedName("desc")
|
||||
var desc: String,
|
||||
@SerializedName("type")
|
||||
var type: Int // -1
|
||||
)
|
||||
|
||||
data class Vip(
|
||||
@SerializedName("accessStatus")
|
||||
var accessStatus: Int, // 0
|
||||
@SerializedName("dueRemark")
|
||||
var dueRemark: String,
|
||||
@SerializedName("vipDueDate")
|
||||
var vipDueDate: Int, // 0
|
||||
@SerializedName("vipStatus")
|
||||
var vipStatus: Int, // 0
|
||||
@SerializedName("vipStatusWarn")
|
||||
var vipStatusWarn: String,
|
||||
@SerializedName("vipType")
|
||||
var vipType: Int // 0
|
||||
)
|
||||
}
|
||||
|
||||
data class Tag(
|
||||
@SerializedName("attribute")
|
||||
var attribute: Int, // 0
|
||||
@SerializedName("cover")
|
||||
var cover: String,
|
||||
@SerializedName("hated")
|
||||
var hated: Int, // 0
|
||||
@SerializedName("hates")
|
||||
var hates: Int, // 0
|
||||
@SerializedName("is_activity")
|
||||
var isActivity: Int, // 0
|
||||
@SerializedName("liked")
|
||||
var liked: Int, // 0
|
||||
@SerializedName("likes")
|
||||
var likes: Int, // 0
|
||||
@SerializedName("tag_id")
|
||||
var tagId: Int, // 7534
|
||||
@SerializedName("tag_name")
|
||||
var tagName: String // 未来
|
||||
)
|
||||
|
||||
data class Staff(
|
||||
@SerializedName("attention")
|
||||
var attention: Int, // 0
|
||||
@SerializedName("face")
|
||||
var face: String, // http://i1.hdslb.com/bfs/face/9a586d1ef659b322af150c925976a134ad046a74.jpg
|
||||
@SerializedName("mid")
|
||||
var mid: Int, // 393484294
|
||||
@SerializedName("name")
|
||||
var name: String, // 娱乐酱鸭
|
||||
@SerializedName("official_verify")
|
||||
var officialVerify: OfficialVerify,
|
||||
@SerializedName("title")
|
||||
var title: String, // UP主
|
||||
@SerializedName("vip")
|
||||
var vip: Vip
|
||||
) {
|
||||
data class OfficialVerify(
|
||||
@SerializedName("desc")
|
||||
var desc: String,
|
||||
@SerializedName("type")
|
||||
var type: Int // -1
|
||||
)
|
||||
|
||||
data class Vip(
|
||||
@SerializedName("accessStatus")
|
||||
var accessStatus: Int, // 0
|
||||
@SerializedName("dueRemark")
|
||||
var dueRemark: String,
|
||||
@SerializedName("vipDueDate")
|
||||
var vipDueDate: Int, // 0
|
||||
@SerializedName("vipStatus")
|
||||
var vipStatus: Int, // 0
|
||||
@SerializedName("vipStatusWarn")
|
||||
var vipStatusWarn: String,
|
||||
@SerializedName("vipType")
|
||||
var vipType: Int // 0
|
||||
)
|
||||
}
|
||||
|
||||
data class DislikeReason(
|
||||
@SerializedName("reason_id")
|
||||
var reasonId: Int, // 8
|
||||
@SerializedName("reason_name")
|
||||
var reasonName: String // 营销广告
|
||||
)
|
||||
|
||||
data class Relate(
|
||||
@SerializedName("ad_index")
|
||||
var adIndex: Int, // 2
|
||||
@SerializedName("aid")
|
||||
var aid: Int, // 38496110
|
||||
@SerializedName("card_index")
|
||||
var cardIndex: Int, // 3
|
||||
@SerializedName("cid")
|
||||
var cid: Int, // 67669037
|
||||
@SerializedName("client_ip")
|
||||
var clientIp: String, // 218.205.81.101
|
||||
@SerializedName("duration")
|
||||
var duration: Int, // 189
|
||||
@SerializedName("goto")
|
||||
var goto: String, // av
|
||||
@SerializedName("is_ad_loc")
|
||||
var isAdLoc: Boolean, // true
|
||||
@SerializedName("owner")
|
||||
var owner: Owner,
|
||||
@SerializedName("param")
|
||||
var `param`: String, // 38496110
|
||||
@SerializedName("pic")
|
||||
var pic: String, // http://i2.hdslb.com/bfs/archive/ca80fb7c554e083716feb910370b77caa5e124b3.jpg
|
||||
@SerializedName("request_id")
|
||||
var requestId: String, // 1550675871470q172a22a56a79q738
|
||||
@SerializedName("src_id")
|
||||
var srcId: Int, // 2334
|
||||
@SerializedName("stat")
|
||||
var stat: Stat,
|
||||
@SerializedName("title")
|
||||
var title: String, // 《流浪地球》发布创想特辑,从无到有呈现刘慈欣科幻想象
|
||||
@SerializedName("trackid")
|
||||
var trackid: String, // related_0.shylf-ai-recsys-87.1550675871470.909
|
||||
@SerializedName("uri")
|
||||
var uri: String // bilibili://video/38496110?player_width=1920&player_height=1080&player_rotate=0&trackid=related_0.shylf-ai-recsys-87.1550675871470.909
|
||||
) {
|
||||
data class Owner(
|
||||
@SerializedName("face")
|
||||
var face: String, // http://static.hdslb.com/images/member/noface.gif
|
||||
@SerializedName("mid")
|
||||
var mid: Int, // 334512441
|
||||
@SerializedName("name")
|
||||
var name: String // 达岸电影2018
|
||||
)
|
||||
|
||||
data class Stat(
|
||||
@SerializedName("aid")
|
||||
var aid: Int, // 38496110
|
||||
@SerializedName("coin")
|
||||
var coin: Int, // 130
|
||||
@SerializedName("danmaku")
|
||||
var danmaku: Int, // 152
|
||||
@SerializedName("dislike")
|
||||
var dislike: Int, // 0
|
||||
@SerializedName("favorite")
|
||||
var favorite: Int, // 194
|
||||
@SerializedName("his_rank")
|
||||
var hisRank: Int, // 0
|
||||
@SerializedName("like")
|
||||
var like: Int, // 341
|
||||
@SerializedName("now_rank")
|
||||
var nowRank: Int, // 0
|
||||
@SerializedName("reply")
|
||||
var reply: Int, // 264
|
||||
@SerializedName("share")
|
||||
var share: Int, // 278
|
||||
@SerializedName("view")
|
||||
var view: Int // 19397
|
||||
)
|
||||
}
|
||||
|
||||
data class Page(
|
||||
@SerializedName("cid")
|
||||
var cid: Int, // 77356986
|
||||
@SerializedName("dimension")
|
||||
var dimension: Dimension,
|
||||
@SerializedName("dm")
|
||||
var dm: Dm,
|
||||
@SerializedName("dmlink")
|
||||
var dmlink: String, // http://comment.bilibili.com/77356986.xml
|
||||
@SerializedName("duration")
|
||||
var duration: Int, // 444
|
||||
@SerializedName("from")
|
||||
var from: String, // vupload
|
||||
@SerializedName("metas")
|
||||
var metas: List<Meta>,
|
||||
@SerializedName("page")
|
||||
var page: Int, // 1
|
||||
@SerializedName("part")
|
||||
var part: String, // 2.20.2
|
||||
@SerializedName("vid")
|
||||
var vid: String,
|
||||
@SerializedName("weblink")
|
||||
var weblink: String
|
||||
) {
|
||||
data class Dm(
|
||||
@SerializedName("closed")
|
||||
var closed: Boolean, // false
|
||||
@SerializedName("count")
|
||||
var count: Int, // 19
|
||||
@SerializedName("mask")
|
||||
var mask: JsonElement, // {}
|
||||
@SerializedName("real_name")
|
||||
var realName: Boolean, // false
|
||||
@SerializedName("subtitles")
|
||||
var subtitles: Any? // null
|
||||
)
|
||||
|
||||
data class Dimension(
|
||||
@SerializedName("height")
|
||||
var height: Int, // 720
|
||||
@SerializedName("rotate")
|
||||
var rotate: Int, // 0
|
||||
@SerializedName("width")
|
||||
var width: Int // 1280
|
||||
)
|
||||
|
||||
data class Meta(
|
||||
@SerializedName("format")
|
||||
var format: String,
|
||||
@SerializedName("quality")
|
||||
var quality: Int, // 48
|
||||
@SerializedName("size")
|
||||
var size: Int // 81074
|
||||
)
|
||||
}
|
||||
|
||||
data class Rights(
|
||||
@SerializedName("autoplay")
|
||||
var autoplay: Int, // 1
|
||||
@SerializedName("bp")
|
||||
var bp: Int, // 0
|
||||
@SerializedName("download")
|
||||
var download: Int, // 1
|
||||
@SerializedName("elec")
|
||||
var elec: Int, // 1
|
||||
@SerializedName("hd5")
|
||||
var hd5: Int, // 0
|
||||
@SerializedName("is_cooperation")
|
||||
var isCooperation: Int, // 0
|
||||
@SerializedName("movie")
|
||||
var movie: Int, // 0
|
||||
@SerializedName("no_reprint")
|
||||
var noReprint: Int, // 1
|
||||
@SerializedName("pay")
|
||||
var pay: Int, // 0
|
||||
@SerializedName("ugc_pay")
|
||||
var ugcPay: Int // 0
|
||||
)
|
||||
|
||||
data class Dimension(
|
||||
@SerializedName("height")
|
||||
var height: Int, // 720
|
||||
@SerializedName("rotate")
|
||||
var rotate: Int, // 0
|
||||
@SerializedName("width")
|
||||
var width: Int // 1280
|
||||
)
|
||||
|
||||
data class CmConfig(
|
||||
@SerializedName("ads_control")
|
||||
var adsControl: AdsControl
|
||||
) {
|
||||
data class AdsControl(
|
||||
@SerializedName("has_danmu")
|
||||
var hasDanmu: Int // 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
18
src/main/kotlin/com/hiczp/bilibili/api/member/MemberAPI.kt
Normal file
18
src/main/kotlin/com/hiczp/bilibili/api/member/MemberAPI.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.hiczp.bilibili.api.member
|
||||
|
||||
import com.hiczp.bilibili.api.member.model.Pre
|
||||
import kotlinx.coroutines.Deferred
|
||||
import retrofit2.http.GET
|
||||
|
||||
/**
|
||||
* 创作中心
|
||||
*/
|
||||
@Suppress("DeferredIsResult")
|
||||
interface MemberAPI {
|
||||
/**
|
||||
* 刚登陆时会访问该 API, 使用返回的 url 来创建一个指向一系列 H5 页面的 ListView
|
||||
* 侧拉抽屉 -> 创作中心 -> 更多功能
|
||||
*/
|
||||
@GET("/x/app/pre")
|
||||
fun pre(): Deferred<Pre>
|
||||
}
|
78
src/main/kotlin/com/hiczp/bilibili/api/member/model/Pre.kt
Normal file
78
src/main/kotlin/com/hiczp/bilibili/api/member/model/Pre.kt
Normal file
@ -0,0 +1,78 @@
|
||||
package com.hiczp.bilibili.api.member.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class Pre(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("data")
|
||||
var `data`: Data,
|
||||
@SerializedName("message")
|
||||
var message: String, // 0
|
||||
@SerializedName("ttl")
|
||||
var ttl: Int // 1
|
||||
) {
|
||||
data class Data(
|
||||
@SerializedName("academy")
|
||||
var academy: Academy,
|
||||
@SerializedName("act")
|
||||
var act: Act,
|
||||
@SerializedName("creative")
|
||||
var creative: Creative,
|
||||
@SerializedName("entrance")
|
||||
var entrance: Entrance
|
||||
) {
|
||||
data class Entrance(
|
||||
@SerializedName("guidance")
|
||||
var guidance: String, // 投稿
|
||||
@SerializedName("show")
|
||||
var show: Int // 1
|
||||
)
|
||||
|
||||
data class Creative(
|
||||
@SerializedName("portal_list")
|
||||
var portalList: List<Portal>,
|
||||
@SerializedName("show")
|
||||
var show: Int // 1
|
||||
) {
|
||||
data class Portal(
|
||||
@SerializedName("icon")
|
||||
var icon: String, // http://i0.hdslb.com/bfs/archive/31f485451e415bbbc59407f1fddce8f317db6287.png
|
||||
@SerializedName("id")
|
||||
var id: Int, // 0
|
||||
@SerializedName("more")
|
||||
var more: Int, // 0
|
||||
@SerializedName("mtime")
|
||||
var mtime: Int, // 1547466050
|
||||
@SerializedName("new")
|
||||
var new: Int, // 1
|
||||
@SerializedName("position")
|
||||
var position: Int, // 8
|
||||
@SerializedName("subtitle")
|
||||
var subtitle: String,
|
||||
@SerializedName("title")
|
||||
var title: String, // 更多功能
|
||||
@SerializedName("url")
|
||||
var url: String // activity://uper/user_center/more_portal
|
||||
)
|
||||
}
|
||||
|
||||
data class Act(
|
||||
@SerializedName("show")
|
||||
var show: Int, // 1
|
||||
@SerializedName("title")
|
||||
var title: String, // 热门活动
|
||||
@SerializedName("url")
|
||||
var url: String // https://www.bilibili.com/blackboard/x/activity-tougao-h5/all
|
||||
)
|
||||
|
||||
data class Academy(
|
||||
@SerializedName("show")
|
||||
var show: Int, // 0
|
||||
@SerializedName("title")
|
||||
var title: String,
|
||||
@SerializedName("url")
|
||||
var url: String
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user